RTOS homework 4

Dependencies:   C12832_lcd mbed

main.cpp

Committer:
gatedClock
Date:
2013-08-18
Revision:
18:f19721f1069e
Parent:
17:cd6c76be8046
Child:
19:0db1451d19ef

File content as of revision 18:f19721f1069e:

/*----------------------------------------------//------------------------------
    student   : m-moore
    class     : rtos
    directory : RTOS_HW_04
    file      : main.cpp
----description---------------------------------//------------------------------
    Joystick-Controlled Metronome
    
    features:

    
    controls:
    1. joystick-up     - increase metronome rate.
    2. joystick-down   - decrease metronome rate.
    3. joystick-center - set metronome to 60BPM.
    
    notes:
    
    testing:


-----includes-----------------------------------//----------------------------*/
    #include "mbed.h"                           // mbed class.
//  #include "rtos.h"
    #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 METROMAX       800                  // max. beats per minute.
    #define METROMIN         8                  // min. beats per minute.
    #define METROTIME       10.0
    #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.
    #define DEBOUNCE         0.16               // debounce pause duration in S.
//--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.
    char  cMetronomeOn;                         // 1 = allow blink.
//--global_instances----------------------------//------------------------------ 
    C12832_LCD   lcd;                           // LCD object.
    
    InterruptIn  iJoyStickUp    (p15);          // joystick up rising edge.
    InterruptIn  iJoyStickDown  (p12);          // joystick down rising edge.
    InterruptIn  iJoyStickLeft  (p13);          // joystick left rising edge.
    InterruptIn  iJoyStickRight (p16);          // joystick right rising edge.
    InterruptIn  iJoyStickCenter(p14);          // 1 if joystick middle pressed.

    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.
    Timeout     timeoutMetronome;
//-------prototypes-----------------------------//------------------------------
    void initialization();                      // initialize settings.
    void lcd_display();                         // display on LCD.
    void interrupt_service_M();                 // metronome tick.                
    void led3_off();                            // attachable LED control.
    void led3_on();                             // attachable LED control.
    void ISR_up();                              // stop metronome.
    void ISR_down();                            // start metronome.
    void ISR_right_rising();                    // decrease BPM.
    void ISR_right_falling();                   // bounce protection.
    void ISR_left_rising();                     // increase BPM.
    void ISR_left_falling();                    // bounce protection.
    void ISR_center();                          // set to 60BPM.
    void turn_off_metronome();                  // turn off blinker.
//==============================================//==============================
    int main(void) 
    {
      iJoyStickUp.rise   (&ISR_up);             // metronome stop.
      iJoyStickDown.rise (&ISR_down);           // metronome start.
      
      iJoyStickLeft.rise (&ISR_left_rising);    // increase BPM.
      iJoyStickLeft.fall (&ISR_left_falling);   // anti-bounce.
      
      iJoyStickRight.rise(&ISR_right_rising);   // decrease BPM.
      iJoyStickRight.fall(&ISR_right_falling);  // anti-bounce.
      
      iJoyStickCenter.rise(&ISR_center);        // 60BPM.
      
      initialization();                         // initialize variables.
      
                                                // metronome ticker.
      tickerMetronome.attach(&interrupt_service_M,fMetroDelay);
      
                                                // LCD ticker.
      tickerLCD.attach(&lcd_display,LCDSAMPLERATE);  
      
      while(1)                                  // all timer/interrupt driven.
      {
        wait(10.0);
      }
    }       
/*----------------------------------------------//----------------------------*/
    void initialization(void)                   // program initializations.
    {
      dMetroBPM      = 60;                      // initialize to 60BPM.      
      fMetroDelay    = 60.0 / (float) (dMetroBPM);
      fMetroDuty     = PULSELENGTH;             // initialize LED on-duration.
 //     lUpDownHowMany = 0;
      cMetronomeOn   = 0;
    }
/*----------------------------------------------//----------------------------*/
    void ISR_left_rising(void)                  // increase BPM.
    {
      __disable_irq();                          // anti-bounce.

      dMetroBPM++;                              // increase BPM.
      
                                                // saturate metronome BPM.
      if (dMetroBPM > METROMAX) dMetroBPM = METROMAX;
      if (dMetroBPM < METROMIN) dMetroBPM = METROMIN;
      
      wait(DEBOUNCE);                           // debounce time.
      
      __enable_irq();                           // safe by now.
    }
/*----------------------------------------------//----------------------------*/
    void ISR_left_falling(void)                 // ignore rising after falling edge.
    {
      __disable_irq();                          // anti-bounce.
      
      wait(DEBOUNCE);                           // debounce time.
      
      __enable_irq();                           // safe by now.
    }
/*----------------------------------------------//----------------------------*/
    void ISR_right_rising(void)                 // decrease BPM.
    {
      __disable_irq();                          // anti-bounce.

      dMetroBPM--;                              // decrease BPM.
      
                                                // saturate metronome BPM.
      if (dMetroBPM > METROMAX) dMetroBPM = METROMAX;
      if (dMetroBPM < METROMIN) dMetroBPM = METROMIN;
      
      wait(DEBOUNCE);                           // debounce time.
      
      __enable_irq();                           // safe by now.
    }
/*----------------------------------------------//----------------------------*/
    void ISR_right_falling(void)                // ignore rising after falling edge.
    {
      __disable_irq();                          // anti-bounce.
      
      wait(DEBOUNCE);                           // debounce time.
      
      __enable_irq();                           // safe by now.
    }
/*----------------------------------------------//----------------------------*/
    void ISR_up(void)                           // turn off metronome.
    {
      cMetronomeOn = 0;
    }
/*----------------------------------------------//----------------------------*/
    void ISR_down(void)                         // metronome on with timeout.
    {
      cMetronomeOn = 1;
      timeoutMetronome.detach();
      timeoutMetronome.attach(&turn_off_metronome,METROTIME);
    }
/*----------------------------------------------//----------------------------*/
    void ISR_center(void)                       // set BPM = 60.
    {
      dMetroBPM = 60;
    }
/*----------------------------------------------//----------------------------*/
    void lcd_display(void)                      // display metronome info.
    {
      lcd.cls();                                // clear display.
      
      LCD1;                                     // line 1.
      
      if (cMetronomeOn)
      lcd.printf("  metronome ON");
      else
      lcd.printf("  metronome OFF");

      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 4");
    }
/*----------------------------------------------//----------------------------*/
//  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.
    {        
      if (cMetronomeOn)
      {
        tickerMetronome.detach();               // only one attachment.  
        tickerMetronome.attach(&interrupt_service_M,fMetroDelay);      
        led3_on();
        timeoutDutyCycle.attach(&led3_off,fMetroDuty);
      } else led3_off();
    }
/*----------------------------------------------//----------------------------*/
    void turn_off_metronome(void)               // turn off metronome.
    {
      cMetronomeOn = 0;
    }
/*----------------------------------------------//----------------------------*/
    void led3_off(void) {led3 = 0;}             // turn off the LED.
/*----------------------------------------------//----------------------------*/
    void led3_on( void) {led3 = 1;}             // turn on the led.
/*----------------------------------------------//----------------------------*/