ws2812 with stm32f0

Hey

I want to use stm32f0 by ws2812 and keil.
this is my code

/* * light weight WS2812 lib - ARM Cortex M0/M0+ version * * Created: 07.07.2013 * Author: Tim (cpldcpu@gmail.com) */

#include "light_ws2812_cortex.h"

/*
* The total length of each bit is 1.25µs (25 cycles @ 20Mhz)
* At 0µs the dataline is pulled high.
* To send a zero the dataline is pulled low after 0.375µs
* To send a one the dataline is pulled low after 0.625µs
*/

#define ws2812_ctot (((ws2812_cpuclk/1000)*1250)/1000000)
#define ws2812_t1 (((ws2812_cpuclk/1000)*375 )/1000000) // floor
#define ws2812_t2 (((ws2812_cpuclk/1000)*625+500000)/1000000) // ceil

#define w1 (ws2812_t1-2)
#define w2 (ws2812_t2-ws2812_t1-2)
#define w3 (ws2812_ctot-ws2812_t2-5)

#define ws2812_DEL1 " nop \n\t"
#define ws2812_DEL2 " b .+2 \n\t"
#define ws2812_DEL4 ws2812_DEL2 ws2812_DEL2
#define ws2812_DEL8 ws2812_DEL4 ws2812_DEL4
#define ws2812_DEL16 ws2812_DEL8 ws2812_DEL8

void ws2812_sendarray(uint8_t *data,int datlen)
{ uint32_t maskhi = ws2812_mask_set; uint32_t masklo = ws2812_mask_clr; volatile uint32_t *set = ws2812_port_set; volatile uint32_t *clr = ws2812_port_clr; uint32_t i; uint32_t curbyte;

while (datlen--) { curbyte=*data++;

asm volatile( " lsl %[dat],#24 \n" " movs %[ctr],#8 \n" "ilop%=: \n" " lsl %[dat], #1 \n" " str %[maskhi], [%[set]] \n"
#if (w1&1) ws2812_DEL1
#endif
#if (w1&2) ws2812_DEL2
#endif
#if (w1&4) ws2812_DEL4
#endif
#if (w1&8) ws2812_DEL8
#endif
#if (w1&16) ws2812_DEL16
#endif " bcs one%= \n" " str %[masklo], [%[clr]] \n" "one%=: \n"
#if (w2&1) ws2812_DEL1
#endif
#if (w2&2) ws2812_DEL2
#endif
#if (w2&4) ws2812_DEL4
#endif
#if (w2&8) ws2812_DEL8
#endif
#if (w2&16) ws2812_DEL16
#endif " sub %[ctr], #1 \n" " str %[masklo], [%[clr]] \n" " beq end%= \n\t"
#if (w3&1) ws2812_DEL1
#endif
#if (w3&2) ws2812_DEL2
#endif
#if (w3&4) ws2812_DEL4
#endif
#if (w3&8) ws2812_DEL8
#endif
#if (w3&16) ws2812_DEL16
#endif

" b ilop%= \n\t" " end%=: \n\t" : [ctr] "+r" (i) : [dat] "r" (curbyte), [set] "r" (set), [clr] "r" (clr), [masklo] "r" (masklo), [maskhi] "r" (maskhi) ); }
}

but i have a problem
1-light_ws2812_cortex.c(45): error: #20: identifier "asm" is undefined but if i change asm to __asm the error change to
light_ws2812_cortex.c(105): error: #18: expected a ")" :ctr] "+r" (i)
how can i fix it?

Parents
  • Thanks for showing us how to convert the gcc inline assemblier code to ARM. It looks like the problem is caused by this statement:

    #define ws2812_DEL2 "      b       .+2     \n\t"
    

    I think this is a branch to current PC + 2 but the . notation is not supported within __asm. I have tried to use the __current_pc intrinsic but that generates additional errors when used within __asm.

    By changing the line to:

    #define ws2812_DEL2 "                         nop\n"
    


    and compiling and flashing. Pressing reset several times will cause the WS2812 to light which shows the code is working but the timing is wrong.

Reply
  • Thanks for showing us how to convert the gcc inline assemblier code to ARM. It looks like the problem is caused by this statement:

    #define ws2812_DEL2 "      b       .+2     \n\t"
    

    I think this is a branch to current PC + 2 but the . notation is not supported within __asm. I have tried to use the __current_pc intrinsic but that generates additional errors when used within __asm.

    By changing the line to:

    #define ws2812_DEL2 "                         nop\n"
    


    and compiling and flashing. Pressing reset several times will cause the WS2812 to light which shows the code is working but the timing is wrong.

Children
More questions in this forum