This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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
  • OK this is my mistake (partly), partly it is a Keil error (I think).
    in first instruction in _asm is

    lsl curbyte,#24
    

    used variable curbyte defined and declares in C code, as local variable in function ws2812_sendarray(), this code do not works and compiler return

        45:         __asm__ volatile(
    0x080010BE E006      B        0x080010CE
        46:    "                            lsl curbyte,#24              \n\t"
    0x080010C0 2508      MOVS     r5,#0x08
    0x080010C2 601C      STR      r4,[r3,#0x00]
    0x080010C4 BF00      NOP
    0x080010C6 D200      BCS      0x080010CA
    0x080010C8 6002      STR      r2,[r0,#0x00]
    0x080010CA 6002      STR      r2,[r0,#0x00]
    0x080010CC D1F9      BNE      0x080010C2
    


    notice lsl curbyte,#24 not include in asm code

    Code will be works only if curbyte will be global variable!!! in other words all c variable in by code used in _asm() must be declared as global. Compiler return

        46:                         "        lsl curbyte,#24           \n\t"
    0x080010C8 EA4F6707  LSL      r7,r7,#24
    0x080010CC 6057      STR      r7,[r2,#0x04]
    0x080010CE 2708      MOVS     r7,#0x08
    0x080010D0 6017      STR      r7,[r2,#0x00]
    0x080010D2 6857      LDR      r7,[r2,#0x04]
    0x080010D4 EA4F0747  LSL      r7,r7,#1
    0x080010D8 6057      STR      r7,[r2,#0x04]
    0x080010DA 602E      STR      r6,[r5,#0x00]
    0x080010DC BF00      NOP
    


    lsl curbyte,#24 is in assembler code as LSL r7,r7,#24

    It's interesting, that if in _asm(); use for example
    lsl datlen,#24 (variable datlen is from void ws2812_sendarray(uint8_t *data,int datlen)
    all vorsk OK and compiler Translate correctly LSL r0,r0,#24

    conclusion
    Why the compiler does not say that it does not know what the local variable c is?
    Why he knows datlen?
    I do not understand much

Reply
  • OK this is my mistake (partly), partly it is a Keil error (I think).
    in first instruction in _asm is

    lsl curbyte,#24
    

    used variable curbyte defined and declares in C code, as local variable in function ws2812_sendarray(), this code do not works and compiler return

        45:         __asm__ volatile(
    0x080010BE E006      B        0x080010CE
        46:    "                            lsl curbyte,#24              \n\t"
    0x080010C0 2508      MOVS     r5,#0x08
    0x080010C2 601C      STR      r4,[r3,#0x00]
    0x080010C4 BF00      NOP
    0x080010C6 D200      BCS      0x080010CA
    0x080010C8 6002      STR      r2,[r0,#0x00]
    0x080010CA 6002      STR      r2,[r0,#0x00]
    0x080010CC D1F9      BNE      0x080010C2
    


    notice lsl curbyte,#24 not include in asm code

    Code will be works only if curbyte will be global variable!!! in other words all c variable in by code used in _asm() must be declared as global. Compiler return

        46:                         "        lsl curbyte,#24           \n\t"
    0x080010C8 EA4F6707  LSL      r7,r7,#24
    0x080010CC 6057      STR      r7,[r2,#0x04]
    0x080010CE 2708      MOVS     r7,#0x08
    0x080010D0 6017      STR      r7,[r2,#0x00]
    0x080010D2 6857      LDR      r7,[r2,#0x04]
    0x080010D4 EA4F0747  LSL      r7,r7,#1
    0x080010D8 6057      STR      r7,[r2,#0x04]
    0x080010DA 602E      STR      r6,[r5,#0x00]
    0x080010DC BF00      NOP
    


    lsl curbyte,#24 is in assembler code as LSL r7,r7,#24

    It's interesting, that if in _asm(); use for example
    lsl datlen,#24 (variable datlen is from void ws2812_sendarray(uint8_t *data,int datlen)
    all vorsk OK and compiler Translate correctly LSL r0,r0,#24

    conclusion
    Why the compiler does not say that it does not know what the local variable c is?
    Why he knows datlen?
    I do not understand much

Children