I am using a FRDM-KL03Z evaluation board with the MCU Expresso IDE. I have simple code where I am writing to the
GPIOA Port Data Output Register memory address to toggle a GPIO pin ON and OFF. The code that is doing so is pretty simple and is shown below.
volatile uint32_t* GPIOA_Port_Data_Output_Register = (uint32_t *)0x400FF000u;//type cast the GPIOA_PDOR address to pointer
*GPIOA_Port_Data_Output_Register |= 0x80;// Write a 1 to GPIOA_7, assign the value 0x080 to the pointer
*GPIOA_Port_Data_Output_Register &= 0x7F; ;// Write a 0 to GPIOA_7
*GPIOA_Port_Data_Output_Register |= 0x80;// Write a 1 to GPIOA_7
When I have my bus clock set to 24 MHz (a 41.67 ns period), I see that the GPIO pin is ON for 250 ns, which equates to 6 clock cycles. When I change my bus clock to 8 MHz (a 125 ns period) I see the GPIO pin is on for 376 ns, which equates to 3 clock cycles. I am operating the MCU in run mode. According to Table 5-2 Module Clocks in the KL03 Sub-Family Reference Manual, the GPIO module uses the platform clock as the bus interface clock.
My questions are:
1) The MCU Expresso Clock Perspective does not show a 'Platform Clock'. Is the bus clock the same as the platform clock?
2) Why does the number of clock cycles for the exercise of the GPIO pins vary with the bus clock frequency? It seems the number of clock cycles to execute a task should remain the same, but the time to execute a task should depend on the clock period.
-Andrew
Hi Andrew
Can you specify the core frequency used in each case? The execution time will depend on both core and bs speeds since the CPU operates at core speed and the GPIO accesses will be additionally dependent on the bus speed.
For the KL03 you will also have faster GPIO operation when you access them as fast GPIOs in the address range 0xf8000000 instead of the 0x400ff000 range.
In addition, you get faster code execution when using the PTOR register rather than the PDOR one with a read/modify/write logic operation.
Regards
Mark
Complete Kinetis solutions, training and support: http://www.utasker.com/kinetis.html
Kinetis KL02/KL03/KL05:
- http://www.utasker.com/kinetis/FRDM-KL02Z.html
- http://www.utasker.com/kinetis/FRDM-KL03Z.html
- http://www.utasker.com/kinetis/FRDM-KL05Z.html
Mark,
I am using a core frequency of 48 MHz:
Per your recommendation, I am now using the fast GPIO address and writing to the PTOR register. Based on the above clock mapping, I am seeing a GPIO toggle of ~332 ns (8 bus clock cycles). My code is:
volatile uint32_t* GPIOA_Port_Toggle_Output_Register = (uint32_t *)0xF800000Cu;//type cast the GPIOA_PTOR address to pointer
*GPIOA_Port_Toggle_Output_Register |= 0x00;// Reset the register
*GPIOA_Port_Toggle_Output_Register |= 0x80;// Write a 1 to GPIOA_7 // assign the value 0x080 to the pointer
*GPIOA_Port_Toggle_Output_Register &= 0x7F;
*GPIOA_Port_Toggle_Output_Register |= 0x80;// Write a 1 to GPIOA_7
-Andrew
Andrew
When using the PTOR you need to do
PCOR = 0x80;
PTOR = 0x80;
PTOR = 0x80;
PTOR = 0x80;
and not as you are doing (read their operating description in the user's manual) - this will remove the read-modify-write and make it about 3..4x faster.
Regards
Mark
Complete Kinetis solutions, training and support: http://www.utasker.com/kinetis.html
Kinetis KL02/KL03/KL05:
- http://www.utasker.com/kinetis/FRDM-KL02Z.html
- http://www.utasker.com/kinetis/FRDM-KL03Z.html
- http://www.utasker.com/kinetis/FRDM-KL05Z.html