info:controlling_ipod_with_atmel32

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
info:controlling_ipod_with_atmel32 [2008/11/26 18:38] tomgeeinfo:controlling_ipod_with_atmel32 [2008/11/26 19:15] (current) tomgee
Line 1: Line 1:
-Controlling an iPod with an Atmega32+===== Controlling an iPod with an Atmega32 =====
  
-Introduction+ 
 +**Introduction**\\
  
 Have you ever imagined, "What does that cable I plug into my iPod every day actually do, and how do I take advantage of it for myself?" We did too, and that's what we aimed to do with our 476 project. The iPod is, of course, the popular digital music player developed by Apple. The heart of the project is to use the Mega32 microcontroller to transmit and receive commands from the iPod using the built-in Dock Connector, as opposed to cracking the iPod open and wiring it up. The Dock Connector is the little port at the bottom of the iPod that you would normally connect a white USB or FireWire sync cable into. Commands that are currently implemented include play, stop, fast forward and other basic commands that allow the user to enjoy music from the iPod, as well as the ability to display the current track's Title, Artist, and Album on an external LCD display. Have you ever imagined, "What does that cable I plug into my iPod every day actually do, and how do I take advantage of it for myself?" We did too, and that's what we aimed to do with our 476 project. The iPod is, of course, the popular digital music player developed by Apple. The heart of the project is to use the Mega32 microcontroller to transmit and receive commands from the iPod using the built-in Dock Connector, as opposed to cracking the iPod open and wiring it up. The Dock Connector is the little port at the bottom of the iPod that you would normally connect a white USB or FireWire sync cable into. Commands that are currently implemented include play, stop, fast forward and other basic commands that allow the user to enjoy music from the iPod, as well as the ability to display the current track's Title, Artist, and Album on an external LCD display.
Line 85: Line 86:
 The button_release state should occur when the user has finished sending a mode 0x02 command. The t_buffer is set to the button release command, which is of mode 0x02, and is transmitted to the iPod. The state then proceeds to Send.  The button_release state should occur when the user has finished sending a mode 0x02 command. The t_buffer is set to the button release command, which is of mode 0x02, and is transmitted to the iPod. The state then proceeds to Send. 
  
