Forum: Mikrocontroller und Digitale Elektronik XMEGA + iPod


von Dominik N. (Firma: HTL-Salzburg) (dominik_hanniball)


Lesenswert?

Hallo!

Ich möchte meinen iPod 4G ansteuern. Ich fange erst an mich mit dem
iPod zu beschäftigen. Der iPod ist bereits richtig angeschlossen + 500k 
Widerstand ( mit Hilfe des iPod Dockouts)

Als Hilfe für den UART habe ich den Sample Code von Atmel verwendet.
Der iPod antwortet mir jedoch reagiert er nicht auf meine Befehle:

Dankeschön für Eure Hilfe
Code:



#include "usart_driver.h"
#include "avr_compiler.h"

/*! Number of bytes to send in test example. */
#define NUM_BYTES  7
/*! Define that selects the Usart used in example. */
#define USART USARTC0

/*! USART data struct used in example. */
USART_data_t USART_data;
/*! Test data to send. */
uint8_t sendArray[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x08, 
0xF3};
uint8_t sendArray2[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x00, 
0xFB};
uint8_t sendArray3[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x00, 0x01, 0x02, 
0xFA};
uint8_t sendArray_Air[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x00, 0x01, 0x04, 
0xF8};



//uint8_t sendArray[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x00, 0x01, 0x01, 
0xFB};
/*! Array to put received data in. */
uint8_t receiveArray[NUM_BYTES];
//uint8_t receiveArray2[NUM_BYTES];
/*! Success variable, used to test driver. */
bool success;


/*! \brief Example application.
 *
 *  Example application. This example configures USARTC0 for with the 
parameters:
 *      - 8 bit character size
 *      - No parity
 *      - 1 stop bit
 *      - 19200 Baud
 *
 *  This function then sends three bytes and tests if the received data 
is
 *  equal to the sent data. The code can be tested by connecting PC3 to 
PC2. If
 *  the variable 'success' is true at the end of the function, the three 
bytes
 *  have been successfully sent and received.
*/
int main(void)
{
  /* counter variable. */
  uint8_t i;

  /* This PORT setting is only valid to USARTC0 if other USARTs is used 
a
   * different PORT and/or pins are used. */
    /* PC3 (TXD0) as output. */
  PORTC.DIRSET   = PIN3_bm;
  /* PC2 (RXD0) as input. */
  PORTC.DIRCLR   = PIN2_bm;

  /* Use USARTC0 and initialize buffers. */
  USART_InterruptDriver_Initialize(&USART_data, &USART, 
USART_DREINTLVL_LO_gc);

  /* USARTC0, 8 Data bits, No Parity, 1 Stop bit. */
  USART_Format_Set(USART_data.usart, USART_CHSIZE_8BIT_gc,
                     USART_PMODE_DISABLED_gc, false);

  /* Enable RXC interrupt. */
  USART_RxdInterruptLevel_Set(USART_data.usart, USART_RXCINTLVL_LO_gc);

  /* Set Baudrate to 19200 bps:
   * Use the default I/O clock frequency that is 2 MHz.
   * Do not use the baudrate scale factor
   *
   * Baudrate select = (1/(16*(((I/O clock frequency)/Baudrate)-1)
   *                 = 12
   */
  USART_Baudrate_Set(&USART, 6 , 0);

  /* Enable both RX and TX. */
  USART_Rx_Enable(USART_data.usart);
  USART_Tx_Enable(USART_data.usart);

  /* Enable PMIC interrupt level low. */
  PMIC.CTRL |= PMIC_LOLVLEX_bm;

  /* Enable global interrupts. */
  sei();

  i = 0;


  while(1)
  {

  i = 0;
    while (i < NUM_BYTES) {
    bool byteToBuffer;
    byteToBuffer = USART_TXBuffer_PutByte(&USART_data, 
sendArray_Air[i]);
    if(byteToBuffer){
      i++;
    }
  }

    i = 0;
    while (i < NUM_BYTES) {
    bool byteToBuffer;
    byteToBuffer = USART_TXBuffer_PutByte(&USART_data, sendArray2[i]);
    if(byteToBuffer){
      i++;
    }


  }
  }// while 1 end


  i = 0;
  while (i < NUM_BYTES) {
    if (USART_RXBufferData_Available(&USART_data)) {
      receiveArray[i] = USART_RXBuffer_GetByte(&USART_data);
      i++;
    }
  }

  /* Test to see if sent data equals received data. */
  /* Assume success first.*/
  success = true;
  for(i = 0; i < NUM_BYTES; i++) {
    /* Check that each element is received correctly. */
    if (receiveArray[i] != sendArray[i]) {
      success = false;
    }
  }

  // If success the program ends up inside the if statement.
  if(success){
    while(true);
  }else{
      while(true);
    }


      while(1)
    {




  }
}


