Jim,
[quote:3966b8d75c="Flyby123"]Let me know what I need to do.[/quote:3966b8d75c]
in the meantime I got me an Atmel Xplained, I was able to test my code and check with an oscilloscope it theoretically works.
"Theoretically", because I have a slightly longer period for the low bit, around 310ns instead of 250ns. I can't avoid that with the kind of bit-banging my code does.
The overall frame length is well within specs.
So I'd be interested, if the WS2811 works with my code. My code's benefit is to steadily push out the frames, means a high update rate, while it uses only about 15-20% of the available cpu power.
The NOP-snake code will use 100% under this condition. That said, one could run 1000 leds, that's a 1000 frames, each 30µs long, equals to 30ms giving an update rate of 33Hz, and still have
enough power to fill the array for the 3000 single leds with with useful data.
But one shall not divide the bear's skin before it is taken, so everything depends on acceptance of the timing by the WS2811.
The NOP-snake actually can be better fine-tuned.
Tested it on a ATXMega128A1, in the following my original code. Notice, that a dedicated UART TXD pin is needed, I've used UARTD0 on Pin PD3.
And, it's not my cleanest code, but does what's expected.
[code:1:3966b8d75c]$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 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
Dim dblbuf_0(dbfsize) As Byte
Dim dblbuf_1(dbfsize) As Byte
Dim ledarr(ledcnt) As Byte
Dim ledptr As Word ' points to actual shifted out RGB data
Dim toctr As Byte
ledptr = ledcnt
ledarr(0) = 128
ledarr(1) = 170
ledarr(2) = 85
'(
ledarr(3) = 1
ledarr(4) = 4
ledarr(5) = 32
')
On Dma_ch0 Dma_ch0_int NOSAVE
On Dma_ch1 Dma_ch1_int NOSAVE
'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, double speed
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
Set PortD.2
For A = 0 To 65535
C = A
Next A
Reset PortD.2
Waitms 10
Loop
End
Dma_ch0_int:
!PUSH ZL
!IN ZL, SREG
!PUSH ZL
!PUSH ZH
Loadadr dblbuf_0(0) , Z
!RCALL dblbuff
!LDI ZL, 2^DMA_CH0TRNIF
!STS DMA_INTFLAGS, ZL
!POP ZH
!POP ZL
!OUT SREG, ZL
!POP ZL
Return
Dma_ch1_int:
!PUSH ZL
!IN ZL, SREG
!PUSH ZL
!PUSH ZH
Loadadr dblbuf_1(0) , Z
!RCALL dblbuff
!LDI ZL, 2^DMA_CH1TRNIF
!STS DMA_INTFLAGS, ZL
!POP ZH
!POP ZL
!OUT SREG, ZL
!POP ZL
Return
!dblbuff:
!PUSH r16
!PUSH r17
!PUSH r24
!PUSH r25
!PUSH XL
!PUSH XH
!LDI r16, bytesperRGBunit
!LDS r24, {toctr}
!TST r24
!BREQ filldb
!LDI r16, dbfsize
!CLR r17
!clrdblbuf:
!ST Z+, r17
!DEC r16
!BRNE clrdblbuf
!DEC R24
!STS {toctr}, r24
!RJMP fillend
!filldb:
Loadadr ledarr(0) , X
!LDS r24, {ledptr}
!LDS r25, {ledptr+1}
!ADD XL, r24
!ADC XH, r25
!SBIW r24, bytesperRGBunit
!BRNE avail
!LDI r24, lbyte(ledcnt)
!LDI r25, hbyte(ledcnt)
!LDI r17, rstto
!STS {toctr}, r17
!avail:
!STS {ledptr}, r24
!STS {ledptr+1}, r25
!byteloop:
!LD r24, -X
!LDI r25, 4
!2nibloop:
!LDI r17, SPItmpl
!LSL r24
!BRCC hnibl
!SBR r17, SPIhnib
!hnibl:
!LSL r24
!BRCC lnibl
!SBR r17, SPIlnib
!lnibl:
!ST Z+, r17
!DEC r25
!BRNE 2nibloop
!DEC r16
!BRNE byteloop
!fillend:
!POP XH
!POP XL
!POP r25
!POP r24
!POP r17
!POP r16
Return[/code:1:3966b8d75c]
↧