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?
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
NO.
It is totally your mistake. You don't have sufficient understanding of the tools.
yes I have not However on the other hand I would expect at least a warning from the tool, warning in __asm is used undeclared variable etc.