/*! \brief Receive complete interrupt service routine.
 *
 *  Receive complete interrupt service routine.
 *  Calls the common receive complete handler with pointer to the 
correct USART
 *  as argument.
 */
ISR(USARTC0_RXC_vect)
{
  USART_RXComplete(&USART_data);
}


/*! \brief Data register empty  interrupt service routine.
 *
 *  Data register empty  interrupt service routine.
 *  Calls the common data register empty complete handler with pointer 
to the
 *  correct USART as argument.
 */
ISR(USARTC0_DRE_vect)
{
  USART_DataRegEmpty(&USART_data);
}






Egal wieviele möglichkeiten ausprobiere der iPod reagiert nicht!!!

Villeicht hat jemand Erfahrung darin.

Bitte um Antwort

Danke
Dominik

von Simon K. (simon) Benutzerseite


Lesenswert?

Bitte hänge so viel Code doch möglichst komplett als (eine oder mehrere) 
.c Datei(en) an.
Und eine Schaltungsbeschreibung als Bild ist auch hilfreich (Was ist ein 
iPod Dockout?).

von Dominik N. (Firma: HTL-Salzburg) (dominik_hanniball)


Angehängte Dateien:

Lesenswert?

Sorry, hier die Source-Files:
gewählt wurde:
der interne Osz. - 2Mhz
19200 Baud.


Bei der Schaltung ist zu beachten, dass ich keinen LF353 OpAmp verwende 
sowie kein 1k und 2k Widerstände da der UART vom XMEGA mit 3,3V 
funktioniert.

Ziel ist es den iPod mittels Apple Accessory Protocol zu steuern, jedoch 
find ich den Fehler nicht heraus warum dieser nicht anspricht!!

iPod Pinout =
http://www.sparkfun.com/commerce/product_info.php?products_id=8295

von hans (Gast)


Lesenswert?

Deine RS232-Routinen hast du ja wohl überprüft (mal den PC
mit Terminalprogramm angeschlossen) ;)

Dein Main schickt in einer Endlosschleife (while(1)) nur
den Befehl zum Modewechsel und die Meldung "Taste losgelassen"
aus dem Remot-Befehlssatz.
Was soll da wohl geschehen?

Was soll der AVR, was der IPod tun?

Und mit 2 MHz sind 19200 Baud ungenau (wohl um 7% daneben)
und mit dem internen Oszillator erst recht.

(IPod ist da unempfindlicher als die meisten PCs)

hans

von Dominik N. (Firma: HTL-Salzburg) (dominik_hanniball)


Lesenswert?

Die RS232-Routine wirde am Oszi. überprüft, und war perfekt.

Also durch das Apple Accessory Protocol würde ich gerne den iPod mittels 
XMEGA über UART steuert.

Um also z.B. in den "Air-Modus" zu gelanden muss ich:
0xFF 0x55 0x03 0x00 0x01 0x04 0xF8
senden.
doch wie oft hintereinander?, Delay? - das ist noch ungeklärt

Eine Weitere möglichkeit, beim iPod "nächster Track" im Mode2
Wie wäre hier der Code um beim iPod jede z.B. 10 sekunten, nächster 
Track?


"Und mit 2 MHz sind 19200 Baud ungenau (wohl um 7% daneben)
und mit dem internen Oszillator erst recht."
Stimmt, jedoch zu kurzen Testzwecken kann es reichen, nur um zu sehen ob 
der iPod anspricht.

Mit der großen bitte um Antwort

Dominik

von Peter D. (peda)


Lesenswert?

Dominik Nell schrieb:
> "Und mit 2 MHz sind 19200 Baud ungenau (wohl um 7% daneben)
> und mit dem internen Oszillator erst recht."
> Stimmt, jedoch zu kurzen Testzwecken kann es reichen

