von
CeeKay (Gast)
30.07.2015 09:54
Hallo Forum,
ich stelle an dieser Stelle mal meinen Code für das Senden von DMX auf
der Atmel XMega Plattform zur Verfügung. Meine Implementation nutzt DMA
Transfer für das Übertragen der 512 Bytes zum UART Buffer. Das ist aber
mehr als Beispiel zu sehen, als eine sinnvolle Anwendung von DMA, da ich
schön brav auf das Ende des DMA Transfers warte. Der gesamte Ablauf
benötigt keine Interrupts und basiert auf dem umkonfiguieren der
Baudrate zur Erzeugung des DMA Frame Formates.
1 /* _ _ _ _ _ _ _ _ _ _
2 * /\ \ /\ \ /\ \ /\_\ / /\ /\ \ /\ \ /\_\/\_\ _ /\ \
3 * / \ \ \_\ \ / \ \ / / / _ / / \ \_\ \ / \ \ / / / / //\_\ / \ \
4 * / /\ \ \ /\__ \ / /\ \ \ \ \ \__ /\_\ / / /\ \__ /\__ \ / /\ \ \ /\ \/ \ \/ / /__/ /\ \ \
5 * / / /\ \_\ / /_ \ \ / / /\ \ \ \ \___\ / / // / /\ \___\ / /_ \ \ / / /\ \ \ / \____\__/ //___/ /\ \ \
6 * / / /_/ / / / / /\ \ \ / / / \ \_\ \__ / / / / \ \ \ \/___// / /\ \ \ / / / \ \_\ / /\/________/ \___\/ / / /
7 * / / /__\/ / / / / \/_// / / \/_/ / / / / / / \ \ \ / / / \/_// / / / / // / /\/_// / / / / /
8 * / / /_____/ / / / / / / / / / / / /_ \ \ \ / / / / / / / / // / / / / / / / / _
9 * / / /\ \ \ / / / / / /________ / / /___/ / //_/\__/ / / / / / / / /___/ / // / / / / / \ \ \__/\_\
10 * / / / \ \ \/_/ / / / /_________\/ / /____\/ / \ \/___/ / /_/ / / / /____\/ / \/_/ / / / \ \___\/ /
11 * \/_/ \_\/\_\/ \/____________/\/_________/ \_____\/ \_\/ \/_________/ \/_/ \/___/_/
12 *
13 *
14 * DMX Output for ATxMega
15 * Tested with ATxMega256A3U
16 * Uses external 16 MHz oscillator together with internal PLL to generate 32MHz system clock
17 * DMX Signal will be transmitted through Port PC3
18 * DMA transfer added for fun but not needed since we are waiting for DMA to finish before next transfer
19 *
20 * Released under the "Don't care" license
21 * Feel free to use this code in any way you want
22 * Also no support will be given in any way
23 *
24 * Code V1.0
25 * 30.07.2015
26 */
27
28
29 #include <avr/io.h>
30 #include <util/delay.h>
31
32
33 enum { BREAK , STARTBYTE , DMXDATA };
34 unsigned char DMXStatus = BREAK ;
35
36
37
38
39
40 void Clock_init ( void )
41 {
42 //Xosc Bit 7&6 to 11 | Bit 3 to 0 as 1011
43 OSC . XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc ;
44 //Bit 3 to 1 to enable external oscillator
45 OSC . CTRL |= OSC_XOSCEN_bm ;
46 //wait for stable clock
47 while ( ! ( OSC . STATUS & OSC_XOSCRDY_bm ));
48 //Disable register protection for 4 clocks
49 CCP = CCP_IOREG_gc ;
50 //Set Bit 2:0 to 011 for external oscillator
51 CLK . CTRL = CLK_SCLKSEL_XOSC_gc ;
52 }
53
54 void PLL_init ( void )
55 {
56 //Bit 7:0 to 11 for external oscillator as PLL source | 2 as multiplication value
57 OSC . PLLCTRL = OSC_PLLSRC_XOSC_gc | 0x02 ;
58 //enable PLL
59 OSC . CTRL |= OSC_PLLEN_bm ;
60 //wait for stable oscillation
61 while ( ! ( OSC . STATUS & OSC_PLLRDY_bm ));
62 //Disable register protection for 4 clocks
63 CCP = CCP_IOREG_gc ;
64 //Set Bit 2:0 for PLL as clock source
65 CLK . CTRL = CLK_SCLKSEL_PLL_gc ;
66 }
67
68 void Init_uart ( void )
69 {
70 //configure usart
71 // Pin from USARTC0 TxD C3 set to output
72 PORTC . DIRSET = PIN3_bm ;
73 // Pin from USARTC0 TxD C3 to high
74 PORTC . OUTSET = PIN3_bm ;
75 // Asynchronous Modus Bit 7 & 6 to 0
76 USARTC0 . CTRLC = ( USARTC0 . CTRLC & ~ USART_CMODE_gm ) | USART_CMODE_ASYNCHRONOUS_gc ;
77 // No parity Bit 5 & 4 to 0
78 USARTC0 . CTRLC = ( USARTC0 . CTRLC & ~ USART_PMODE_gm ) | USART_PMODE_DISABLED_gc ;
79 // 2 stop bits Bit 3 to 1
80 USARTC0 . CTRLC = ( USARTC0 . CTRLC & ~ USART_SBMODE_bm ) | ( 0x01 << 3 );
81 // 8 data bits Bit 2 to 0 set to 011
82 USARTC0 . CTRLC = ( USARTC0 . CTRLC & ~ USART_CHSIZE_gm ) | USART_CHSIZE_8BIT_gc ;
83 // 100 kBaud
84 USARTC0 . BAUDCTRLA = 19 ;
85 // 100 kBaud
86 USARTC0 . BAUDCTRLB = ( 0x00 << USART_BSCALE0_bp ) | ( 19 >> 8 );
87 // activate USARTC1
88 USARTC0 . CTRLB = USART_TXEN_bm ;
89 }
90
91 //Configure DMA to transfer data from DMX array into UART buffer
92 void dma_set ( unsigned char * dmxdata , unsigned int length ){
93
94 // activate single buffer, burst size 1Byte
95 DMA . CTRL = DMA_CH_ENABLE_bm ;
96
97 //Modus transaction, increase and decrease, Burst
98 DMA . CH0 . ADDRCTRL = DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTRELOAD_NONE_gc | DMA_CH_DESTDIR_FIXED_gc ;
99
100 // Trigger Source is USARTC1 trigger if data buffer is empty
101 DMA . CH0 . TRIGSRC = DMA_CH_TRIGSRC_USARTC0_DRE_gc ;
102
103 //Set number of dmx channels to transfer
104 DMA . CH0 . TRFCNT = length ;
105
106 //8Bit source register
107 DMA . CH0 . SRCADDR0 = ((( uint16_t )( dmxdata )) >> 0 * 8 ) & 0xFF ;
108 DMA . CH0 . SRCADDR1 = ((( uint16_t )( dmxdata )) >> 1 * 8 ) & 0xFF ;
109 DMA . CH0 . SRCADDR2 = 0 ;
110
111 //8Bit target register at USARTC1
112 DMA . CH0 . DESTADDR0 = (( uint16_t ) & USARTC0 . DATA >> 0 * 8 ) & 0xFF ;
113 DMA . CH0 . DESTADDR1 = (( uint16_t ) & USARTC0 . DATA >> 1 * 8 ) & 0xFF ;
114 DMA . CH0 . DESTADDR2 = 0 ;
115 }
116
117
118 void Send_DMX_DMA ( unsigned char * dmxdata , unsigned int length )
119 {
120 //DMX is 250 kBaud 8N2 format
121 //Each package is framed by 1 start bit (0) and 2 stop bits (1)
122 //Start Condition is a >88µs break followed by >8 µs mark
123 //To generate Start condition reconfigure baud rate setting to 100 kBaud and send 0x00
124 //0x00 is 0000 0000 together with normal start bit = 9 low bits followed by two high bits from stop bits of 8N2 format
125 //At 100 kBaud a single bit time is 10µs
126 //9 x 10 µs = 90 µs low and 2 x 10 µs = 20 µs high
127 //Calculated register settings for 100 kBaud are BSCALE = 0 & BSEL = 019
128 //Calculated register settings for 250 kBaud are BSCALE = 0 & BSEL = 007
129 //Than always transfer a Null package to determine data type for channel transmission
130 //After this send out DMX payload data
131
132 //Generate break condition
133 if ( DMXStatus == BREAK )
134 {
135 //Reconfigure baud rate to 100 kBaud
136 USARTC0 . BAUDCTRLA = 19 ;
137 USARTC0 . BAUDCTRLB = ( 0 << USART_BSCALE0_bp ) | ( 19 >> 8 );
138 //Send a Zero to generate Break and Mark
139 USARTC0 . DATA = 0x00 ;
140 //Check for finished physical transmission and clear flag
141 while ( ! ( USARTC0 . STATUS & USART_TXCIF_bm ));
142 USARTC0 . STATUS |= USART_TXCIF_bm ;
143 //Switch to next step in DMX protocol. The start byte 0x00
144 DMXStatus = STARTBYTE ;
145 }
146
147
148
149 //Send information about type of DMX transmission
150 if ( DMXStatus == STARTBYTE )
151 {
152 //Reconfigure baud rate to 250 kBaud
153 USARTC0 . BAUDCTRLA = 07 ;
154 USARTC0 . BAUDCTRLB = ( 0 << USART_BSCALE0_bp ) | ( 07 >> 8 );
155 //Send a Zero to let DMX receivers know that now channels values will be send
156 USARTC0 . DATA = 0x00 ;
157 //Check for finished physical transmission and clear flag
158 while ( ! ( USARTC0 . STATUS & USART_TXCIF_bm ));
159 USARTC0 . STATUS |= USART_TXCIF_bm ;
160 //Switch to next step in DMX protocol and send channel informations
161 DMXStatus = DMXDATA ;
162
163 }
164
165
166 //Send DMX channel data
167 if ( DMXStatus == DMXDATA )
168 {
169 //Configure DMA to transmission data register and length
170 dma_set ( dmxdata , length );
171 //Activate DMA CH0 and send rest of DMX stream via DMA access
172 DMA . CH0 . REPCNT = 0 ;
173 DMA . CH0 . CTRLA = DMA_CH_ENABLE_bm | DMA_CH_SINGLE_bm | DMA_CH_BURSTLEN_1BYTE_gc ;
174 //Check for running DMA transfer and clear flag
175 while ( ! ( DMA . INTFLAGS & DMA_CH0TRNIF_bm ) || ( DMA . CH0 . CTRLB & ( DMA_CH_CHBUSY_bm | DMA_CH_CHPEND_bm )));
176 DMA . INTFLAGS |= DMA_CH0TRNIF_bm ;
177 //Deactivate DMA
178 DMA . CH0 . CTRLA &= ~ DMA_CH_ENABLE_bm ;
179 //Check for finished physical transmission and clear flag
180 while ( ! ( USARTC0 . STATUS & USART_TXCIF_bm ));
181 USARTC0 . STATUS |= USART_TXCIF_bm ;
182 //Go back to start of DMX protocol
183 DMXStatus = BREAK ;
184 }
185 }
186
187
188 int main ( void )
189 {
190 Clock_init ();
191 PLL_init ();
192 Init_uart ();
193 //Port E to Output and High for routing Uart to SP3T Output
194 PORTE . DIRSET |= PIN6_bm ;
195 PORTE . OUTSET |= PIN6_bm ;
196
197 unsigned char white [ 512 ] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
198 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
199 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
200 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
201 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
202 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF };
203
204 while ( 1 )
205 {
206 Send_DMX_DMA ( & white [ 0 ], 512 );
207 _delay_ms ( 1000 );
208 }
209
210 }
@CeeKay (Gast)
>der Atmel XMega Plattform zur Verfügung. Meine Implementation nutzt DMA
>Transfer für das Übertragen der 512 Bytes zum UART Buffer. Das ist aber
>mehr als Beispiel zu sehen, als eine sinnvolle Anwendung von DMA, da ich
>schön brav auf das Ende des DMA Transfers warte. Der gesamte Ablauf
>benötigt keine Interrupts
"Niemand ist unnütze. Er kann auch als schlechtes Beispiel dienen."
Im Ernst, was soll denn das? Hat die Welt wirklich ein sooo schlechtes
Beispiel gebraucht? Da ist jede Routone mit Interrupt und ohne DMA
besser als das hier. 100% CPU Ausbremsung für NICHTS!
DONT LIKE
von
CeeKay (Gast)
26.08.2015 09:08
Berühmtes Zitat "Rofelcopter"
Zitiert noch die Passage, dass der DMA Zugriff nicht sinnvoll genutzt
wird und bashed trotzdem drauf rum. Aber die Tatsache, dass das gesate
Program eigentlich nichts nützliches macht, außer alle Kanäle permanent
auf FF zu setzten wird gekonnt ignoriert. Nun ja geben wir dem Troll
noch etwas Futter. Hier nun eine etwas sinnvollere Anwendung von DMA,
dafür aber mit Interrupts.
1 /* _ _ _ _ _ _ _ _ _ _
2 * /\ \ /\ \ /\ \ /\_\ / /\ /\ \ /\ \ /\_\/\_\ _ /\ \
3 * / \ \ \_\ \ / \ \ / / / _ / / \ \_\ \ / \ \ / / / / //\_\ / \ \
4 * / /\ \ \ /\__ \ / /\ \ \ \ \ \__ /\_\ / / /\ \__ /\__ \ / /\ \ \ /\ \/ \ \/ / /__/ /\ \ \
5 * / / /\ \_\ / /_ \ \ / / /\ \ \ \ \___\ / / // / /\ \___\ / /_ \ \ / / /\ \ \ / \____\__/ //___/ /\ \ \
6 * / / /_/ / / / / /\ \ \ / / / \ \_\ \__ / / / / \ \ \ \/___// / /\ \ \ / / / \ \_\ / /\/________/ \___\/ / / /
7 * / / /__\/ / / / / \/_// / / \/_/ / / / / / / \ \ \ / / / \/_// / / / / // / /\/_// / / / / /
8 * / / /_____/ / / / / / / / / / / / /_ \ \ \ / / / / / / / / // / / / / / / / / _
9 * / / /\ \ \ / / / / / /________ / / /___/ / //_/\__/ / / / / / / / /___/ / // / / / / / \ \ \__/\_\
10 * / / / \ \ \/_/ / / / /_________\/ / /____\/ / \ \/___/ / /_/ / / / /____\/ / \/_/ / / / \ \___\/ /
11 * \/_/ \_\/\_\/ \/____________/\/_________/ \_____\/ \_\/ \/_________/ \/_/ \/___/_/
12 *
13 *
14 * DMX Output for ATxMega
15 * Tested with ATxMega256A3U
16 * Uses external 16 MHz oscillator together with internal PLL to generate 32MHz system clock
17 * DMX Signal will be transmitted through Port PC3
18 * DMA transfer used for transmission of DMX data to UART registers
19 * Low level interrupt priority für DMA transfer set
20 *
21 * Released under the "Don't care" license
22 * Feel free to use this code in any way you want
23 * Also no support will be given in any way
24 *
25 * Code V1.1
26 * 26.08.2015
27 */
28
29
30 #include <avr/io.h>
31 #include <util/delay.h>
32
33
34 enum { BREAK , STARTBYTE , DMXDATA };
35 unsigned char DMXStatus = BREAK ;
36
37
38
39 void Clock_init ( void )
40 {
41 //Xosc Bit 7&6 to 11 | Bit 3 to 0 as 1011
42 OSC . XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc ;
43 //Bit 3 to 1 to enable external oscillator
44 OSC . CTRL |= OSC_XOSCEN_bm ;
45 //wait for stable clock
46 while ( ! ( OSC . STATUS & OSC_XOSCRDY_bm ));
47 //Disable register protection for 4 clocks
48 CCP = CCP_IOREG_gc ;
49 //Set Bit 2:0 to 011 for external oscillator
50 CLK . CTRL = CLK_SCLKSEL_XOSC_gc ;
51 }
52
53 void PLL_init ( void )
54 {
55 //Bit 7:0 to 11 for external oscillator as PLL source | 2 as multiplication value
56 OSC . PLLCTRL = OSC_PLLSRC_XOSC_gc | 0x02 ;
57 //enable PLL
58 OSC . CTRL |= OSC_PLLEN_bm ;
59 //wait for stable oscillation
60 while ( ! ( OSC . STATUS & OSC_PLLRDY_bm ));
61 //Disable register protection for 4 clocks
62 CCP = CCP_IOREG_gc ;
63 //Set Bit 2:0 for PLL as clock source
64 CLK . CTRL = CLK_SCLKSEL_PLL_gc ;
65 }
66
67 void Init_uart ( void )
68 {
69 //configure usart
70 // Pin from USARTC0 TxD C3 set to output
71 PORTC . DIRSET = PIN3_bm ;
72 // Pin from USARTC0 TxD C3 to high
73 PORTC . OUTSET = PIN3_bm ;
74 // Asynchronous Modus Bit 7 & 6 to 0
75 USARTC0 . CTRLC = ( USARTC0 . CTRLC & ~ USART_CMODE_gm ) | USART_CMODE_ASYNCHRONOUS_gc ;
76 // No parity Bit 5 & 4 to 0
77 USARTC0 . CTRLC = ( USARTC0 . CTRLC & ~ USART_PMODE_gm ) | USART_PMODE_DISABLED_gc ;
78 // 2 stop bits Bit 3 to 1
79 USARTC0 . CTRLC = ( USARTC0 . CTRLC & ~ USART_SBMODE_bm ) | ( 0x01 << 3 );
80 // 8 data bits Bit 2 to 0 set to 011
81 USARTC0 . CTRLC = ( USARTC0 . CTRLC & ~ USART_CHSIZE_gm ) | USART_CHSIZE_8BIT_gc ;
82 // 100 kBaud
83 USARTC0 . BAUDCTRLA = 19 ;
84 // 100 kBaud
85 USARTC0 . BAUDCTRLB = ( 0x00 << USART_BSCALE0_bp ) | ( 19 >> 8 );
86 // activate USARTC1
87 USARTC0 . CTRLB = USART_TXEN_bm ;
88 }
89
90 //Configure DMA to transfer data from DMX array into UART buffer
91 void dma_set ( unsigned char * dmxdata , unsigned int length ){
92
93 // activate single buffer, burst size 1Byte
94 DMA . CTRL = DMA_CH_ENABLE_bm ;
95
96 //Modus transaction, increase and decrease, Burst
97 DMA . CH0 . ADDRCTRL = DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTRELOAD_NONE_gc | DMA_CH_DESTDIR_FIXED_gc ;
98
99 // Trigger Source is USARTC1 trigger if data buffer is empty
100 DMA . CH0 . TRIGSRC = DMA_CH_TRIGSRC_USARTC0_DRE_gc ;
101
102 //Set number of dmx channels to transfer
103 DMA . CH0 . TRFCNT = length ;
104
105 //8Bit source register
106 DMA . CH0 . SRCADDR0 = ((( uint16_t )( dmxdata )) >> 0 * 8 ) & 0xFF ;
107 DMA . CH0 . SRCADDR1 = ((( uint16_t )( dmxdata )) >> 1 * 8 ) & 0xFF ;
108 DMA . CH0 . SRCADDR2 = 0 ;
109
110 //8Bit target register at USARTC1
111 DMA . CH0 . DESTADDR0 = (( uint16_t ) & USARTC0 . DATA >> 0 * 8 ) & 0xFF ;
112 DMA . CH0 . DESTADDR1 = (( uint16_t ) & USARTC0 . DATA >> 1 * 8 ) & 0xFF ;
113 DMA . CH0 . DESTADDR2 = 0 ;
114
115 //Set CH0 transmission completed interrupt level to low
116 DMA . CH0 . CTRLB |= DMA_CH_TRNINTLVL_LO_gc ;
117 }
118
119
120 void Send_DMX_DMA ( unsigned char * dmxdata , unsigned int length )
121 {
122 //DMX is 250 kBaud 8N2 format
123 //Each package is framed by 1 start bit (0) and 2 stop bits (1)
124 //Start Condition is a >88µs break followed by >8 µs mark
125 //To generate Start condition reconfigure baud rate setting to 100 kBaud and send 0x00
126 //0x00 is 0000 0000 together with normal start bit = 9 low bits followed by two high bits from stop bits of 8N2 format
127 //At 100 kBaud a single bit time is 10µs
128 //9 x 10 µs = 90 µs low and 2 x 10 µs = 20 µs high
129 //Calculated register settings for 100 kBaud are BSCALE = 0 & BSEL = 019
130 //Calculated register settings for 250 kBaud are BSCALE = 0 & BSEL = 007
131 //Than always transfer a Null package to determine data type for channel transmission
132 //After this send out DMX payload data
133
134 //Generate break condition
135 if ( DMXStatus == BREAK )
136 {
137 //Reconfigure baud rate to 100 kBaud
138 USARTC0 . BAUDCTRLA = 19 ;
139 USARTC0 . BAUDCTRLB = ( 0 << USART_BSCALE0_bp ) | ( 19 >> 8 );
140 //Send a Zero to generate Break and Mark
141 USARTC0 . DATA = 0x00 ;
142 //Check for finished physical transmission and clear flag
143 while ( ! ( USARTC0 . STATUS & USART_TXCIF_bm ));
144 USARTC0 . STATUS |= USART_TXCIF_bm ;
145 //Switch to next step in DMX protocol. The start byte 0x00
146 DMXStatus = STARTBYTE ;
147 }
148
149
150
151 //Send information about type of DMX transmission
152 if ( DMXStatus == STARTBYTE )
153 {
154 //Reconfigure baud rate to 250 kBaud
155 USARTC0 . BAUDCTRLA = 07 ;
156 USARTC0 . BAUDCTRLB = ( 0 << USART_BSCALE0_bp ) | ( 07 >> 8 );
157 //Send a Zero to let DMX receivers know that now channels values will be send
158 USARTC0 . DATA = 0x00 ;
159 //Check for finished physical transmission and clear flag
160 while ( ! ( USARTC0 . STATUS & USART_TXCIF_bm ));
161 USARTC0 . STATUS |= USART_TXCIF_bm ;
162 //Switch to next step in DMX protocol and send channel informations
163 DMXStatus = DMXDATA ;
164
165 }
166
167
168 //Send DMX channel data
169 if ( DMXStatus == DMXDATA )
170 {
171 //Configure DMA to transmission data register and length
172 dma_set ( dmxdata , length );
173 //Activate DMA CH0 and send rest of DMX stream via DMA access
174 DMA . CH0 . REPCNT = 0 ;
175 DMA . CH0 . CTRLA = DMA_CH_ENABLE_bm | DMA_CH_SINGLE_bm | DMA_CH_BURSTLEN_1BYTE_gc ;
176 }
177 }
178
179
180 int main ( void )
181 {
182 Clock_init ();
183 PLL_init ();
184 Init_uart ();
185 //Port E to Output and High for routing Uart to SP3T Output
186 PORTE . DIRSET |= PIN6_bm ;
187 PORTE . OUTSET |= PIN6_bm ;
188
189 /* Enable LO interrupt level. */
190 PMIC . CTRL |= PMIC_LOLVLEN_bm ;
191 sei ();
192
193 unsigned char white [ 512 ] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
194 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
195 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
196 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
197 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
198 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF };
199
200 while ( 1 )
201 {
202 Send_DMX_DMA ( & white [ 0 ], 512 );
203 _delay_ms ( 1000 );
204 }
205
206 }
207
208 ISR ( DMA_CH0_vect )
209 {
210 //clear interrupt flag
211 DMA . CH0 . CTRLB |= DMA_CH_TRNIF_bm ;
212 //Deactivate DMA
213 DMA . CH0 . CTRLA &= ~ DMA_CH_ENABLE_bm ;
214 //Check for finished physical transmission and clear flag
215 while ( ! ( USARTC0 . STATUS & USART_TXCIF_bm ));
216 USARTC0 . STATUS |= USART_TXCIF_bm ;
217 //Go back to start of DMX protocol
218 DMXStatus = BREAK ;
219 }
Quizfrage wo liegt das Problem in dieser Form der Implementierung,
welche hier nicht abgefangen wird? Der beste Flame erhält einen
Rofelcopter als kostenloses GIF (Jiff)
von
Rajat (Gast)
26.09.2015 06:40
Your posting is abselutoly on the point!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.