XMega USART in SPI-Mode, CS-Problem

OP #3096582
Lesenswert?
• ▲
▼
Moin,

Hab hier nen ziemliches Problem mit nem XMega.
Ich will den USARTC1 in SPI-Mode betreiben. Dabei möchte ich 32 bits 
übertragen.

Mein Ansatz: USARTC1 initialisieren, CS -> low, 4x das Datenregister 
beschreiben (vorm schreiben Prüfen ob frei) und danach wieder CS -> 
High.

Mein Problem: siehe Foto.
oben dargestellt die SCK-Leitung, unten die CS-Leitung. Irgendwie wird 
die zu früh wieder H gesetzt, hab aber keine Peilung woher das kommt.

Hier der Code:
1
void UART_5004_write(const uint8_t adr, const uint32_t data){
2
  PORTC.OUTCLR = (1<<CS_5004_PIN);
3
  while (!(USARTC1.STATUS & USART_DREIF_bm));
4
  USARTC1.DATA  = adr;
5
  while(!(USARTC1.STATUS & USART_TXCIF_bm));
6

7
  USARTC1.DATA = (data>>16);
8
  /while(!(USARTC1.STATUS & USART_TXCIF_bm));
9

10
  USARTC1.DATA = (data>>8);
11
  while(!(USARTC1.STATUS & USART_TXCIF_bm));
12

13
  USARTC1.DATA = (data);
14
  while(!(USARTC1.STATUS & USART_TXCIF_bm));
15

16
  PORTC.OUTSET = (1<<CS_5004_PIN);
17
  _delay_us(10);
18
} 
19

20
void PE5004_init_UART(void){
21
  PORTC.DIRSET = (1<<SCK_5004_PIN)|(1<<MOSI_5004_PIN)|(1<<CS_5004_PIN);
22
  PORTC.OUTSET = (1<<CS_5004_PIN);
23
  PORTC.DIRCLR = (1<<MISO_5004_PIN);
24
  PORTD.DIRCLR = (1<<INT_5004_PIN);
25
  USARTC1.CTRLA = 0;
26
  USARTC1.CTRLB = 0x1C;  // TX Enabled, Rx enabled, Double speed
27
  USARTC1.CTRLC = 0xC0;  // UART in SPI-Mode, MSB First, 
28
  USARTC1.BAUDCTRLA = 0x05;  // 32 MHz/(2*(5+1)) = 32 MHz / 12 = 2,666 MHz // Evtl auch 0x04 möglich -> 3,2 MHz  
29
  
30
  UART_5004_write(0x05, 0x02);    // Select SPI
31
  UART_5004_write(0x02, (WAITCOL<<12)|WAITROW);
32
  UART_5004_write(0x03, (SinePush<<23)|(SINF<<18)|(SINA<<12)|(PWRI<<11)|(GCO<<4)|DACREF);
33
  UART_5004_write(0x04, PCO);
34
}
Angehängte Dateien:
#3096816
Lesenswert?
• ▲
▼
Hallo,

das TXCIF-Flag wird ohne aktivierten TXC-Interrupt nicht automatisch 
gelöscht! Du musst es voher mit einer 1 beschreiben um es 
zurückzusetzen. Die Ausgabe kannst du besser mit dem UDRE-Flag steuern, 
denn so kannst du den Puffer des UART ordentlich verwenden - allerdings 
macht das die Auswertung wann die Bytes versendet sind nicht einfacher. 
Mann könnte aber z.B. über die RX-ISR die Anzahl der empfangenen Bytes 
zählen, und wenn 4 Byte empfangen sind, wurden auch 4 Byte gesendet.

Sascha
OP #3096840
Lesenswert?
• ▲
▼
Danke für den Tip!

setze jetzt hinter jeder while-schleife das flag mit
1
USARTC1.STATUS |= USART_TXCIF_bm
zurück, damit funktionierts!

Das UDRE-Flag habe ich bewusst nicht verwendet, denn das zeigt ja nur an 
wann ich das datenregister verwenden kann (eben wenns leer ist). Das 
TXIC Flag hingen wird erst gesetzt wenn das ganze byte durch das 
register durchgeschoben wurde.

Auf Interrupts wollte ich an der stelle noch verzichten, ich bin an 
dieser stelle erst noch in der initialisierungsphase, da muss ich 
lediglich die 4x32 bits durchschieben. Da kann ich auch mal warten. 
Später zum auslesen muss ich dann aber eventgesteurt den DMA Controller 
verwenden.

Nochmals Danke!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren