Forum: Mikrocontroller und Digitale Elektronik Playstation Controller mit FullDuplex-SPI


von Karl (Gast)


Lesenswert?

Hey,

ich habe noch einen Playstation 2 Controller liegen und wollte den nun 
für meine zukünftigen AVR-Projekte flott machen. Ich habe nun auch eine 
Homepage mit der Ansteuerung gefunden...

http://store.curiousinventor.com/guides/PS2

Auf den Ansteuerungsbilder ist zu erkennen, das gleichzeitig gesendet 
und empfangen wird (full-duplex).
Nun wollte ich dafür mein SPI-Interface als Full-Duplex verwenden und 
konfigurieren. Dazu habe ich nun den Code aus dem Datenblatt 
abgeändert...
1
void SPI_MasterInit(void)
2
{
3
  /* Set MOSI and SCK output, all others input */
4
  DDRB |= ((1<<PB5)|(1<<PB7));
5
  /* Enable SPI, Master, set clock rate fck/128 */
6
  SPCR0 = (1<<SPE0)|(1<<MSTR0)|(1<<SPR00)|(1<<SPR10)|(1<<DORD0)|(1<<CPOL0)|(1<<CPHA0);
7
}
8
void SPI_MasterTransmit(char cData)
9
{
10
  /* Start transmission */
11
  SPDR0 = cData;
12
  /* Wait for transmission complete */
13
  while(!(SPSR0 & (1<<SPIF0)))
14
  ;
15
}
16
17
void SPI_SlaveInit(void)
18
{
19
  /* Set MISO output, all others input */
20
  DDRB = (1<<PB6);
21
  /* Enable SPI */
22
  SPCR0 = (1<<SPE0)|(1<<SPR00)|(1<<SPR10)|(1<<DORD0)|(1<<CPOL0)|(1<<CPHA0);
23
}
24
char SPI_SlaveReceive(void)
25
{
26
  /* Wait for reception complete */
27
  while(!(SPSR0 & (1<<SPIF0)))
28
  ;
29
  /* Return Data Register */
30
  return SPDR0;
31
}

Aber man arbeitet beim Schreiben und Lesen mit dem selben Register 
(SPDR0). Wie mach ich das nun gleichzeitig? Ausserdem müsste ich dann ja 
permanent die Master und Slave Initialisierung tauschen?!

Irgendwas habe ich noch nicht ganz verstanden und bräuchte Hilfe

Vielen Dank

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Eine SPI-Übertragung ist i.d.R. immer eine Vollduplexübertragung, da mit 
jedem gesendeten Byte auch eines empfangen wird. Den Takt gibt der 
Master vor, ein Hin- und Herschalten zwischen Master- und Slave-Betrieb 
ist weder erforderlich noch sinnvoll.

von Karl (Gast)


Lesenswert?

Mhm, aber ich bekomme vom Controller nichts zurück

folgender Code
1
void control()
2
{
3
  DDRB |= (1<<PB1);
4
  PORTB |= (1<<PB1);
5
  _delay_ms(2);
6
  
7
  PORTB &= ~(1<<PB1);
8
  SPI_MasterTransmit(0x01);
9
  data[0]=(uint8_t)SPI_MasterReceive();
10
11
  SPI_MasterTransmit(0x42);
12
  PORTB &= ~(1<<PB1);
13
  data[1]=(uint8_t)SPI_MasterReceive();
14
  PORTB |= (1<<PB1);
15
16
  SPI_MasterTransmit(0x00);
17
  PORTB &= ~(1<<PB1);
18
  data[2]=(uint8_t)SPI_MasterReceive();
19
  PORTB |= (1<<PB1);
20
  _delay_ms(1);
21
}
22
23
void SPI_MasterInit(void)
24
{
25
  /* Set MOSI and SCK output, all others input */
26
  DDRB |= ((1<<PB5)|(1<<PB7));
27
  /* Enable SPI, Master, set clock rate fck/16 */
28
  SPCR0 =(1<<SPE0)|(1<<MSTR0)|(1<<SPR00)|(1<<SPR10)|(1<<DORD0)|(1<<CPOL0)|(1<<CPHA0);
29
}
30
void SPI_MasterTransmit(char cData)
31
{
32
  /* Start transmission */
33
  SPDR0 = cData;
34
  /* Wait for transmission complete */
35
  while(!(SPSR0 & (1<<SPIF0)))
36
  ;
37
}
38
char SPI_MasterReceive(void)
39
{
40
  /* Wait for reception complete */
41
  while(!(SPSR0 & (1<<SPIF0)))
42
  ;
43
  /* Return Data Register */
44
  return SPDR0;
45
}

PB1 ist meine Attention-Leitung. Ich habe auf meinem oszi nachgesehen, 
clk und command werden übermittelt. Allerdings bekomme ich vom 
PS-Controller weder data noch ack gesendet -.-

Sieht jemand einen Fehler?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Da das Senden und Empfangen simultan abläuft, sollte unmittelbar nach 
dem Senden mit einem Lesezugriff auf das Datenregister SPDR0 der 
empfangene Wert zur Verfügung stehen.

Das sollte also in etwa so aussehen:
1
uint8_t SPI_SendAndReceive(uint8_t Data)
2
{
3
  /* Start transmission */
4
  SPDR0 = Data;
5
  /* Wait for transmission complete */
6
  while(!(SPSR0 & (1<<SPIF0)))
7
  ;
8
  return SPDR0
9
}

(Ich kann das nicht testen, da ich keine AVRs programmiere)

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.