-{{info:states.jpg?700|}}+{{info:states.jpg?900|}} 
 + 
 +Helper functions we used: 
 + 
 +initialize() sets up the LCD display and determines the baud rate that we use. Since the iPod transmits at 19200 bits per second, we set UBRRL to 51. Additionally, an interrupt is set to trigger every millisecond, which provides the clock for the state machine. 
 + 
 +buttons() is called every millisecond, and checks to see if a button has been pressed or not. If the previous button (lastpress) is 0, and there is a button press (press != 0), then debouncecounter begins to increment. When debouncecounter reaches 40 (40 ms have passed), the validcommand flag is set high, and the debouncecounter is reset to -460. Thus, the debouncecounter also functions as a hold timer. After 500ms have passed, the validcommand flag is set high again, and the button press is sent again. 
 + 
 +As it turns out, when an iPod receives a mode 0x02 command, it continues performing that operation until a button release command is sent. However, the iPod does not send any acknowledgment regarding mode 2 commands, unlike mode 4 commands. Thus, we decided to err on caution and simplicity, and send the command multiple times if the button is held down noticeably. It would be an interesting question to ask if the iPod functions similarly for internal button presses (e.g. on the click wheel). Clearly, volume up/down is handled differently on the iPod due to the wheel motion. 
 + 
 +Finally, we have a helper function called lcd_scroll(). This helper function is called every 300 ms, and is used to scroll the title, artist, and album fields on our little 16x2 LCD screen. These fields need to be scrolled if the fields are longer than 16 bits, which would not display nicely on our LCD screen. It works by copying over the relevant part of r_buffer, namely the part that includes the string fields, to another array, lcdbuffer. That array is then copied over into a "scratch" LCD buffer, displaybuffer, which includes exactly what 16 characters are supposed to be displayed on the LCD. Thus, every 300 ms, we move the LCD display buffer over by 1 character and update the LCD screen. Additionally, we also loop around to the beginning when we hit the end of our string field, so the scroll itself loops too. 
 + 
 +puts_int() starts transmitting t_buffer through the UART. It resets all through t_index and t_ready, then calls put_char() to transmit the first character of t_buffer. Afterwards, the interrupt transmits each character at a time. 
 +Tricky Stuff 
 + 
 +To send and receive, we initially used Bruce Land's serial transmission code and modified the stop conditions to checksums instead of null terminators. Additionally, the transmit interrupt would not stop at the appropriate place -- we rewrote the code so it was logically the same, but now would stop at the appropriate spot. 
 + 
 +Within the receive interrupt, we realized that a parameter within an iPod response could erroneously match the checksum. For example, when sending back the album title "Good News for People Who Like Bad News," one of our implementations stopped at the space character (' ') because its ASCII code, 0x20, matches the incomplete computed checksum. The old implementation detected this match and considered it to be the end of the transmission, while the actual checksum was quite a few bytes later. After finding several checksum collisions, we changed the end condition of the receive interrupt to look at the length of r_buffer to prevent the premature setting of r_ready flags. 
 + 
 +How the Send and Receive states intertwined was easily the trickiest part of the code. The sources we used did not explicitly tell us every response an iPod would give us -- for example, mode switching was not well documented and we were not aware of its necessity. Originally, we were planning to ignore responses that we did not care about. After spending some time in lab, we decided that this was not the correct approach, and spent time determining all the responses. 
 + 
 +When the iPod leaves mode 4 and enters mode 2, the iPod can ignore commands! When the user presses the physical play button on the iPod, there are no issues. In contrast, the iPod ignores the serial Play command up to three times! We believe there is a command in the sequence missing that we are not aware of and/or is not documented. We cannot see what a "proper" commercial implementation does as we do not own an accessory that actually makes use of Mode 4 commands and, as a result, cannot intercept and spy on what other implementations do. Thus, to start playing a song after entering Mode 4, the user needs to hit the play button twice on our implementation. 
 + 
 +Finally, John Sicilia showed us a clever way of checking the receive buffer using the LEDs. Light up the LEDs according to the character in the buffer, delay for several seconds, turn the LEDs off for some time, and then move on to the next character in the buffer. Prior to this method, we had been looking at the waveform on the oscilloscope, which works fine but is very time consuming. When there were issues like the checksum error, we would compare the oscilloscope waveform to the output from the LEDs. A sample of this technique is shown here; be sure to include delay.h: 
 + 
 + 
 + 
 +    for(k=0; k<11; k++) 
 +    { 
 +          PORTB = t_buffer[k]; 
 +          delay_ms(5000); 
 +          PORTB = 0xFF; 
 +          delay_ms(500); 
 +    } 
 +    while(1); 
 + 
 +**Hardware Design**\\ 
 + 
 +The microcontroller outputs a high and low voltage of 5V and 0V respectively. However, the iPod operates at a maximum of 3.3V for high. Thus, for the serial transmission line, we created a voltage divider, so that when the line is pulled to 5V, the iPod sees 3.3V. The high level schematic is below. 
 + 
 +{{info:mega32_schem.jpg|}} 
 + 
 +Additionally, the iPod only outputs a maximum of 3V when transmitting serially. We used an LF353 op-amp to increase the output voltage to 5V. The schematic for a non-inverting amplifier is shown below, where R2 is 1 kilo-Ohm and R1 is 2 kilo-Ohms. The Gain is 1+(R2/R1), where our values give a gain of 1.5. 
 + 
 +{{info:opamp.jpg|}} 
 + 
 +Code for this project is in the file ipod_avr32.c  
 + 
 +**Conclusions**\\ 
 + 
 +The results of this project met our expectations. We wanted to both control and receive from an iPod with a microcontroller, and this was accomplished. Our design used the serial communication protocol 8-N-1, and for this we used Bruce Land's serial communication code as a jump-off point for our serial communication code. As mentioned before, the specifics of the iPod communication protocol came from researching the reverse engineering efforts of other hobbyists, and we communicated with a few of them if there we had specific questions about the protocol. The documentation of the protocol was fairly good but, as always with documentation and especially unofficial documentation, could have been improved and more clear. Hopefully our writeup here will clarify certain things that are confusing. We do not expect to have any patent opportunities with this project. 
 + 
 +{{info:benchsetup.jpg?700|}} 
 + 
 +**Future Design Aspirations**\\ 
 + 
 +If we had more time available, we would have liked to implement an IR receiver with the microcontroller. Thus, a user could use an IR remote to send commands to the microcontroller, which would then be relayed to the iPod. We also could have implemented more mode 4 commands, with more pushbuttons being our main constraint. Additionally, future efforts could involve changing the 16x2 LCD for a more complicated and complex one that could allow displaying more information at once or even color images, such as album art or pictures. An audiophile may want to add something that uses the Line-Out component of the connector, as those pins are readily accessible as well. 
 +Ethics 
 + 
 +We believe that our project was consistent with the IEEE Code of Ethics. For example, we believe that our project is safe to individuals and the public at large, and we would promptly notify everyone if this ever changed. We believe that we have been honest about our project's performance and potential future efforts. We also hope that our project has made the iPod (and similar MP3 players for which control data can be obtained) an attractive option for future hobbyists and 476 students. 
 + 
 +In the interest of full disclosure, one of us was formerly employed by Apple (then known as Apple Computer). It should be noted that none of the material referenced in this project or on this page resulted either directly or indirectly from any material obtained during employment or with any use of Apple-owned resources, such as hardware or documentation. We have made careful efforts to ensure that nothing done here would compromise any previous or (hopeful) future employment agreements and that we have respected intellectual property throughout. 
 + 
 +No animals were harmed in the making of this project. Cornell students were merely deprived of sleep.
info/controlling_ipod_with_atmel32.1227742684.txt.gz · Last modified: 2008/11/26 18:38 by tomgee