???

Wenns nicht geht, dann gehts nicht.
Egal, ob kurz oder lang.


Peter

von hans (Gast)


Lesenswert?

@peter
> Wenns nicht geht, dann gehts nicht.

Im Prinzip ja, es bestädigt auch, daß er seine RS232 nicht
getestet hat (Oszi-Bildchen reichen nicht).
Aber wie geschrieben ist der IPod gutmütig.
Das 0xFF 0x55 ist für die automatische Baudratenerkennung.
Und wenn er dann den kpl. Befehl mit 17000 Baud überträgt
geht es auch noch.

hans

von Dominik N. (Firma: HTL-Salzburg) (dominik_hanniball)


Lesenswert?

OK, danke dann werde ich gleich mal auf 32MHz umsteigen!!!
Dann sollte der RS232 stimmen ( Ist ja auch ein Sample-Beispiel von 
Atmel, da kann nicht sooo viel falsch sein )

Dennoch eine Frage wie würden hier in meinem Programm die Routine für 
das umschalten in den "Air-modus", sowie eine Routine für "nächter 
Track" lauten??

mit bestem Dank

Dominik

von hans (Gast)


Lesenswert?

Näschster Track/Skip ist ein einfacher Remote-Befehl (Mode 2).
Dafür braucht man kein AIR (Mode 4).

Also Befehl "Skip>>" senden "FF 55 03 02 00 08 F3" ,
(ohne Endzeichen) entspricht einem Tastendruck auf >>.
Dann Befehl "Released" senden "FF 55 03 02 00 00 FB" ,
(auch ohne Endzeichen) entspricht dem Loslassen der Tasten.
Jetzt wird der "Tastendruck" ausgewertet.

hans

von Dominik N. (Firma: HTL-Salzburg) (dominik_hanniball)


Lesenswert?

ok ich werden mal 32MHz einstellen und testen

laut diversen Internet seiten muss man den Befehl 66 mal senden und 
danach ein Button release, oder wieder andere These, den Befehl senden 
danach Button release und das gesamte 66 mal??

oder reicht es wenn ich den Befehl nur einmal sende und danach ein 
Button release?

Weiters soll ich ein delay_us(?) zwischen dem Befehl und Button release 
einfügen?

mfg

Dominik

von Simon K. (simon) Benutzerseite


Lesenswert?

Das Problem ist, dass es keine offizielle Beschreibung zu dem Protokoll 
gibt. Von daher hilft nur probieren.

von Armin S. (nimra)


Lesenswert?

ist dann ohne 2k Resistor nicht der RX-Pin des I-Pod auf Masse gelegt?

NIMRA

von Dominik N. (Firma: HTL-Salzburg) (dominik_hanniball)


Lesenswert?

Nein die Leitung gibts bei mir nicht ich hab keinen Spannungsteiler, 
einfach Leitung von XMEGA zu iPod

von Christian R. (supachris)


Angehängte Dateien:

Lesenswert?

Dominik Nell schrieb:

> oder reicht es wenn ich den Befehl nur einmal sende und danach ein
> Button release?

Das reicht aus.

> Weiters soll ich ein delay_us(?) zwischen dem Befehl und Button release
> einfügen?

Muss man nicht.

Ich hab das auch mal auf dem MSP430 implementiert, ging problemlos. 
Quelltext ist mal angehängt. Das ganze war ein RC5 zu IPod Umsetzer, 
daher mit Adresse und Kommando.

von hans (Gast)


Lesenswert?

Der Code von Christian ist gut.

Die andegebene Referenz :
1
//Referece: http://www.adriangame.co.uk/ipod-acc-pro.html

ist neben ipodlinux.org und der tuwien eine der wenigen zugänglichen 
Quellen für das Protokoll die was taugt.

Zum Teil werden jedoch aus dem Remotesatz (Mode2) Befehle mit
mehr als 2 Byte verwendet. Alte IPods könnten da Probleme
machen, da diese erst später dazukammen.

hans

von Christian R. (supachris)


Lesenswert?

Mit seinem 4G sollte es da keine Probleme geben. Mit dem iPod Touch 3G 
(war´s glaub ich) klappts super mit 19200 baud. Bei Interesse kann ich 
auch das ganze Projekt zur Verfügung stellen. Das setzt die RC5-Befehle 
der VDO Dayton Lenkrad-Fernbedienung RCS4000 auf den Eipott um. Benutzt 
wird ein MSP430F1121A mit der Timer-UART und RC5 Dekodierung im Timer A.

