The iPod controller that I submitted for the mbed challenge
Dependencies: mbed Motordriver PID
main.cpp
- Committer:
- networker
- Date:
- 2011-05-04
- Revision:
- 0:371773dd3dd1
File content as of revision 0:371773dd3dd1:
#include "mbed.h" #include "fader.h" #include "MCP23017.h" #include "TextLCD23017.h" #include "keybrd.h" #include "ipod.h" #include "ipodcontrol.h" fader trackbar(p21,p22,p23,p20); I2C iic(p28, p27); MCP23017 ui(iic, 0x40); TextLCD23017 lcd(ui); keybrd kb(ui, p12);//second argument is the interrupt pin, although only used by keyboard it logically belongs to the MCP23017 ipod pod(p9, p10);//serial pins for the ipod ipodControl cntrl(pod); DigitalOut led(LED1);//for debug only const float beyondEnd = 2.0; //any number > 1.0 float inmark=0, outmark=beyondEnd; void show(const char* s) { //write to LCD bottom line lcd.locate(0, 1); lcd.printf("%-16s", s); } void showtop(const char* s) { //write to LCD top line lcd.locate(0, 0); lcd.printf("%-16s", s); } void show(unsigned, const char* s) { lcd.locate(0, 1); if (cntrl.getItems()>0) lcd.printf("%-16s", s); else lcd.printf(" <Empty> ");//placeholder } void time(unsigned t) { //OnTime, iPod polling command float pos = t; unsigned length = cntrl.getTrackLength(); if (length == 0) return;//valid length not available (yet) pos /= length; if (pos >= outmark) { cntrl.MoveTo(inmark * cntrl.getTrackLength()); trackbar.set(inmark); } else trackbar.set(pos);//when fader is 'holding' or 'tracking moveto new position } void changeTrack(unsigned t) { //OnTrackChange, iPod polling command printf("Track %u\n", t); //the track changed so we need new artist/song/tracklength //must not call guarded_SendAirCmd here because the rx_buffer will not be released before reply arrives //calling a sequence of normal SendAirCmds is also dangerous because they may not be properly queued cntrl.Update(); //sends the first SendAirCmd and starts the 'updater' state-machine to send the rest } void OnMove(float newpos) { //fader move command, called after manual movement of wiper cntrl.MoveTo(newpos * cntrl.getTrackLength()); //new wiper position in ms } void errHandler(unsigned e, unsigned cmd) { //ipodcontrol::OnError if (e==1 && cmd==get_ipod_name) lcd.printf("iPod connected??"); } void handleKey(char c) { //handles the keys of the user interface switch (c) { case 1://OK if (cntrl.getMode() == nav) cntrl.OK(); else { //mode==play outmark = beyondEnd;//stop repeating marked section inmark = 0; } break; case 2://>>/out if (cntrl.getMode()==nav) cntrl.Fwd(); else //'out' command if (cntrl.getPos() > inmark) outmark = cntrl.getPos(); break; case 3://<</in if (cntrl.getMode()==nav) cntrl.Rev(); else //'in' command if (cntrl.getPos() < outmark) inmark = cntrl.getPos(); break; case 4://>|| cntrl.PlayPause(); break; case 5://menu cntrl.Menu(); if (cntrl.getType() == top) show(""); break; case 6://rec case 7://replay default: break; } } /* On a real iPod, the wheel has multiple functions, depending on the mode: navigation: moves up and down the current list play: changes volume (not implemented here and afaik not possible) but it has submodes fast: moves quickly through a song (here implemented by fader movement) stars: rates the song (not implemented) */ int main() { int count = 0; iic.frequency(400000);//does not work, stays at 100kHz cntrl.OnGetNames = show; cntrl.OnTitle = show; cntrl.OnArtist = showtop; cntrl.OnAlbum = show; cntrl.OnTime = time; cntrl.OnTrackChange = changeTrack; cntrl.OnError = errHandler; trackbar.setOnMove(OnMove); if (!cntrl.readName()) //calls errHandler if no reply ; wait(1.0); cntrl.StartPolling(); lcd.printf("%-16s", cntrl.getPathStr());//display "Playlist" on topline, bottomline empty printf("entering main loop\n"); for (;;) { count = (count+1)%0x20000; if (count==0) led = !led;//just to see if the main loop keeps running lcd.locate(0, 0);//col, row switch (kb.getevent(true)) { case keybrd::keydown: printf("Key %01d\n", kb.getc()); handleKey(kb.getc()); goto update; case keybrd::keyup: break; case keybrd::posup://rotary encoder turns right printf("Pos %d\n", kb.getpos()); cntrl.Right(); outmark = beyondEnd; //stop repeating inmark = 0; goto update; case keybrd::posdown: printf("Pos %d\n", kb.getpos()); cntrl.Left(); outmark = beyondEnd; //stop repeating inmark = 0; update: if (cntrl.getType() == top) lcd.printf("%-16s", cntrl.getPathStr());//toplevel name from array else lcd.printf("%-16s", cntrl.getTypeStr());//item name from iPod break; case keybrd::none: break; default: printf("Unknown keyboard event\n"); } cntrl.poll();//handle the ipodcontrol events in the event loop } }