The iPod controller that I submitted for the mbed challenge

Dependencies:   mbed Motordriver PID

Committer:
networker
Date:
Wed May 04 15:41:13 2011 +0000
Revision:
0:371773dd3dd1
first publication

Who changed what in which revision?

UserRevisionLine numberNew contents of line
networker 0:371773dd3dd1 1 #include "mbed.h"
networker 0:371773dd3dd1 2 #include "fader.h"
networker 0:371773dd3dd1 3 #include "MCP23017.h"
networker 0:371773dd3dd1 4 #include "TextLCD23017.h"
networker 0:371773dd3dd1 5 #include "keybrd.h"
networker 0:371773dd3dd1 6 #include "ipod.h"
networker 0:371773dd3dd1 7 #include "ipodcontrol.h"
networker 0:371773dd3dd1 8
networker 0:371773dd3dd1 9 fader trackbar(p21,p22,p23,p20);
networker 0:371773dd3dd1 10 I2C iic(p28, p27);
networker 0:371773dd3dd1 11 MCP23017 ui(iic, 0x40);
networker 0:371773dd3dd1 12 TextLCD23017 lcd(ui);
networker 0:371773dd3dd1 13 keybrd kb(ui, p12);//second argument is the interrupt pin, although only used by keyboard it logically belongs to the MCP23017
networker 0:371773dd3dd1 14 ipod pod(p9, p10);//serial pins for the ipod
networker 0:371773dd3dd1 15 ipodControl cntrl(pod);
networker 0:371773dd3dd1 16
networker 0:371773dd3dd1 17 DigitalOut led(LED1);//for debug only
networker 0:371773dd3dd1 18
networker 0:371773dd3dd1 19 const float beyondEnd = 2.0; //any number > 1.0
networker 0:371773dd3dd1 20 float inmark=0, outmark=beyondEnd;
networker 0:371773dd3dd1 21
networker 0:371773dd3dd1 22 void show(const char* s) { //write to LCD bottom line
networker 0:371773dd3dd1 23 lcd.locate(0, 1);
networker 0:371773dd3dd1 24 lcd.printf("%-16s", s);
networker 0:371773dd3dd1 25 }
networker 0:371773dd3dd1 26
networker 0:371773dd3dd1 27 void showtop(const char* s) { //write to LCD top line
networker 0:371773dd3dd1 28 lcd.locate(0, 0);
networker 0:371773dd3dd1 29 lcd.printf("%-16s", s);
networker 0:371773dd3dd1 30 }
networker 0:371773dd3dd1 31
networker 0:371773dd3dd1 32 void show(unsigned, const char* s) {
networker 0:371773dd3dd1 33 lcd.locate(0, 1);
networker 0:371773dd3dd1 34 if (cntrl.getItems()>0)
networker 0:371773dd3dd1 35 lcd.printf("%-16s", s);
networker 0:371773dd3dd1 36 else
networker 0:371773dd3dd1 37 lcd.printf(" <Empty> ");//placeholder
networker 0:371773dd3dd1 38 }
networker 0:371773dd3dd1 39
networker 0:371773dd3dd1 40 void time(unsigned t) { //OnTime, iPod polling command
networker 0:371773dd3dd1 41 float pos = t;
networker 0:371773dd3dd1 42 unsigned length = cntrl.getTrackLength();
networker 0:371773dd3dd1 43 if (length == 0)
networker 0:371773dd3dd1 44 return;//valid length not available (yet)
networker 0:371773dd3dd1 45 pos /= length;
networker 0:371773dd3dd1 46 if (pos >= outmark) {
networker 0:371773dd3dd1 47 cntrl.MoveTo(inmark * cntrl.getTrackLength());
networker 0:371773dd3dd1 48 trackbar.set(inmark);
networker 0:371773dd3dd1 49 } else
networker 0:371773dd3dd1 50 trackbar.set(pos);//when fader is 'holding' or 'tracking moveto new position
networker 0:371773dd3dd1 51 }
networker 0:371773dd3dd1 52
networker 0:371773dd3dd1 53 void changeTrack(unsigned t) { //OnTrackChange, iPod polling command
networker 0:371773dd3dd1 54 printf("Track %u\n", t);
networker 0:371773dd3dd1 55 //the track changed so we need new artist/song/tracklength
networker 0:371773dd3dd1 56 //must not call guarded_SendAirCmd here because the rx_buffer will not be released before reply arrives
networker 0:371773dd3dd1 57 //calling a sequence of normal SendAirCmds is also dangerous because they may not be properly queued
networker 0:371773dd3dd1 58 cntrl.Update(); //sends the first SendAirCmd and starts the 'updater' state-machine to send the rest
networker 0:371773dd3dd1 59 }
networker 0:371773dd3dd1 60
networker 0:371773dd3dd1 61 void OnMove(float newpos) { //fader move command, called after manual movement of wiper
networker 0:371773dd3dd1 62 cntrl.MoveTo(newpos * cntrl.getTrackLength()); //new wiper position in ms
networker 0:371773dd3dd1 63 }
networker 0:371773dd3dd1 64
networker 0:371773dd3dd1 65 void errHandler(unsigned e, unsigned cmd) { //ipodcontrol::OnError
networker 0:371773dd3dd1 66 if (e==1 && cmd==get_ipod_name)
networker 0:371773dd3dd1 67 lcd.printf("iPod connected??");
networker 0:371773dd3dd1 68 }
networker 0:371773dd3dd1 69
networker 0:371773dd3dd1 70 void handleKey(char c) { //handles the keys of the user interface
networker 0:371773dd3dd1 71 switch (c) {
networker 0:371773dd3dd1 72 case 1://OK
networker 0:371773dd3dd1 73 if (cntrl.getMode() == nav)
networker 0:371773dd3dd1 74 cntrl.OK();
networker 0:371773dd3dd1 75 else { //mode==play
networker 0:371773dd3dd1 76 outmark = beyondEnd;//stop repeating marked section
networker 0:371773dd3dd1 77 inmark = 0;
networker 0:371773dd3dd1 78 }
networker 0:371773dd3dd1 79 break;
networker 0:371773dd3dd1 80 case 2://>>/out
networker 0:371773dd3dd1 81 if (cntrl.getMode()==nav)
networker 0:371773dd3dd1 82 cntrl.Fwd();
networker 0:371773dd3dd1 83 else //'out' command
networker 0:371773dd3dd1 84 if (cntrl.getPos() > inmark)
networker 0:371773dd3dd1 85 outmark = cntrl.getPos();
networker 0:371773dd3dd1 86 break;
networker 0:371773dd3dd1 87 case 3://<</in
networker 0:371773dd3dd1 88 if (cntrl.getMode()==nav)
networker 0:371773dd3dd1 89 cntrl.Rev();
networker 0:371773dd3dd1 90 else //'in' command
networker 0:371773dd3dd1 91 if (cntrl.getPos() < outmark)
networker 0:371773dd3dd1 92 inmark = cntrl.getPos();
networker 0:371773dd3dd1 93 break;
networker 0:371773dd3dd1 94 case 4://>||
networker 0:371773dd3dd1 95 cntrl.PlayPause();
networker 0:371773dd3dd1 96 break;
networker 0:371773dd3dd1 97 case 5://menu
networker 0:371773dd3dd1 98 cntrl.Menu();
networker 0:371773dd3dd1 99 if (cntrl.getType() == top)
networker 0:371773dd3dd1 100 show("");
networker 0:371773dd3dd1 101 break;
networker 0:371773dd3dd1 102 case 6://rec
networker 0:371773dd3dd1 103 case 7://replay
networker 0:371773dd3dd1 104 default:
networker 0:371773dd3dd1 105 break;
networker 0:371773dd3dd1 106 }
networker 0:371773dd3dd1 107 }
networker 0:371773dd3dd1 108
networker 0:371773dd3dd1 109 /* On a real iPod, the wheel has multiple functions, depending on the mode:
networker 0:371773dd3dd1 110 navigation: moves up and down the current list
networker 0:371773dd3dd1 111 play: changes volume (not implemented here and afaik not possible)
networker 0:371773dd3dd1 112 but it has submodes
networker 0:371773dd3dd1 113 fast: moves quickly through a song (here implemented by fader movement)
networker 0:371773dd3dd1 114 stars: rates the song (not implemented)
networker 0:371773dd3dd1 115 */
networker 0:371773dd3dd1 116 int main() {
networker 0:371773dd3dd1 117 int count = 0;
networker 0:371773dd3dd1 118 iic.frequency(400000);//does not work, stays at 100kHz
networker 0:371773dd3dd1 119 cntrl.OnGetNames = show;
networker 0:371773dd3dd1 120 cntrl.OnTitle = show;
networker 0:371773dd3dd1 121 cntrl.OnArtist = showtop;
networker 0:371773dd3dd1 122 cntrl.OnAlbum = show;
networker 0:371773dd3dd1 123 cntrl.OnTime = time;
networker 0:371773dd3dd1 124 cntrl.OnTrackChange = changeTrack;
networker 0:371773dd3dd1 125 cntrl.OnError = errHandler;
networker 0:371773dd3dd1 126 trackbar.setOnMove(OnMove);
networker 0:371773dd3dd1 127 if (!cntrl.readName()) //calls errHandler if no reply
networker 0:371773dd3dd1 128 ;
networker 0:371773dd3dd1 129 wait(1.0);
networker 0:371773dd3dd1 130 cntrl.StartPolling();
networker 0:371773dd3dd1 131 lcd.printf("%-16s", cntrl.getPathStr());//display "Playlist" on topline, bottomline empty
networker 0:371773dd3dd1 132 printf("entering main loop\n");
networker 0:371773dd3dd1 133 for (;;) {
networker 0:371773dd3dd1 134 count = (count+1)%0x20000;
networker 0:371773dd3dd1 135 if (count==0) led = !led;//just to see if the main loop keeps running
networker 0:371773dd3dd1 136
networker 0:371773dd3dd1 137 lcd.locate(0, 0);//col, row
networker 0:371773dd3dd1 138
networker 0:371773dd3dd1 139 switch (kb.getevent(true)) {
networker 0:371773dd3dd1 140 case keybrd::keydown:
networker 0:371773dd3dd1 141 printf("Key %01d\n", kb.getc());
networker 0:371773dd3dd1 142 handleKey(kb.getc());
networker 0:371773dd3dd1 143 goto update;
networker 0:371773dd3dd1 144 case keybrd::keyup:
networker 0:371773dd3dd1 145 break;
networker 0:371773dd3dd1 146 case keybrd::posup://rotary encoder turns right
networker 0:371773dd3dd1 147 printf("Pos %d\n", kb.getpos());
networker 0:371773dd3dd1 148 cntrl.Right();
networker 0:371773dd3dd1 149 outmark = beyondEnd; //stop repeating
networker 0:371773dd3dd1 150 inmark = 0;
networker 0:371773dd3dd1 151 goto update;
networker 0:371773dd3dd1 152 case keybrd::posdown:
networker 0:371773dd3dd1 153 printf("Pos %d\n", kb.getpos());
networker 0:371773dd3dd1 154 cntrl.Left();
networker 0:371773dd3dd1 155 outmark = beyondEnd; //stop repeating
networker 0:371773dd3dd1 156 inmark = 0;
networker 0:371773dd3dd1 157 update:
networker 0:371773dd3dd1 158 if (cntrl.getType() == top)
networker 0:371773dd3dd1 159 lcd.printf("%-16s", cntrl.getPathStr());//toplevel name from array
networker 0:371773dd3dd1 160 else
networker 0:371773dd3dd1 161 lcd.printf("%-16s", cntrl.getTypeStr());//item name from iPod
networker 0:371773dd3dd1 162 break;
networker 0:371773dd3dd1 163 case keybrd::none:
networker 0:371773dd3dd1 164 break;
networker 0:371773dd3dd1 165 default:
networker 0:371773dd3dd1 166 printf("Unknown keyboard event\n");
networker 0:371773dd3dd1 167 }
networker 0:371773dd3dd1 168 cntrl.poll();//handle the ipodcontrol events in the event loop
networker 0:371773dd3dd1 169 }
networker 0:371773dd3dd1 170 }