Code:
$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 ' ledarr(0) is first led of strip
Dim ledptr As Word ' points to actual shifted out RGB data
Dim toctr As Byte
ledptr = 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 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
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 ' I'm alive led0 on Atmel XPlained ATMega128A1
Config PORTD.2 = Output
Dim A As Word
Dim C As Word
Const testspeed = 0
#IF testspeed = 0
Do
Waitms 500
Toggle PortE.0
Loop
#ELSE
Do
Toggle PortD.2
For A = 0 To 65535 ' 91ms for this loop with disabled interrupts (no DMA)
C = A ' 108ms with interrupts (with DMA), CPU 84% App <-> 16% ISR/DMA
Next A
Loop
#ENDIF
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
!ADIW r24, bytesperRGBunit
!LDI r17, hbyte(ledcnt)
!CPI r24, lbyte(ledcnt)
!CPC r25, r17
!BRCS avail
!CLR r24
!CLR r25
!LDI r17, rstto
!STS {toctr}, r17
!avail:
!STS {ledptr}, r24
!STS {ledptr+1}, r25
!byteloop:
!LD r24, X+
!LDI r17, SPItmpl
!BST r24, 7
!BLD r17, 6
!BST r24, 6
!BLD r17, 2
!ST Z+, r17
!LDI r17, SPItmpl
!BST r24, 5
!BLD r17, 6
!BST r24, 4
!BLD r17, 2
!ST Z+, r17
!LDI r17, SPItmpl
!BST r24, 3
!BLD r17, 6
!BST r24, 2
!BLD r17, 2
!ST Z+, r17
!LDI r17, SPItmpl
!BST r24, 1
!BLD r17, 6
!BST r24, 0
!BLD r17, 2
!ST Z+, r17
!DEC r16
!BRNE byteloop
!fillend:
!POP XH
!POP XL
!POP r25
!POP r24
!POP r17
!POP r16
Return
Lesezeichen