Hallo zusammen, hat jemand von euch eine brauchbare Library für DMX Senden und Empfangen auf Atmel XMEGA in C zu Hand oder ist über sowas schonmal gestolpert? Am besten währe natürlich mit Einsatz des DMA Controllers, damit die Systemlast gering bleibt. Bei Elektor gab es wohl mal eine solche Codesammelung, leider hat der Author die Dateien wieder gelöscht. Gruß Chris
:
Verschoben durch User
Hallo zusammen, da scheinbar keiner eine Lösung hat, habe ich angefangen einen DMX Sender für den Atxmega256A3U zu schreiben. Zur Verbesserung der Systemperformance nutzte ich den DMA Modus für den Datentransfer aus dem DMX Datenarray hinüber zum UART. Bis dahin funktioniert das Programm auch schon. Daten senden via UART läuft. Probleme macht mir die Erzeugung des DMX spezifischen Frame Starts. DMX Verlangt ja einen 88µs Break, gefolgt von 8µs Mark vor der eigentlichen Datenübertragung. Zur Erzeugung dieser Bedingung wollte ich mit verlangsamter Datenrate eine 0x00 senden. Zusammen mit der "Null" vom Start Bit und den zwei "Eins" Stop Bits kommt man bei 100 kBaud so auf 90µs für den Break und 20 µs Mark. Leider schaffe ich es nicht die Datenrate zur Laufzeit zu ändern. Die grandiosen Debug Fähigkeiten des AVR Studio 6 sind dort auch keine große Hilfe. In meinem Programm warte ich darauf, dass das Data Register Empty flag gelöscht wird, ehe ich neue Daten in den Sendepuffer stelle. Der Debugger steppt auch schön durch, jedoch erhalte ich das gesamte Datenpacket immer mit der 250kBaud Datenrate an einem Stück. Jemand eine Idee wie man den XMega dazu bewegen kann die Datenrate des UART zur Laufzeit zu änder? Oder geht das beim XMega nicht mehr? Wobei mir kommt gerade eine Idee, geht das ändern der Datenrate vielleicht nur während einer ISR? Wie dem auch sei, hier mal der Quelltext für den DMX Output. Im Hautprogramm stelle ich eigentlich nur einen Systemtakt von 32 MHz ein und rufe dann die 3 Funktionen aus der dmx.h
1 | /*
|
2 | dmx.c
|
3 | Functions to send DMX data via USART
|
4 | Uses DMA to minimize system load during transfer of 512 bytes payload
|
5 | */
|
6 | |
7 | |
8 | #include "dmx.h" |
9 | #include <stdlib.h> |
10 | #include <avr/io.h> |
11 | |
12 | //The Buffer from where the DMX Data is read, Filled for test purpose with ABCDEABC...
|
13 | uint8_t dmxdata[dmxchannels] = {0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45}; |
14 | |
15 | //Configure DMA to transfer data from dmx buffer into usart buffer
|
16 | void dma_init(void){ |
17 | |
18 | // activate single buffer, burst size 1Byte
|
19 | DMA.CTRL = DMA_CH_ENABLE_bm; |
20 | |
21 | //Modus transaction, increase and decrease, Burst
|
22 | DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc| DMA_CH_DESTRELOAD_NONE_gc | DMA_CH_DESTDIR_FIXED_gc; |
23 | |
24 | // Trigger Source is USARTC1 trigger if data buffer is empty
|
25 | DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_DRE_gc; |
26 | |
27 | //Set number of dmx channels to transfer
|
28 | DMA.CH0.TRFCNT = dmxchannels; |
29 | |
30 | //8Bit source register
|
31 | DMA.CH0.SRCADDR0 =(((uint16_t)(&dmxdata))>>0*8)&0xFF; |
32 | DMA.CH0.SRCADDR1 =(((uint16_t)(&dmxdata))>>1*8)&0xFF; |
33 | DMA.CH0.SRCADDR2 = 0; |
34 | |
35 | //8Bit target register at USARTC1
|
36 | DMA.CH0.DESTADDR0 = ((uint16_t) &USARTC0.DATA >>0*8)&0xFF; |
37 | DMA.CH0.DESTADDR1 = ((uint16_t) &USARTC0.DATA >>1*8)&0xFF; |
38 | DMA.CH0.DESTADDR2 = 0; |
39 | }
|
40 | |
41 | //DMA Start
|
42 | void start_dmx(void){ |
43 | |
44 | //DMX is 250 kBaud 8N2 format
|
45 | //Each package is frames by 1 start bit (0) and 2 stop bits (1)
|
46 | //Start Condition is a >88µs break followed by >8 µs mark
|
47 | //Than always transfer a Null package to determine data type for channel transmission
|
48 | //To generate Start condition reconfigure baud rate setting to 100 kBaud and send 0x00
|
49 | //0x00 is 0000 0000 together with normal start bit = 9 low bits followed by two high bits from stop bits of 8N2 format
|
50 | //At 100 kBaud a single bit time is 10µs
|
51 | //9 x 10 µs = 90 µs & 2 x 10 µs = 20 µs
|
52 | //Calculated register settings for 100 kBaud are BSCALE = 0 & BSEL = 019
|
53 | //Calculated register settings for 250 kBaud are BSCALE = 0 & BSEL = 007
|
54 | |
55 | |
56 | |
57 | //Start DMX protocol with break condition
|
58 | if(DMXStatus == BREAK) |
59 | {
|
60 | //Wait for TX buffer to be empty
|
61 | while (!( USARTC0.STATUS & USART_DREIF_bm)); |
62 | {
|
63 | //Reconfigure baud rate to 100 kBaud
|
64 | USARTC0.BAUDCTRLA = 19; |
65 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(19 >> 8); |
66 | //Send a Zero to generate Break and Mark
|
67 | USARTC0.DATA = 0x00; |
68 | //Switch to next step in DMX protocol the start byte 0x00
|
69 | DMXStatus = STARTBYTE; |
70 | }
|
71 | }
|
72 | |
73 | |
74 | |
75 | //Send information about type of DMX transmission
|
76 | if(DMXStatus == STARTBYTE) |
77 | {
|
78 | //Wait for TX buffer to be empty
|
79 | while (!( USARTC0.STATUS & USART_DREIF_bm)); |
80 | {
|
81 | //Reconfigure baud rate to 250 kBaud
|
82 | USARTC0.BAUDCTRLA = 007; |
83 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(007 >> 8); |
84 | //Send a Zero to let DMX receivers know that now channels values will be send
|
85 | USARTC0.DATA = 0x00; |
86 | //Switch to next step in DMX protocol and send channel informations
|
87 | DMXStatus = DMXDATA; |
88 | }
|
89 | }
|
90 | |
91 | |
92 | //Send DMX channel data
|
93 | if(DMXStatus == DMXDATA) |
94 | {
|
95 | //Wait for TX buffer to be empty
|
96 | while (!( USARTC0.STATUS & USART_DREIF_bm)); |
97 | {
|
98 | // DMA CH0 activate send rest of DMX stream via DMA access
|
99 | DMA.CH0.REPCNT = 0; |
100 | DMA.CH0.CTRLA = DMA_CH_ENABLE_bm |DMA_CH_SINGLE_bm|DMA_CH_BURSTLEN_1BYTE_gc; |
101 | //Go back to start of DMX protocol
|
102 | DMXStatus = BREAK; |
103 | }
|
104 | }
|
105 | |
106 | |
107 | }
|
108 | |
109 | void usart_init(void){ |
110 | |
111 | //configure usart
|
112 | // Pin from USARTC0 TxD C3 set to output
|
113 | PORTC.DIRSET = PIN3_bm; |
114 | // Pin from USARTC0 TxD C3 to high
|
115 | PORTC.OUTSET = PIN3_bm; |
116 | // Asynchronous Modus
|
117 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_CMODE_gm ) | USART_CMODE_ASYNCHRONOUS_gc; |
118 | // No parity
|
119 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_PMODE_gm ) | USART_PMODE_DISABLED_gc; |
120 | // 8 data bits
|
121 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_CHSIZE_gm ) | USART_CHSIZE_8BIT_gc; |
122 | // 2 stop bits
|
123 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_SBMODE_bm) | (0x01<<3); |
124 | // 100 kBaud
|
125 | USARTC0.BAUDCTRLA = 19; |
126 | // 100 kBaud
|
127 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(19 >> 8); |
128 | // activate USARTC1
|
129 | USARTC0.CTRLB = USART_TXEN_bm; |
130 | //Set DMX Status to Break Condition
|
131 | DMXStatus = BREAK; |
132 | }
|
dmx.h
1 | /*
|
2 | * dmx.h
|
3 | */
|
4 | |
5 | |
6 | #ifndef DMX_H_
|
7 | #define DMX_H_
|
8 | |
9 | |
10 | #define dmxchannels 20
|
11 | |
12 | void dma_init(void); |
13 | void start_dmx(void); |
14 | void usart_init(void); |
15 | |
16 | enum{BREAK, STARTBYTE, DMXDATA}; |
17 | unsigned char DMXStatus; |
18 | |
19 | #endif /* DMX_H_ */ |
@ Chris N. (Gast) >Probleme macht mir die Erzeugung des DMX spezifischen Frame Starts. DMX >Verlangt ja einen 88µs Break, gefolgt von 8µs Mark vor der eigentlichen >Datenübertragung. Zur Erzeugung dieser Bedingung wollte ich mit >verlangsamter Datenrate eine 0x00 senden. Zusammen mit der "Null" vom >Start Bit und den zwei "Eins" Stop Bits kommt man bei 100 kBaud so auf >90µs für den Break und 20 µs Mark. >Leider schaffe ich es nicht die Datenrate zur Laufzeit zu ändern. Machs nicht zu kompliziert. Erzeuge den BREAK + Pause danach einfach per _delay_us() IN der ISR, JA, IN der ISR. Das ist hier schon OK. >Hilfe. In meinem Programm warte ich darauf, dass das Data Register Empty >flag gelöscht wird, ehe ich neue Daten in den Sendepuffer stelle. Falsch. Du musst das TXC Flag prüfen, erst DANN ist das Byte vollständiug gesendet. >UART zur Laufzeit zu änder? Oder geht das beim XMega nicht mehr? Das glaube ich nicht.
Hallo Falk, das mit dem TXC Flag hatte ich auch schon versucht, aber wohl ein großes Brett vor dem Kopf gehabt. Ich habe schon im Break geprüft, ob das TXC Flag gesetzt ist, kann natürlich nicht, weil ich zuvor ja nie was gesendet habe. Also im Break weiterhin auf DREIF prüfen und bei Start und Daten dann auf TXC. Schon klappt es auch ganz ohne Interrupts oder Timer
1 | /*
|
2 | dmx.c
|
3 | Functions to send DMX data via USART
|
4 | Uses DMA to minimize system load during transfer of 512 bytes payload
|
5 | */
|
6 | |
7 | |
8 | #include "dmx.h" |
9 | #include <stdlib.h> |
10 | #include <avr/io.h> |
11 | |
12 | //The Buffer from where the DMX Data is read, Filled for test purpose with ABCDEABC...
|
13 | uint8_t dmxdata[dmxchannels] = {0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45}; |
14 | |
15 | //Configure DMA to transfer data from dmx buffer into usart buffer
|
16 | void dma_init(void){ |
17 | |
18 | // activate single buffer, burst size 1Byte
|
19 | DMA.CTRL = DMA_CH_ENABLE_bm; |
20 | |
21 | //Modus transaction, increase and decrease, Burst
|
22 | DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc| DMA_CH_DESTRELOAD_NONE_gc | DMA_CH_DESTDIR_FIXED_gc; |
23 | |
24 | // Trigger Source is USARTC1 trigger if data buffer is empty
|
25 | DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_DRE_gc; |
26 | |
27 | //Set number of dmx channels to transfer
|
28 | DMA.CH0.TRFCNT = dmxchannels; |
29 | |
30 | //8Bit source register
|
31 | DMA.CH0.SRCADDR0 =(((uint16_t)(&dmxdata))>>0*8)&0xFF; |
32 | DMA.CH0.SRCADDR1 =(((uint16_t)(&dmxdata))>>1*8)&0xFF; |
33 | DMA.CH0.SRCADDR2 = 0; |
34 | |
35 | //8Bit target register at USARTC1
|
36 | DMA.CH0.DESTADDR0 = ((uint16_t) &USARTC0.DATA >>0*8)&0xFF; |
37 | DMA.CH0.DESTADDR1 = ((uint16_t) &USARTC0.DATA >>1*8)&0xFF; |
38 | DMA.CH0.DESTADDR2 = 0; |
39 | }
|
40 | |
41 | //DMA Start
|
42 | void start_dmx(void){ |
43 | |
44 | //DMX is 250 kBaud 8N2 format
|
45 | //Each package is frames by 1 start bit (0) and 2 stop bits (1)
|
46 | //Start Condition is a >88µs break followed by >8 µs mark
|
47 | //Than always transfer a Null package to determine data type for channel transmission
|
48 | //To generate Start condition reconfigure baud rate setting to 100 kBaud and send 0x00
|
49 | //0x00 is 0000 0000 together with normal start bit = 9 low bits followed by two high bits from stop bits of 8N2 format
|
50 | //At 100 kBaud a single bit time is 10µs
|
51 | //9 x 10 µs = 90 µs & 2 x 10 µs = 20 µs
|
52 | //Calculated register settings for 100 kBaud are BSCALE = 0 & BSEL = 019
|
53 | //Calculated register settings for 250 kBaud are BSCALE = 0 & BSEL = 007
|
54 | |
55 | |
56 | |
57 | //Start DMX protocol with break condition
|
58 | if(DMXStatus == BREAK) |
59 | {
|
60 | //Wait for TX buffer to be empty
|
61 | while (!( USARTC0.STATUS & USART_DREIF_bm)); |
62 | {
|
63 | //Reconfigure baud rate to 100 kBaud
|
64 | USARTC0.BAUDCTRLA = 19; |
65 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(19 >> 8); |
66 | //Send a Zero to generate Break and Mark
|
67 | USARTC0.DATA = 0x00; |
68 | //Switch to next step in DMX protocol the start byte 0x00
|
69 | DMXStatus = STARTBYTE; |
70 | }
|
71 | }
|
72 | |
73 | |
74 | |
75 | //Send information about type of DMX transmission
|
76 | if(DMXStatus == STARTBYTE) |
77 | {
|
78 | //Wait for TX buffer to be empty
|
79 | while (!( USARTC0.STATUS & USART_TXCIF_bm)); |
80 | {
|
81 | //Reconfigure baud rate to 250 kBaud
|
82 | USARTC0.BAUDCTRLA = 07; |
83 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(07 >> 8); |
84 | //Send a Zero to let DMX receivers know that now channels values will be send
|
85 | USARTC0.DATA = 0x00; |
86 | //Switch to next step in DMX protocol and send channel informations
|
87 | DMXStatus = DMXDATA; |
88 | }
|
89 | }
|
90 | |
91 | |
92 | //Send DMX channel data
|
93 | if(DMXStatus == DMXDATA) |
94 | {
|
95 | //Wait for TX buffer to be empty
|
96 | while (!( USARTC0.STATUS & USART_TXCIF_bm)); |
97 | {
|
98 | // DMA CH0 activate send rest of DMX stream via DMA access
|
99 | DMA.CH0.REPCNT = 0; |
100 | DMA.CH0.CTRLA = DMA_CH_ENABLE_bm |DMA_CH_SINGLE_bm|DMA_CH_BURSTLEN_1BYTE_gc; |
101 | //Go back to start of DMX protocol
|
102 | DMXStatus = BREAK; |
103 | }
|
104 | }
|
105 | |
106 | |
107 | }
|
108 | |
109 | void usart_init(void){ |
110 | |
111 | //configure usart
|
112 | // Pin from USARTC0 TxD C3 set to output
|
113 | PORTC.DIRSET = PIN3_bm; |
114 | // Pin from USARTC0 TxD C3 to high
|
115 | PORTC.OUTSET = PIN3_bm; |
116 | // Asynchronous Modus
|
117 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_CMODE_gm ) | USART_CMODE_ASYNCHRONOUS_gc; |
118 | // No parity
|
119 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_PMODE_gm ) | USART_PMODE_DISABLED_gc; |
120 | // 8 data bits
|
121 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_CHSIZE_gm ) | USART_CHSIZE_8BIT_gc; |
122 | // 2 stop bits
|
123 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_SBMODE_bm) | (0x01<<3); |
124 | // 100 kBaud
|
125 | USARTC0.BAUDCTRLA = 19; |
126 | // 100 kBaud
|
127 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(19 >> 8); |
128 | // activate USARTC1
|
129 | USARTC0.CTRLB = USART_TXEN_bm; |
130 | //Set DMX Status to Break Condition
|
131 | DMXStatus = BREAK; |
132 | }
|
Somit haben wir hier ein einfaches Grundgerüst für das Senden von DMX via UART mit DMA auf einem XMega.
Mist zu früh gefreut, klappt nur beim ersten mal. Danach stimmt am Anfang wieder die Datenrate nicht argh
Ok, ich kommme nicht dahinter was der UART in meiner Software treibt. Die erste Übertragung von DMX Daten funktioniert wie gewünscht. Bei der zweiten stimmt das Timing nicht. Ich habe das Programm jetzt so umgebaut, dass ich sicherstelle, dass die DMA Übertragung abgeschlossen ist, der UART die Daten auch wirklich auf den PIN ausgegeben hat und ich deaktiviere sogar den UART vor dem Umkonfigurieren auf die langsame Baudrate wieder. Dennoch ist im zweiten DMX durchgang immer der Wurm drin. Zur besseren Übersichtlichkeit der Daten habe ich das erste Null Bit mal auf CC gesetzt. Lasse ich nun die Break Erzeugung auf 00 stehen kommen alle Daten mit 250 kBaud raus, auch das Break. Änder ich die Break Erzeugung einfach mal auf zum Beispiel 0x46 passt gleich die ganze Datenübertragung nicht mehr. Noch jemand eine Idee was mit dem UART nicht stimmt?
1 | /*
|
2 | dmx.c
|
3 | Functions to send DMX data via USART
|
4 | Uses DMA to minimize system load during transfer of 512 bytes payload
|
5 | */
|
6 | |
7 | |
8 | #include "dmx.h" |
9 | #include <stdlib.h> |
10 | #include <avr/io.h> |
11 | |
12 | //The Buffer from where the DMX Data is read, Filled for test purpose with ABCDEABC...
|
13 | uint8_t dmxdata[dmxchannels] = {0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45,0x41,0x42,0x43,0x44,0x45}; |
14 | |
15 | //Configure DMA to transfer data from dmx buffer into usart buffer
|
16 | void dma_init(void){ |
17 | |
18 | // activate single buffer, burst size 1Byte
|
19 | DMA.CTRL = DMA_CH_ENABLE_bm; |
20 | |
21 | //Modus transaction, increase and decrease, Burst
|
22 | DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_TRANSACTION_gc | DMA_CH_SRCDIR_INC_gc| DMA_CH_DESTRELOAD_NONE_gc | DMA_CH_DESTDIR_FIXED_gc; |
23 | |
24 | // Trigger Source is USARTC1 trigger if data buffer is empty
|
25 | DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_DRE_gc; |
26 | |
27 | //Set number of dmx channels to transfer
|
28 | DMA.CH0.TRFCNT = dmxchannels; |
29 | |
30 | //8Bit source register
|
31 | DMA.CH0.SRCADDR0 =(((uint16_t)(&dmxdata))>>0*8)&0xFF; |
32 | DMA.CH0.SRCADDR1 =(((uint16_t)(&dmxdata))>>1*8)&0xFF; |
33 | DMA.CH0.SRCADDR2 = 0; |
34 | |
35 | //8Bit target register at USARTC1
|
36 | DMA.CH0.DESTADDR0 = ((uint16_t) &USARTC0.DATA >>0*8)&0xFF; |
37 | DMA.CH0.DESTADDR1 = ((uint16_t) &USARTC0.DATA >>1*8)&0xFF; |
38 | DMA.CH0.DESTADDR2 = 0; |
39 | }
|
40 | |
41 | //DMA Start
|
42 | void start_dmx(void){ |
43 | |
44 | //DMX is 250 kBaud 8N2 format
|
45 | //Each package is frames by 1 start bit (0) and 2 stop bits (1)
|
46 | //Start Condition is a >88µs break followed by >8 µs mark
|
47 | //Than always transfer a Null package to determine data type for channel transmission
|
48 | //To generate Start condition reconfigure baud rate setting to 100 kBaud and send 0x00
|
49 | //0x00 is 0000 0000 together with normal start bit = 9 low bits followed by two high bits from stop bits of 8N2 format
|
50 | //At 100 kBaud a single bit time is 10µs
|
51 | //9 x 10 µs = 90 µs & 2 x 10 µs = 20 µs
|
52 | //Calculated register settings for 100 kBaud are BSCALE = 0 & BSEL = 019
|
53 | //Calculated register settings for 250 kBaud are BSCALE = 0 & BSEL = 007
|
54 | |
55 | |
56 | |
57 | //Start DMX protocol with break condition
|
58 | if(DMXStatus == BREAK || FIRSTBREAK) |
59 | {
|
60 | |
61 | |
62 | //Wait for TX buffer to be empty
|
63 | if(DMXStatus==FIRSTBREAK) |
64 | {
|
65 | //Send a Zero to generate Break and Mark
|
66 | USARTC0.DATA = 0x00; |
67 | //Switch to next step in DMX protocol the start byte 0x00
|
68 | DMXStatus = STARTBYTE; |
69 | }
|
70 | else
|
71 | {
|
72 | //Check is DMA transaction is running in background
|
73 | while (!(DMA.INTFLAGS & DMA_CH0TRNIF_bm) || (DMA.CH0.CTRLB & (DMA_CH_CHBUSY_bm | DMA_CH_CHPEND_bm))); |
74 | DMA.INTFLAGS |= DMA_CH0TRNIF_bm; |
75 | |
76 | //Deactivate DMA
|
77 | DMA.CH0.CTRLA &= ~DMA_CH_ENABLE_bm; |
78 | |
79 | //Check for UART Data has been physical shifted out
|
80 | while (!( USARTC0.STATUS & USART_TXCIF_bm)); |
81 | |
82 | //Deactivate USART
|
83 | USARTC0.CTRLB = 0x00; |
84 | |
85 | |
86 | //configure usart
|
87 | // Pin from USARTC0 TxD C3 set to output
|
88 | PORTC.DIRSET = PIN3_bm; |
89 | // Pin from USARTC0 TxD C3 to high
|
90 | PORTC.OUTSET = PIN3_bm; |
91 | // Asynchronous Modus
|
92 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_CMODE_gm ) | USART_CMODE_ASYNCHRONOUS_gc; |
93 | // No parity
|
94 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_PMODE_gm ) | USART_PMODE_DISABLED_gc; |
95 | // 8 data bits
|
96 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_CHSIZE_gm ) | USART_CHSIZE_8BIT_gc; |
97 | // 2 stop bits
|
98 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_SBMODE_bm) | (0x01<<3); |
99 | // 100 kBaud
|
100 | USARTC0.BAUDCTRLA = 19; |
101 | // 100 kBaud
|
102 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(19 >> 8); |
103 | // activate USARTC1
|
104 | USARTC0.CTRLB = USART_TXEN_bm; |
105 | //Set DMX Status to Break Condition
|
106 | |
107 | //Send a Zero to generate Break and Mark
|
108 | USARTC0.DATA = 0x00; |
109 | //Switch to next step in DMX protocol the start byte 0x00
|
110 | DMXStatus = STARTBYTE; |
111 | }
|
112 | }
|
113 | |
114 | |
115 | |
116 | //Send information about type of DMX transmission
|
117 | if(DMXStatus == STARTBYTE) |
118 | {
|
119 | //Check for UART Data has been physical shifted out
|
120 | while (!( USARTC0.STATUS & USART_TXCIF_bm)); |
121 | |
122 | //Reconfigure baud rate to 250 kBaud
|
123 | USARTC0.BAUDCTRLA = 07; |
124 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(07 >> 8); |
125 | //Send a Zero to let DMX receivers know that now channels values will be send
|
126 | USARTC0.DATA = 0xCC; |
127 | //Switch to next step in DMX protocol and send channel informations
|
128 | DMXStatus = DMXDATA; |
129 | |
130 | }
|
131 | |
132 | |
133 | //Send DMX channel data
|
134 | if(DMXStatus == DMXDATA) |
135 | {
|
136 | //Check for UART Data has been physical shifted out
|
137 | while (!( USARTC0.STATUS & USART_TXCIF_bm)); |
138 | |
139 | // DMA CH0 activate send rest of DMX stream via DMA access
|
140 | DMA.CH0.REPCNT = 0; |
141 | DMA.CH0.CTRLA = DMA_CH_ENABLE_bm |DMA_CH_SINGLE_bm|DMA_CH_BURSTLEN_1BYTE_gc; |
142 | //Go back to start of DMX protocol
|
143 | DMXStatus = BREAK; |
144 | }
|
145 | |
146 | |
147 | }
|
148 | |
149 | void usart_init(void){ |
150 | |
151 | //configure usart
|
152 | // Pin from USARTC0 TxD C3 set to output
|
153 | PORTC.DIRSET = PIN3_bm; |
154 | // Pin from USARTC0 TxD C3 to high
|
155 | PORTC.OUTSET = PIN3_bm; |
156 | // Asynchronous Modus
|
157 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_CMODE_gm ) | USART_CMODE_ASYNCHRONOUS_gc; |
158 | // No parity
|
159 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_PMODE_gm ) | USART_PMODE_DISABLED_gc; |
160 | // 8 data bits
|
161 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_CHSIZE_gm ) | USART_CHSIZE_8BIT_gc; |
162 | // 2 stop bits
|
163 | USARTC0.CTRLC = (USARTC0.CTRLC & ~USART_SBMODE_bm) | (0x01<<3); |
164 | // 100 kBaud
|
165 | USARTC0.BAUDCTRLA = 19; |
166 | // 100 kBaud
|
167 | USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(19 >> 8); |
168 | // activate USARTC1
|
169 | USARTC0.CTRLB = USART_TXEN_bm; |
170 | //Set DMX Status to Break Condition
|
171 | DMXStatus = FIRSTBREAK; |
172 | }
|
//Reconfigure baud rate to 250 kBaud USARTC0.BAUDCTRLA = 07; USARTC0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(07 >> 8); Schau mal in XMEGA Manual unter BAUDCTRLB – Baud Rate register B Writing BAUDCTRLA will trigger an immediate update of the baud rate prescaler. Ich glaube, du solltest erst CTRLB und danach CTRLA beschreiben.
1 | //Check for UART Data has been physical shifted out
|
2 | while (!( USARTC0.STATUS & USART_TXCIF_bm)); |
ist ja schön und gut. Aber wo setzt du das flag zurück? Einen IRQ scheinst du ja nicht konfiguriert zu haben. Und so wie ich das lese:
1 | This flag is set when the entire frame in the transmit shift register has been shifted out and there are no new data in the |
2 | transmit buffer (DATA). TXCIF is automatically cleared when the transmit complete interrupt vector is executed. The flag |
3 | can also be cleared by writing a one to its bit location. |
geht das nicht von selbst wieder auf 0. BTW: wo ist das Problem mit 31K Interrupts / Sec? Da bleiben doch ewig lange 1024 Ticks zwischen 2 Bytes...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.