Mike Moore
/
RTOS_HW_04
RTOS homework 4
main.cpp
- Committer:
- gatedClock
- Date:
- 2013-08-18
- Revision:
- 3:8ff0c9c853be
- Parent:
- 2:1a3acbc4d799
- Child:
- 4:67d958cc00e8
File content as of revision 3:8ff0c9c853be:
/*----------------------------------------------//------------------------------ student : m-moore class : rtos directory : RTOS_HW_04 file : main.cpp ----description---------------------------------//------------------------------ Joystick-Controlled Metronome features: 1. post-initialization functionality all timer-driven. 2. IRSs contain no blocking functions. 3. LED shows the metronome beat. 4. metronome speed controlled with up/down joystick. 5. rate-of-speed-change depends on how long the up/down has been active. 6. Beat-Per-Minute (BPM) shown on LCD display. controls: 1. joystick-up - increase metronome rate. 2. joystick-down - decrease metronome rate. 3. joystick-center - set metronome to 60BPM. notes: testing: 1. confirm ease of being able to adjust one BPM rate with joystick up/down. 2. confirm three joystick up/down change rates, if keeping the stick pressed. 3. confirm max/min BPS saturation & display. 4. confirm joystick up/down control works to change display & LED BPM. 5. confirm joystick center-press sets rate to 60BPM immediately. 6. confirm long-test does not result in a crash. -> all items confirmed. -----includes-----------------------------------//----------------------------*/ #include "mbed.h" // mbed class. #include "C12832_lcd.h" // LCD class. //---defines------------------------------------//------------------------------ #define LCD1 lcd.locate(0, 0); // LCD line 1. #define LCD2 lcd.locate(0,11); // LCD line 2. #define LCD3 lcd.locate(0,22); // LCD line 3. #define JOYUP p15 #define JOYDOWN p12 #define JOYLEFT p13 #define JOYRIGHT p16 #define JOYCENTER p14 #define METROMAX 800 // max. beats per minute. #define METROMIN 8 // min. beats per minute. #define UDSAMPLERATE 0.1 // how often to sample U/D joystick. #define LCDSAMPLERATE 0.1 // how often to redraw the LCD. #define PULSELENGTH 0.0625 // how long the LED-on-time is. //--global_definitions--------------------------//------------------------------ //--global_variables----------------------------//------------------------------ float fMetroDelay; // time between ticks, in seconds. float fMetroDuty; // duration of metro high, in seconds. int dMetroBPM; // master parameter. long lUpDownHowMany; // count how long up/down joystick pressed. //--global_instances----------------------------//------------------------------ C12832_LCD lcd; // LCD object. InterruptIn iJoyStickUp (p15); // 1 if joystick up pressed. InterruptIn iJoyStickDown (p12); // 1 if joystick down pressed. InterruptIn iJoyStickLeft (p13); InterruptIn iJoyStickRight (p16); InterruptIn iJoyStickCenter(p14); // 1 if joystick middle pressed. DigitalOut dJoyStickUp (p15); DigitalOut dJoyStickDown (p12); DigitalOut dJoyStickLeft (p13); DigitalOut dJoyStickRight (p16); DigitalOut dJoyStickCenter(p14); DigitalOut led3(LED1); // leftmost LED. Ticker tickerMetronome; // blinking LED. Ticker tickerJoystickUD; // joystick up/down sample. Ticker tickerLCD; // display ticker. Timeout timeoutDutyCycle; // LED duty cycle delay. //-------prototypes-----------------------------//------------------------------ void initialization(); // initialize settings. void lcd_display(); // display on LCD. void interrupt_service_M(); // metronome tick. void interrupt_service_UD(); // joystick up/down sample. void led3_off(); // attachable LED control. void led3_on(); // attachable LED control. void ISR_up(); void ISR_down(); void ISR_right(); void ISR_left(); void ISR_center(); //==============================================//============================== int main(void) { iJoyStickUp.rise(&ISR_up); } /*----------------------------------------------//----------------------------*/ void initialization(void) // program initializations. { dMetroBPM = 60; // initialize to 60BPM. fMetroDelay = 60.0 / (float) (dMetroBPM); fMetroDuty = PULSELENGTH; // initialize LED on-duration. lUpDownHowMany = 0; } /*----------------------------------------------//----------------------------*/ void ISR_up(void) // metronome stop. { int dPressedSeconds; // how many seconds joystick pressed. int dMultiCount; // slow count rate. char cDiscontinuity; // 1 = break phase & change BPM now. cDiscontinuity = 0; // don't break phase. // calculate slow rate period. dMultiCount = (int) ((float) (1.0 / ((float) UDSAMPLERATE))); if (dJoyStickUp) // joystick up. { // rate-range calculations. dPressedSeconds = (int) (((float) lUpDownHowMany) * UDSAMPLERATE); if (dPressedSeconds < 5) {if (!(lUpDownHowMany % dMultiCount)) dMetroBPM ++;} else if (dPressedSeconds < 10) dMetroBPM++; else dMetroBPM += 5; lUpDownHowMany++; // joystick holddown time. } } /*----------------------------------------------//----------------------------*/ void ISR_down(void) // metronome START. { } /*----------------------------------------------//----------------------------*/ void ISR_left(void) // increase BPM. { } /*----------------------------------------------//----------------------------*/ void ISR_right(void) // decrease BPM. { } /*----------------------------------------------//----------------------------*/ void ISR_center(void) // set BPM = 60. { } /*----------------------------------------------//----------------------------*/ void lcd_display(void) // display metronome info. { lcd.cls(); // clear display. LCD1; // line 1. lcd.printf(" METRONOME"); LCD2; // line 2. if (dMetroBPM == METROMIN) // BPM, with saturation notification. lcd.printf(" %5.2d BPM minimum",dMetroBPM); else if (dMetroBPM == METROMAX) lcd.printf(" %5.2d BPM maximum",dMetroBPM); else lcd.printf(" %5.2d BPM",dMetroBPM); LCD3; // line 3. lcd.printf(" RTOS HW 3 PART 1"); } /*----------------------------------------------//----------------------------*/ // this metronome tick ISR will self-adjust to the current user-selected // metronome rate. that has to be done here, and at the start of the function, // in order to maintain a constant phase and to prevent a beat-skip. void interrupt_service_M() // metronome tick. { tickerMetronome.detach(); // only one attachment. tickerMetronome.attach(&interrupt_service_M,fMetroDelay); led3 = 1; timeoutDutyCycle.attach(&led3_off,fMetroDuty); } /*----------------------------------------------//----------------------------*/ // this routine measures the number of seconds for which the joystick is // in the up or down position. for three ranges of time, three different // BPM rates-of-change are used. This means that as the user controls the // metronome rate using the joystick, at first it will change slowly, then // it will change at a moderate speed, then it will change quickly. // additionally, pressing the center joystick button will bring the metronome // back to 60BPM immediately, breaking BPM phase continuity. void interrupt_service_UD(void) // joystick up/down sample { int dPressedSeconds; // how many seconds joystick pressed. int dMultiCount; // slow count rate. char cDiscontinuity; // 1 = break phase & change BPM now. cDiscontinuity = 0; // don't break phase. // calculate slow rate period. dMultiCount = (int) ((float) (1.0 / ((float) UDSAMPLERATE))); if (dJoyStickUp) // joystick up. { // rate-range calculations. dPressedSeconds = (int) (((float) lUpDownHowMany) * UDSAMPLERATE); if (dPressedSeconds < 5) {if (!(lUpDownHowMany % dMultiCount)) dMetroBPM ++;} else if (dPressedSeconds < 10) dMetroBPM++; else dMetroBPM += 5; lUpDownHowMany++; // joystick holddown time. } else if (dJoyStickDown) // joystick down. { // rate-range calculations. dPressedSeconds = (int) (((float) lUpDownHowMany) * UDSAMPLERATE); if (dPressedSeconds < 5) {if (!(lUpDownHowMany % dMultiCount)) dMetroBPM --;} else if (dPressedSeconds < 10) dMetroBPM--; else dMetroBPM -= 5; lUpDownHowMany++; // joystick holddown time. } else lUpDownHowMany = 0; // clear when not up or down. if (dJoyStickCenter) { dMetroBPM = 60; // center-button -> 60BPM. cDiscontinuity = 1; // pending phase-break. } // saturate metronome BPM. if (dMetroBPM > METROMAX) dMetroBPM = METROMAX; if (dMetroBPM < METROMIN) dMetroBPM = METROMIN; fMetroDelay = 60.0 / (float) (dMetroBPM); // calculate Ticker delay time. if (cDiscontinuity) // implement 60BPS now. { tickerMetronome.detach(); // only one attachment. tickerMetronome.attach(&interrupt_service_M,fMetroDelay); } } /*----------------------------------------------//----------------------------*/ void led3_off(void) {led3 = 0;} // turn off the LED. /*----------------------------------------------//----------------------------*/ void led3_on( void) {led3 = 1;} // turn on the led. /*----------------------------------------------//----------------------------*/