Forum: Mikrocontroller und Digitale Elektronik DMX Lib für Xmega bekannt?


von Chris N. (Gast)


Lesenswert?

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
von Chris N. (Gast)


Angehängte Dateien:

Lesenswert?

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_ */

von Falk B. (falk)


Lesenswert?

@ 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.

von Chris N. (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Chris N. (Gast)


Lesenswert?

Mist zu früh gefreut, klappt nur beim ersten mal. Danach stimmt am 
Anfang wieder die Datenrate nicht argh

von Chris N. (Gast)


Angehängte Dateien:

Lesenswert?

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
}

von Falk B. (falk)


Lesenswert?

//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.

von tim (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.