von Dominik N. (Firma: HTL-Salzburg) (dominik_hanniball)


Lesenswert?

Hallo!!!

OK ich habe die Eistellungen gewählt(XMEGA128A3): 32 MHz, 19200 Baud, 
die Verdrahtung ist auch richtig, jedoch spricht der iPod noch immer 
nicht an!!!

1. Methode:
Als erstes habe ich versuht den iPod in den Modus 2 zu schalten:
uint8_t sendArray3[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x00, 0x01, 0x02, 
0xFA};
danach einmal mit und ohne Button Release
und nachher dann ein Befehl wie dieser: nächster Titel
uint8_t sendArray[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x08, 
0xF3};
mit button Release

2. Methode:
in den Air Modus umschalten:
uint8_t sendArray_Air[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x00, 0x01, 0x04, 
0xF8};
mit und ohne Button release, jedoch reagiert der iPod auf nichts

3. Methode
ich hab von meinem iPod die TxD Leitung mit meinem RxD Pin vom XMEGA 
verbunden und nochmals gesendet!!!
wenn ich jetzt z.B.
nächster Track sowie ein Button release sende
empfange ich:
nächster Track

Bsp:
Senden:
uint8_t sendArray[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x08, 
0xF3}
uint8_t sendArray2[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x00, 
0xFB};
empfangen wird:
uint8_t sendArray[NUM_BYTES] = {0xFF, 0x55, 0x03, 0x02, 0x00, 0x08, 
0xF3}

könnte mir bitte wer das erklären??
hatt villeicht noch jemand einen XMEGA und hatte wer damit schon mal 
Erfolg?

bitte um Antwort
Dominik

von Dominik N. (Firma: HTL-Salzburg) (dominik_hanniball)


Lesenswert?

Möglicherweise kann es sein, dass er nicht mitbekommt das ich ihm was 
sende, aber wie sag ich ihm, jetzt Seriell?
Mit dem 500k Widerstand reichts wohl nicht, gibts ein paar tricks wie 
ich ihm das sagen kann??

Dominik

von Christian R. (supachris)


Angehängte Dateien:

Lesenswert?

500k? Ich hab da einen 68k Widerstand dran getan, dann kommt der Ton aus 
dem Dock Connector und er reagier auf die seriellen Befehle. Im Anhang 
mal das ganze Projekt.

von hans (Gast)


Lesenswert?

Die Befehle habe ich so wie Christian verwendet.
Als ID-Widerstand jedoch 1 MOhm. Da ich die Versorgungs/
Ladespannung an USB schalte hat das den Vorteil, daß der
IPod bei Spannung aus sich auch automatisch ausschaltet.

Das NF-Signal ist wie Christian sagt ebenfalls am
Dockingstecker (PIN 27+28 GND 29).
Der Pegel ist fix, d.h. Lautstärkeregelung muß man
selber machen.
Es läuft mit div. IPods und dem IPhone.

Hans

von dominik_hanniball (Gast)


Lesenswert?

Hab jetzt mal das ganze mit 500 Ohm, sowie 68k und 1 MOhm getestet, bei 
500 Ohm und 68k macht der iPod so ein tidlüü, aber er reagiert noch 
immer nicht auf meine Befehle.

Kann es sein dass ich in meinem Programm, einen Fehler habe?
hab auch leider nur einen XMEGA zur verfügung!!
Sonst weiß ich schon langsam nicht mehr weiter!!

Es gibt doch schon einige die das geschafft haben, wo gab es bei denen 
Fehler und worauf muss man besoners ACHTEN!!

Dominik

von dominik_hanniball (Gast)


Lesenswert?

OK, endlich funktioniert die Ansteuerung:

1. Versorge nicht einen XMEGA mit 4,2 V auch wenn er es aushält, denn 
dadurch wird das Signal total verfälscht
2. Auch wenn das richtige gesenden wird und auch EMPFANGEN, traue dem 
frieden nicht und überprüf deine Werte die du sendest mit einem Programm
3. verwendeter Widerstand 600k, funktioniert aber auch mit 1k!!

danke für eure hilfe
Dominik

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.