This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Mixing c & assembly in Keil IDE

Dear Nordic, Whats wrong with the below code. It works well in RFduino but when I try to port the same code in Keil environment.Its not working throwing error as 1.identifier "asm is undefined 2. expected a ";" code below

void mixC_and_Assembly()
{
 volatile uint32_t  *out = &NRF_GPIO->OUT;
 byte *_ptbytes = txBuf;
 byte *_ptbytes1 = &txBuf[32];
 uint32_t  rbyte;

   // out =%0
   //_ptbytes = %1
   //rbyte = %2
  asm  volatile
  ( 
       //"headSP:\n\t"
       "push {r0,r1,r2,r3}\n\t"
       
        "ldrb %2, [%1,#0]\n\t"    //    rbyte = *_ptbytes
        "str %2,[%0,#0] \n\t"    //  *out = _ptbytes[0]

        "ldrb %2,[%1,#1] \n\t"    //  rbyte = *_ptbytes
        "str %2,[%0,#0] \n\t"    //  *out = _ptbytes[1]
       
        "ldrb %2,[%1,#2] \n\t"    //  rbyte = *_ptbytes
        "str %2,[%0,#0] \n\t"    //  *out = _ptbytes[2]

        ......
        .....
        .....
        ......
        
        
        "pop {r0,r1,r2,r3} \n\t" 
    ::
    "r" (out),   // %0
    "r" (_ptbytes),   // %1
    "r" (rbyte), //%2
    "r" (_ptbytes1)   // %3
    :"memory"
  );
}

after going through core_cmo.h file I have changed asm into __asm

void mixC_and_Assembly()
{
 volatile uint32_t  *out = &NRF_GPIO->OUT;
 byte *_ptbytes = txBuf;
 byte *_ptbytes1 = &txBuf[32];
 uint32_t  rbyte;

   // out =%0
   //_ptbytes = %1
   //rbyte = %2

  __asm  volatile
  ( 
       //"headSP:\n\t"
       "push {r0,r1,r2,r3}\n\t"
       
        "ldrb %2, [%1,#0]\n\t"    //    rbyte = *_ptbytes
        "str %2,[%0,#0] \n\t"    //  *out = _ptbytes[0]

        "ldrb %2,[%1,#1] \n\t"    //  rbyte = *_ptbytes
        "str %2,[%0,#0] \n\t"    //  *out = _ptbytes[1]
       
        "ldrb %2,[%1,#2] \n\t"    //  rbyte = *_ptbytes
        "str %2,[%0,#0] \n\t"    //  *out = _ptbytes[2]

        ......
        .....
        .....
        ......
        
        
        "pop {r0,r1,r2,r3} \n\t" 
    ::
    "r" (out),   // %0
    "r" (_ptbytes),   // %1
    "r" (rbyte), //%2
    "r" (_ptbytes1)   // %3
    :"memory"
  );
}

still I am getting error as "expected ")" ". is there anything I need to add in compiler option in keil ? kindly advise Thanks and Regards Lakshman,PMP,PMI-RMP

Parents
  • Hi Hung & Vidar, Thanks for your response.Yes I went through still I am unable to use it in proper way. After browsing I found out that above asm code is for GNU compiler. For Keil its very easy you can just give the variable name "as is" like below

    void mixC_and_Assembly()
    {
     volatile uint32_t  *out = &NRF_GPIO->OUT;
     byte *_ptbytes = txBuf;
     byte *_ptbytes1 = &txBuf[32];
     uint32_t  rbyte;
    
       // out =%0
       //_ptbytes = %1
       //rbyte = %2
    
    __asm  volatile
    		{      
    	        LDRB rbyte,[_ptbytes,#0]    //    rbyte = *_ptbytes
    	        STR  rbyte,[out,#0]    //  *out = _ptbytes[0]
    	
    	        LDRB rbyte,[_ptbytes,#1]    //  rbyte = *_ptbytes
    	        STR  rbyte,[out,#0]         //  *out = _ptbytes[1]
    	   
    	        LDRB rbyte,[_ptbytes,#2]    //  rbyte = *_ptbytes
    	        STR  rbyte,[out,#0]         //  *out = _ptbytes[2]
    	     
    	        LDRB rbyte,[_ptbytes,#3]    //  rbyte = *_ptbytes
    	        STR  rbyte,[out,#0]         //  *out = _ptbytes[3]
    	
    	 	    LDRB rbyte,[_ptbytes,#4]    //  rbyte = *_ptbytes
    	        STR  rbyte,[out,#0]      
    	        ......
    	        .....
    	        .....
    	        ......
    	
    	        LDRB rbyte,[_ptbytes1,#16]           //  rbyte = *_ptbytes1
    	        STR  rbyte,[out,#0]             //  *out = _ptbytes1[16]
    	 
    	        LDRB rbyte,[_ptbytes1,#17]           //  rbyte = *_ptbytes1
    	        STR  rbyte,[out,#0]             //  *out = _ptbytes1[17]
          
    		}
    }
    

    I am using p0.2,p0.3and p0.4 .If I give use the assembly I am able to get expected result but all the led is ON. volatile uint32_t *out = &NRF_GPIO->OUT; with the above statement I write to P0.2,P0.3 & P0.4 at the same time. will it have any effect on LED ? did I miss anything.?

    Thanks and Regards Lakshman,PMP,PMI-RMP

  • Hi Lakshman,

    You are correct, if you want to set and clear multiple pins at the same time then OUTSET and OUTCLR won't do the task. If you have to call 2 instruction, the delay will be 62.5 ns.

    The issue with OUT register, that I am afraid of is that to be able to not affect other pins, we need to read the OUT register before set it. The value of OUT register can be changed between when we read and we set (by an interrupt handler for example). But if you don't have interrupt that change out register then you should be fine.

Reply
  • Hi Lakshman,

    You are correct, if you want to set and clear multiple pins at the same time then OUTSET and OUTCLR won't do the task. If you have to call 2 instruction, the delay will be 62.5 ns.

    The issue with OUT register, that I am afraid of is that to be able to not affect other pins, we need to read the OUT register before set it. The value of OUT register can be changed between when we read and we set (by an interrupt handler for example). But if you don't have interrupt that change out register then you should be fine.

Children
No Data
Related