First steps with ARM GNU ASM on PSoC 4

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

Hi all, hope this topic fits well here.

   

Just start trying to learn ASM, so there is a lot of stuff i don't know yet, but i tried a function on ASM and call that function from the main file of ths program. Most of the function is just NOP instructions, so i was expecting 1 or 2 clock cycles expended on each of those (i'm measuring the cycles watching the SysTick Value register on the Memory view while debug session), but i'm getting 4 clock cycles on each 😕 .

   

The function seems to take only 16 clock cycles, but i'm getting about 52.

   

Optimization is set to None, Debug mode.

   

Also i have found a register on the ARM site, DWT  http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337h/BIIFBHIF.html, it is a cycle counter, but i can't find it on the Register Documentation of the 4200 family, so anyone who can tell me if what i'm doing is well? any thought on another way to measure clock cycles?

   

Atached the project, it's based on the PSoC 4 Pioneer Kit

   

 

   

Thanks in advance, and excuse for the n00b questions 😄

0 Likes
6 Replies
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Use systick as your cycle counter (section in AN90799) -.

   

 

   

http://www.cypress.com/?id=4&rID=94607     PSOC 4 Systick

   

http://www.cypress.com/?docID=49253     AN90799 (Systick as well)

   

 

   

Regards, Dana.

0 Likes
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

I did, that's why i see each NOP instruction uses 4 clock cycles and not 1 or 2 as i was expecting.

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

Carlos,

   

The DWT "clock cycles" (CYCCNT) works only on Cortex-M3 CPU (PSoC5LP), and not on -M0 (PSoC4).

   

 

   

On PSoC4 you can measure amount of CPU cycles using SysTick (see below). Notice that min amount of counter starts with 3 - that is a  "zero offset". This is likely the reason you observe 4 clocks instead of 1 as you expected.

   

 

   

#define SYSTICK_MAXVAL 0x00FFFFFF //max allowed SysTick counter value for 24bit

   

uint32 SysCntVal; // The value of SysTick counter you are trying to retrieve
 

   

       
      SysTick_Config(SYSTICK_MAXVAL); //reset counter set to max value, 1-time,  will not reload

   

      TCPWM_WritePeriod(); //do something.. 

   

      SysCntVal = SYSTICK_MAXVAL - (SysTick->VAL); //get elapsed ticks (min offset 3 ticks)
           
      sprintf(strMsg1, "%d, %f\r\n", SysCntVal, x); //report result
      UART_PutString(strMsg1);

0 Likes

Hi Odissey,

   

I was using SysTick to measure the clock cycles, but didn't know about the "zero offset", now i do.

   

I dig into the Creator function to the get the count value of SysTick and found it's get from this register:

   

#define CYREG_CM0_SYST_CVR 0xe000e018u

   

so i watch this direction on the memory view of the debug session and saw it down counting.

   

 

   

Where can i found more information about the zero offset?

   

It is 3 cycles offset with all the instructions? or just the first one on the subroutine?

   

Is there another way to measure the clock cycles in more accurate way?

   

Will do the same test with the 5LP and check DWT and SysTick registers.

   

 

   

Thanks

0 Likes
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

yay, just did it with the PSoC 5LP and DWT and it give me 15 clock cycles. What i don't know is if the way i write to the DWT registers are the best, here my main:

   

<blockquote>

   

#include <project.h>

   

extern void retardo(uint16_t us);
extern uint64_t Invertir(uint64_t);

   

int main(){
    CyGlobalIntEnable;
    
    (*(reg32*)CYREG_CORE_DBG_EXC_MON_CTL) |= CoreDebug_DEMCR_VC_CHKERR_Msk; /* This mask = 0x01000000 */
    (*(reg32*)CYREG_DWT_CTRL) |= DWT_CTRL_CYCCNTENA_Msk; /* This mask = 0x1 */
    (*(reg32*)CYREG_DWT_CYCLE_COUNT) = 0;
    retardo(1);
    

   

    for(;;){
        
    }
}

   

/* [] END OF FILE */

   

</blockquote>

   

DWT init taken from here http://www.microbuilder.eu/Projects/LPC1343ReferenceDesign/DWTBenchmarking.aspx

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

Carlos,

   

there is no undocumented "zero offset", 3 cycles is what it takes to calculate elapsed ticks:

   

SysCntVal = SYSTICK_MAXVAL - (SysTick->VAL); //get elapsed ticks (min offset 3 ticks)
            

   

15 cycles measured to call external procedure (retardo(1);) and to stop and calculate DWT timer seems reasonable. You can record this time and use it to subtract from subsequent measurements

0 Likes