Usb Device Interface, protocol, and programming homework #4 Audio Control device
Dependencies: C12832_lcd USBDevice mbed
Revision 1:948ffad3284f, committed 2013-07-31
- Comitter:
- jakowisp
- Date:
- Wed Jul 31 22:20:00 2013 +0000
- Parent:
- 0:69eb9d19fb91
- Child:
- 2:dec5e78d579b
- Commit message:
- Instructor requested publish of HW#4
;
Changed in this revision
--- a/MyDisplayClass.cpp Tue Jul 30 22:35:10 2013 +0000 +++ b/MyDisplayClass.cpp Wed Jul 31 22:20:00 2013 +0000 @@ -3,6 +3,8 @@ MyDisplayClass::MyDisplayClass(){ lcd=new C12832_LCD(); volume=new bargraph(lcd,32); + volumeDisplayEnable=false; + graphicModeEnable=false; } void MyDisplayClass::drawNoConnection(C12832_LCD *lcd) { @@ -57,18 +59,17 @@ } -void MyDisplayClass::update(int state,int features){ - if((features&0x1) == 0x1) - if((features&0x2) == 0x2) { +void MyDisplayClass::update(int state){ + if(volumeDisplayEnable) + if(graphicModeEnable) { volume->updateBargraph(); } else { lcd->locate(3,3); lcd->printf("Volume: %2d",volume->level); } - if((features&0x2) == 0x2) + if(graphicModeEnable) UpdateStatus(state); else UpdateTextStatus(state); } -
--- a/MyDisplayClass.h Tue Jul 30 22:35:10 2013 +0000 +++ b/MyDisplayClass.h Wed Jul 31 22:20:00 2013 +0000 @@ -7,12 +7,14 @@ class MyDisplayClass { public: MyDisplayClass(void); - void update(int state,int features); + void update(int state); void UpdateTextStatus(int state); void UpdateStatus(int state); void setLevel(int level); void setMaxLevel(int level); - + bool graphicModeEnable; + bool volumeDisplayEnable; + private: void drawSuspend(C12832_LCD *lcd); void drawConnection(C12832_LCD *lcd); @@ -20,8 +22,6 @@ C12832_LCD *lcd; bargraph *volume; - //(&lcd,32); - }; #endif \ No newline at end of file
--- a/USBAudioControl.cpp Tue Jul 30 22:35:10 2013 +0000 +++ b/USBAudioControl.cpp Wed Jul 31 22:20:00 2013 +0000 @@ -1,17 +1,20 @@ #include "stdint.h" #include "USBAudioControl.h" +//Override the USBDevice suspendStateChange function to provide callback hook void USBAudioControl::suspendStateChanged(unsigned int suspend){ if(callbackSuspendChange!=NULL) (*callbackSuspendChange)(suspend); } +//Provide a way to poll the configure state of USB device unsigned int USBAudioControl::getConnectState(){ if (device.state != CONFIGURED) return 0; return 1; } +//Define the report descriptor uint8_t * USBAudioControl::reportDesc() { static uint8_t reportDescriptor[] = { USAGE_PAGE(2), 0x0c,0x00, // Consumer
--- a/USBAudioControl.h Tue Jul 30 22:35:10 2013 +0000 +++ b/USBAudioControl.h Wed Jul 31 22:20:00 2013 +0000 @@ -25,7 +25,8 @@ */ USBAudioControl( uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0006, uint16_t product_release = 0x0001): USBHID(1, 1, 1, vendor_id, product_id, product_release, false) - { + { + // NO suspend callback by default. callbackSuspendChange=NULL; }; @@ -37,8 +38,25 @@ */ virtual uint8_t * reportDesc(); + /* + * USBDevice does not ptovide a callback function for connection state changes + * This functions will poll the state + * + * @returns 0/1 for the Connected state + */ unsigned int getConnectState(); + + /* + * User accessable Function pointer for callbacks + */ void (*callbackSuspendChange)(unsigned int connected); + + /* + * + * Provide override function for USBDevice function suspendStateChanged + * USBDevice version of the function does nothing, the HIDAudiControl + * provides a use callback hool. + */ virtual void suspendStateChanged(unsigned int suspend); };
--- a/USBDevice.lib Tue Jul 30 22:35:10 2013 +0000 +++ b/USBDevice.lib Wed Jul 31 22:20:00 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/jakowisp/code/USBDevice/#00cd29199e0e +http://mbed.org/users/jakowisp/code/USBDevice/#2b2a28dc6ed5
--- a/bargraph.cpp Tue Jul 30 22:35:10 2013 +0000 +++ b/bargraph.cpp Wed Jul 31 22:20:00 2013 +0000 @@ -1,36 +1,38 @@ #include "bargraph.h" bargraph::bargraph(C12832_LCD *inlcd,int maxlevelsIn,int Xin,int Yin,int widthIn,int heightIn){ - lcd=inlcd; - level=0; - lastLevel=0; + this->lcd=inlcd; + this->level=0; + this->lastLevel=0; if(maxlevelsIn<=32 && maxlevelsIn >=4) - maxlevels=maxlevelsIn; + this->maxlevels=maxlevelsIn; else - maxlevels=32; - if(Xin>=0 && Xin<=127-maxlevels) - x=Xin; + this->maxlevels=32; + if(Xin>=0 && Xin<=127-this->maxlevels) + this->x=Xin; else - x=0; - if(Yin>=0 && Yin<=31-maxlevels) - y=Yin; + this->x=0; + if(Yin>=0 && Yin<=31-this->maxlevels) + this->y=Yin; else - y=0; + this->y=0; if(widthIn>maxlevels && widthIn<128) - width=widthIn-1; + this->width=widthIn-1; else - width=127; + this->width=127; if(heightIn>=(maxlevels-1) && heightIn<31) - height=heightIn; + this->height=heightIn; else - height=31; - leveladjust=(height+1)/maxlevels; - levelwidth=(width+1)/maxlevels; + this->height=31; + this->leveladjust=(this->height+1)/this->maxlevels; + this->levelwidth=(this->width+1)/this->maxlevels; } void bargraph::setMaxLevel(int maxlevels){ - lcd->fillrect(x, y, x+width,y+height, 0); - leveladjust=(height+1)/maxlevels; - levelwidth=(width+1)/maxlevels; + //TODO: need to defensive check maxlevels + this->lcd->fillrect(this->x, this->y, this->x+this->width,this->y+this->height, 0); + this->lastLevel=0; + this->leveladjust=(this->height+1)/maxlevels; + this->levelwidth=(this->width+1)/maxlevels; } void bargraph::setLevel(int level){ @@ -38,15 +40,23 @@ } void bargraph::updateBargraph(){ - if(lcd!=NULL) { - if(level!=lastLevel) { - for(int i = 0 ; i<lastLevel;i++) { - lcd->fillrect(x+levelwidth*(i), y, x+levelwidth*(i+1)-1, y+i*leveladjust, 0); + if(this->lcd!=NULL) { + if(this->level!=this->lastLevel) { + for(int i = 0 ; i<this->lastLevel;i++) { + this->lcd->fillrect(this->x+this->levelwidth*(i), + this->y, + this->x+this->levelwidth*(i+1)-1, + this->y+i*this->leveladjust, + 0); } for(int i = 0 ; i<level;i++) { - lcd->fillrect(x+levelwidth*(i), y, x+levelwidth*(i+1)-1, y+i*leveladjust, 1); + this->lcd->fillrect(this->x+this->levelwidth*(i), + this->y, + this->x+this->levelwidth*(i+1)-1, + this->y+i*this->leveladjust, + 1); } - lastLevel=level; + this->lastLevel = this->level; } } };
--- a/main.cpp Tue Jul 30 22:35:10 2013 +0000 +++ b/main.cpp Wed Jul 31 22:20:00 2013 +0000 @@ -3,40 +3,57 @@ #include "USBAudioControl.h" #include "MyDisplayClass.h" -#define PAUSEKEY 16 +//Define Key words for the special disconnect/connect functionality +#define PAUSEKEY 0x10 #define NUMSECONDSTOHOLD 5 +//Joystick array for the audio control functions BusIn btnArray(p15,p12,p13,p16,p14); +//Display LED to provide feedback during the hold button sequence DigitalOut toggle(LED1); +//Group all the display items in a class. This class creates a LCD object, and bargraph object MyDisplayClass display; + +//Set up the USB HID device USBAudioControl hid(0x1234,0x0006,0x0001); +//temporary structure to hold data before filling the input report HID_REPORT tempReport; -unsigned int features=0; + +//Variable to hold USB state +// Bit 0: suspended=0,normal=1 +// Bit 1: 1=USB configured, 0 USB not configured unsigned int USBstate=0; +//Callback funciton: When an Output Report is received, set the current volume level. void SetLevel(HID_REPORT *report){ display.setLevel(report->data[0]); } +//Callback Function: When a feature report is sent, change the feature bits, and the scale void SetFeatures(HID_REPORT *report){ - features=(report->data[1]&0x30)>>4; + display.volumeDisplayEnable=((report->data[1]&0x10)>>4)==0x1; + display.graphicModeEnable=((report->data[1]&0x20)>>5)==0x1; display.setMaxLevel((report->data[1]&0x0f)<<2); } +//Function to write the USB configured bit, this is polled. void WriteConnectedBit(unsigned int connected){ USBstate = (connected << 1) | (USBstate & 0x1); } +//Callback function: When the Suspend bit is changed, update USBstate void WriteSuspendBit(unsigned int suspend){ USBstate = (suspend) | (USBstate & 0x2); } - + +//Fill a temp report with the button array state void PollInputs(HID_REPORT *tempReport) { tempReport->data[0]=btnArray; } +//Provide a check for a special button combination to connect and disconnect. void CheckForHeldPauseKey(HID_REPORT * tempreport, USBAudioControl * hid, DigitalOut * toggle){ static int holdCount=0; @@ -57,21 +74,33 @@ } } + +//Main Function int main() { + //Assign callback functions for USB events hid.callbackSetOutputReport=&SetLevel; hid.callbackSetFeatureReport=&SetFeatures; hid.callbackSuspendChange=&WriteSuspendBit; + //The temp report needs to know how many bytes it has. + // TODO: The Hid_report structure in USBHID_TYPES should be changed to a class. tempReport.length=1; + //Main Loop while(1) { + //Poll Inputs PollInputs(&tempReport); + //Poll USB Configured WriteConnectedBit(hid.getConnectState()); + //Hidden Configureation option CheckForHeldPauseKey(&tempReport,&hid,&toggle); + //Set up the input data for a send hid.FillInputReport(&tempReport); - display.update(USBstate,features); + //Update the display + display.update(USBstate); wait(0.1); } } +