Quantcast
Channel: MCS Electronics Forum
Viewing all articles
Browse latest Browse all 20748

BASCOM-AVR : WS2811/2812 LED strip & Assembler code : REPLY

$
0
0
Not very efficient, but at least a proof it can be made functional. But I needed already to unroll some code, while would it have been in loops, it would be too slow. The same unrolling can be done in ASM also, and will still save some cycles, but I think I let it be for now. [code:1:6ae7edb04b]$regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = 64 $swstack = 40 $framesize = 40 '$noramclear '$sim Config Osc = Enabled , 32mhzosc = Enabled Config Sysclock = 32mhz Config Base = 0 '### user configurable ### Const RGBunits = 3 ' total count of RGB units Const rstto = 2 ' reset timeout, 1 equals one empty frame, 24 bits * 1,25µs = 30µs '### user configurable ### Const bytesperRGBunit = 3 ' every RGB-unit has 3 leds, every led is controlled by 1 byte Const ledcnt = RGBunits * bytesperRGBunit ' total amount of leds Const dbfsize = 12 ' one nibble per sent bit, 24 bit per RGB unit, 24 nibbles = 12 bytes Const dbfsize2 = dbfsize * 2 Const USART_TXEN = 3 Const USART_CMOD0 = 6 Const USART_CMOD1 = 7 Const USART_UCPHA = 1 Const USART_UDORD = 2 Const DMA_CH0TRNIF = 0 Const DMA_CH1TRNIF = 1 Const SPItmpl = &b10001000 Const SPIhnib = &b01000000 ' SPI_Out_0 = &b1000, 1.25µs/4*1 = H0.312µs, L0.938µs Const SPIlnib = &b00000100 ' SPI_Out_1 = &b1100, 1.25µs/4*2 = H0.625µs, L0.625µs Declare Sub filldbuf() Dim dblbuf_0(dbfsize) As Byte Dim dblbuf_1(dbfsize) As Byte Dim dblbuf(dbfsize2) As Byte At dblbuf_0(0) Overlay ' access both buffers through this one Dim ledarr(ledcnt) As Byte Dim ledptr As Word ' points to actual shifted out RGB data Dim toctr As Byte '### ISR related vars ### Dim SPIbyte As Byte Dim dbufptr As Byte Dim bufb As Byte Dim RGBtrsfr As Byte '### ISR related vars ### ledptr = 0 toctr = 0 ledarr(0) = 128 ledarr(1) = 170 ledarr(2) = 85 ledarr(3) = 1 ledarr(4) = 4 ledarr(5) = 32 On Dma_ch0 Dma_ch0_int On Dma_ch1 Dma_ch1_int 'UART0 in SPI Mode, TXD --> PD3, XCK --> PD1 (unused) Config PORTD.3 = Output ' set SPI TXD to output USARTD0_BAUDCTRLA = 4 ' BSEL = (32MHz/(2*3.2MBaud))-1, 1/(1.25µs/4bit) = 3.2MBaud USARTD0_BAUDCTRLB = 0 ' BSCALE = 0 USARTD0_CTRLA = 0 USARTD0_CTRLB = Bits(USART_TXEN) ' enable transmitter USARTD0_CTRLC = Bits(USART_CMOD1 , USART_CMOD0) ' enable UART SPI-mode, MSB first, sample rising edge Config Dma = Enabled , Doublebuf = CH01 , Cpm = CH0123 'Trigger Base Value = &H6B + Data register empty (DRE) &H01 --> &H6C Config Dmach0 = Enabled , Burstlen = 1 , Chanrpt = Enabled , Tci = Lo , Eil = OFF , Singleshot = Enabled , _ Sar = BLOCK , Sam = INC , Dar = NONE , Dam = FIXED , Trigger = &H6C , Btc = dbfsize , Repeat = 0 , Sadr = Varptr(dblbuf_0(0)) , Dadr = Varptr(usartD0_data) Config Dmach1 = Enabled , Burstlen = 1 , Chanrpt = Enabled , Tci = Lo , Eil = OFF , Singleshot = Enabled , _ Sar = BLOCK , Sam = INC , Dar = NONE , Dam = FIXED , Trigger = &H6C , Btc = dbfsize , Repeat = 0 , Sadr = Varptr(dblbuf_1(0)) , Dadr = Varptr(usartD0_data) Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled 'Enable Interrupts Config PORTE.0 = Output 'led0 Config PORTD.2 = Output Dim A As Word Dim C As Word '( Do Waitms 500 Toggle PortE.0 Loop ') Do For A = 0 To 65535 ' 91ms for this loop with disabled interrupts (no DMA) C = A ' 322ms with interrupts (with DMA), CPU 28% App <-> 72% ISR/DMA Next A Toggle PortD.2 Loop End Dma_ch0_int: dbufptr = 0 Call filldbuf DMA_INTFLAGS = 2 ^ DMA_CH0TRNIF Return Dma_ch1_int: dbufptr = dbfsize Call filldbuf DMA_INTFLAGS = 2 ^ DMA_CH1TRNIF Return Sub filldbuf() RGBtrsfr = 3 While RGBtrsfr > 0 If toctr = 0 Then SPIbyte = ledarr(ledptr) bufb = SPItmpl ' preset with template bufb.6 = SPIbyte.7 bufb.2 = SPIbyte.6 ' set out-bits according in-bits dblbuf(dbufptr) = bufb : Incr dbufptr ' write to double buffer, next buffer byte bufb = SPItmpl bufb.6 = SPIbyte.5 bufb.2 = SPIbyte.4 dblbuf(dbufptr) = bufb : Incr dbufptr bufb = SPItmpl bufb.6 = SPIbyte.3 bufb.2 = SPIbyte.2 dblbuf(dbufptr) = bufb : Incr dbufptr bufb = SPItmpl bufb.6 = SPIbyte.1 bufb.2 = SPIbyte.0 dblbuf(dbufptr) = bufb : Incr dbufptr Incr ledptr Else dblbuf(dbufptr) = 0 : Incr dbufptr ' pause, set all out bytes zu zero dblbuf(dbufptr) = 0 : Incr dbufptr dblbuf(dbufptr) = 0 : Incr dbufptr dblbuf(dbufptr) = 0 : Incr dbufptr End If Decr RGBtrsfr Wend If toctr > 0 Then Decr toctr Else If ledptr >= ledcnt Then ' end of array ? ledptr = 0 ' reset pointer toctr = rstto ' prepare for WS2811 reset End If End If End Sub[/code:1:6ae7edb04b]

Viewing all articles
Browse latest Browse all 20748

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>