diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/test-session.cpp | 19 | ||||
| -rw-r--r-- | examples/test-timers.cpp | 372 | 
2 files changed, 216 insertions, 175 deletions
diff --git a/examples/test-session.cpp b/examples/test-session.cpp index a147e06..9b4bce4 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -15,7 +15,6 @@  //#define COMM Serial2  //#define COMM Serial3 -  #define ESC       ((uint8)27)  int rate = 0; @@ -610,17 +609,15 @@ void cmd_servo_sweep(void) {      COMM.println("(reset serial port)");  } +static uint16 init_all_timers_prescale = 0; + +static void set_prescale(timer_dev *dev) { +    timer_set_prescaler(dev, init_all_timers_prescale); +} +  void init_all_timers(uint16 prescale) { -    timer_init(TIMER1, prescale); -    timer_init(TIMER2, prescale); -    timer_init(TIMER3, prescale); -    timer_init(TIMER4, prescale); -#ifdef STM32_HIGH_DENSITY -    timer_init(TIMER5, prescale); -    // timer_init(TIMER6, prescale); -    // timer_init(TIMER7, prescale); -    timer_init(TIMER8, prescale); -#endif +    init_all_timers_prescale = prescale; +    timer_foreach(set_prescale);  }  // Force init to be called *first*, i.e. before static object allocation. diff --git a/examples/test-timers.cpp b/examples/test-timers.cpp index f3cfdcc..a4fbc8a 100644 --- a/examples/test-timers.cpp +++ b/examples/test-timers.cpp @@ -1,8 +1,7 @@ -// Program to test the wirish timers implementation +// Program to test the timer.h implementation's essential functionality.  #include "wirish.h" - -#define LED_PIN BOARD_LED_PIN +#include "timer.h"  void handler1(void);  void handler2(void); @@ -27,208 +26,253 @@ uint16 val2 = 10000;  uint16 val3 = 10000;  uint16 val4 = 10000; -HardwareTimer Timers[] = {Timer1, Timer2, Timer3, Timer4}; +// FIXME high density timer test (especially basic timers + DAC) +timer_dev *timers[] = {TIMER1, TIMER2, TIMER3, TIMER4}; +voidFuncPtr handlers[] = {handler1, handler2, handler3, handler4}; + +void initTimer(timer_dev *dev); +void setTimerPeriod(timer_dev *dev, uint32 period_us); +void testSetTimerPeriod(uint32 period); +void testTimerChannels(timer_dev *dev); +int timerNumber(timer_dev *dev); -void setup() -{ -    /* Set up the LED to blink  */ -    pinMode(LED_PIN, OUTPUT); +void setup() { +    // Set up the LED to blink +    pinMode(BOARD_LED_PIN, OUTPUT);      // Setup the button as input      pinMode(BOARD_BUTTON_PIN, INPUT); -    // Wait for user to attach... -    waitForButtonPress(0); - -    // Send a message out SerialUSB -    SerialUSB.println("Beginning timer test..."); -    for(int t=0; t<4; t++) { -        Timers[t].setChannel1Mode(TIMER_OUTPUTCOMPARE); -        Timers[t].setChannel2Mode(TIMER_OUTPUTCOMPARE); -        Timers[t].setChannel3Mode(TIMER_OUTPUTCOMPARE); -        Timers[t].setChannel4Mode(TIMER_OUTPUTCOMPARE); -    } +    // Send a message out Serial2 +    Serial2.begin(115200); +    Serial2.println("*** Initializing timers..."); +    Serial2.println("foo"); +    timer_foreach(initTimer); +    Serial2.println("*** Done. Beginning timer test.");  }  void loop() { -    SerialUSB.println("-----------------------------------------------------"); -    SerialUSB.println("Testing setCount/getCount"); -    SerialUSB.print("Timer1.getCount() = "); SerialUSB.println(Timer1.getCount()); -    SerialUSB.println("Timer1.setCount(1234)"); -    Timer1.setCount(1234); -    SerialUSB.print("Timer1.getCount() = "); SerialUSB.println(Timer1.getCount()); -    // This tests whether the pause/resume functions work; when BUT is held -    // down Timer4 is in the "pause" state and the timer doesn't increment, so -    // the final counts should reflect the ratio of time that BUT was held down -    SerialUSB.println("-----------------------------------------------------"); -    SerialUSB.println("Testing Pause/Resume; button roughly controls Timer4"); +    Serial2.println("-----------------------------------------------------"); + +    Serial2.println("Testing timer_get_count()/timer_set_count()"); +    Serial2.print("TIMER1 count = "); +    Serial2.println(timer_get_count(TIMER1)); +    Serial2.println("timer_set_count(TIMER1, 1234)"); +    timer_set_count(TIMER1, 1234); +    Serial2.print("timer_get_count(TIMER1) = "); +    Serial2.println(timer_get_count(TIMER1)); + +    Serial2.println("-----------------------------------------------------"); +    Serial2.println("Testing pause/resume; button roughly controls TIMER4"); +    // when BUT is held down, TIMER4 is in the "pause" state and the +    // timer doesn't increment, so the final counts should reflect the +    // ratio of time that BUT was held down.      count3 = 0;      count4 = 0; -    Timer3.setChannel1Mode(TIMER_OUTPUTCOMPARE); -    Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); -    Timer3.pause(); -    Timer4.pause(); -    Timer3.setCount(0); -    Timer4.setCount(0); -    Timer3.setOverflow(30000); -    Timer4.setOverflow(30000); -    Timer3.setCompare1(1000); -    Timer4.setCompare1(1000); -    Timer3.attachCompare1Interrupt(handler3b); -    Timer4.attachCompare1Interrupt(handler4b); -    Timer3.resume(); -    Timer4.resume(); -    SerialUSB.println("~4 seconds..."); -    for(int i = 0; i<4000; i++) { -        if(isButtonPressed()) { -            Timer4.pause(); +    timer_set_mode(TIMER3, TIMER_CH1, TIMER_OUTPUT_COMPARE); +    timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); +    timer_pause(TIMER3); +    timer_pause(TIMER4); +    timer_set_count(TIMER3, 0); +    timer_set_count(TIMER4, 0); +    timer_set_reload(TIMER3, 30000); +    timer_set_reload(TIMER4, 30000); +    timer_set_compare(TIMER3, 1, 1000); +    timer_set_compare(TIMER4, 1, 1000); +    timer_attach_interrupt(TIMER3, TIMER_CC1_INTERRUPT, handler3b); +    timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); +    timer_resume(TIMER3); +    timer_resume(TIMER4); + +    Serial2.println("Testing for ~4 seconds..."); +    for(int i = 0; i < 4000; i++) { +        if (isButtonPressed()) { +            timer_pause(TIMER4);          } else { -            Timer4.resume(); +            timer_resume(TIMER4);          }          delay(1);      } -    Timer3.setChannel1Mode(TIMER_DISABLED); -    Timer4.setChannel1Mode(TIMER_DISABLED); -    SerialUSB.print("Count3: "); SerialUSB.println(count3); -    SerialUSB.print("Count4: "); SerialUSB.println(count4); - -    // These test the setPeriod auto-configure functionality -    SerialUSB.println("-----------------------------------------------------"); -    SerialUSB.println("Testing setPeriod"); -    Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); -    Timer4.setCompare1(1); -    Timer4.setPeriod(10); -    Timer4.pause(); -    Timer4.setCount(0); -    Timer4.attachCompare1Interrupt(handler4b); -    SerialUSB.println("Period 10ms, wait 2 seconds..."); -    count4 = 0; -    Timer4.resume(); -    delay(2000); -    Timer4.pause(); -    Timer4.setChannel1Mode(TIMER_DISABLED); -    SerialUSB.print("Count4: "); SerialUSB.println(count4); -    SerialUSB.println("(should be around 2sec/10ms = 200000)"); -    Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); -    Timer4.setCompare1(1); -    Timer4.pause(); -    Timer4.setPeriod(30000); -    Timer4.setCount(0); -    Timer4.attachCompare1Interrupt(handler4b); -    SerialUSB.println("Period 30000ms, wait 2 seconds..."); -    count4 = 0; -    Timer4.resume(); -    delay(2000); -    Timer4.pause(); -    Timer4.setChannel1Mode(TIMER_DISABLED); -    SerialUSB.print("Count4: "); SerialUSB.println(count4); -    SerialUSB.println("(should be around 2sec/30000ms ~ 67)"); - -    Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); -    Timer4.setPeriod(300000); -    Timer4.setCompare1(1); -    Timer4.pause(); -    Timer4.setCount(0); -    Timer4.attachCompare1Interrupt(handler4b); -    SerialUSB.println("Period 300000ms, wait 2 seconds..."); -    count4 = 0; -    Timer4.resume(); -    delay(2000); -    Timer4.pause(); -    Timer4.setChannel1Mode(TIMER_DISABLED); -    SerialUSB.print("Count4: "); SerialUSB.println(count4); -    SerialUSB.println("(should be around 2sec/300000ms ~ 6.7)"); - -    Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); -    Timer4.setPrescaleFactor(33); -    Timer4.setOverflow(65454); -    Timer4.pause(); -    Timer4.setCount(0); -    Timer4.setCompare1(1); -    Timer4.attachCompare1Interrupt(handler4b); -    SerialUSB.println("Period 30000ms, wait 2 seconds..."); + +    timer_set_mode(TIMER3, TIMER_CH1, TIMER_DISABLED); +    timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); + +    Serial2.print("TIMER3 count: "); +    Serial2.println(timer_get_count(TIMER3)); +    Serial2.print("TIMER4 count: "); +    Serial2.println(timer_get_count(TIMER4)); + +    Serial2.println("-----------------------------------------------------"); +    Serial2.println("Testing setTimerPeriod()"); +    testSetTimerPeriod(10); +    testSetTimerPeriod(30000); +    testSetTimerPeriod(300000); +    testSetTimerPeriod(30000); + +    Serial2.println("Sanity check (with hand-coded reload and prescaler for " +                      "72 MHz timers):"); +    timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); +    timer_set_prescaler(TIMER4, 33); +    timer_set_reload(TIMER4, 65454); +    timer_pause(TIMER4); +    timer_set_count(TIMER4, 0); +    timer_set_compare(TIMER4, TIMER_CH1, 1); +    timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); +    Serial2.println("Period 30000ms, wait 2 seconds...");      count4 = 0; -    Timer4.resume(); +    timer_resume(TIMER4);      delay(2000); -    Timer4.pause(); -    Timer4.setChannel1Mode(TIMER_DISABLED); -    SerialUSB.print("Count4: "); SerialUSB.println(count4); -    SerialUSB.println("(should be around 2sec/30000ms ~ 67)"); - -    Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); -    Timer4.setCompare1(1); -    Timer4.setPeriod(30000); -    Timer4.pause(); -    Timer4.setCount(0); -    Timer4.attachCompare1Interrupt(handler4b); -    SerialUSB.println("Period 30000ms, wait 2 seconds..."); +    timer_pause(TIMER4); +    timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); +    Serial2.print("TIMER4 count: "); +    Serial2.println(count4); +    Serial2.println("  (Should be around 2sec/30000ms ~ 67)"); + +    // Test all the individual timer channels +    timer_foreach(testTimerChannels); +} + +void initTimer(timer_dev *dev) { +    switch (dev->type) { +    case TIMER_ADVANCED: +    case TIMER_GENERAL: +        Serial2.print("Initializing timer "); +        Serial2.println(timerNumber(dev)); +        for (int c = 1; c <= 4; c++) { +            timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE); +        } +        Serial2.println("Done."); +        break; +    case TIMER_BASIC: +        break; +    } +} + +void testSetTimerPeriod(uint32 period) { +    timer_set_mode(TIMER4, TIMER_CH1, TIMER_OUTPUT_COMPARE); +    timer_set_compare(TIMER4, TIMER_CH1, 1); +    setTimerPeriod(TIMER4, period); +    timer_pause(TIMER4); +    timer_set_count(TIMER4, 0); +    timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler4b); +    Serial2.println("Period "); +    Serial2.print(period); +    Serial2.print(" ms. Waiting 2 seconds...");      count4 = 0; -    Timer4.resume(); +    timer_resume(TIMER4);      delay(2000); -    Timer4.pause(); -    Timer4.setChannel1Mode(TIMER_DISABLED); -    SerialUSB.print("Count4: "); SerialUSB.println(count4); -    SerialUSB.println("(should be around 2sec/30000ms ~ 67)"); - -    // This section is to touch every channel of every timer. The output -    // ratios should reflect the ratios of the rate variables. Demonstrates -    // that over time the actual timing rates get blown away by other system -    // interrupts. -    for(t=0; t<4; t++) { -        toggleLED(); -        delay(100); -        SerialUSB.println("-----------------------------------------------------"); -        SerialUSB.print("Testing Timer "); SerialUSB.println(t+1); +    timer_pause(TIMER4); +    timer_set_mode(TIMER4, TIMER_CH1, TIMER_DISABLED); +    Serial2.print("TIMER4 count: "); +    Serial2.println(timer_get_count(TIMER4)); +    Serial2.print("  (Should be around 2 sec / "); +    Serial2.print(period); +    Serial2.print(" ms = "); +    Serial2.print(double(2) / period * 1000); +    Serial2.println(", modulo delays due to interrupts)"); +} + +int timerNumber(timer_dev *dev) { +    switch (dev->clk_id) { +    case RCC_TIMER1: +        return 1; +    case RCC_TIMER2: +        return 2; +    case RCC_TIMER3: +        return 3; +    case RCC_TIMER4: +        return 4; +#ifdef STM32_HIGH_DENSITY +    case RCC_TIMER5: +        return 5; +    case RCC_TIMER6: +        return 6; +    case RCC_TIMER7: +        return 7; +    case RCC_TIMER8: +        return 8; +#endif +    default: +        ASSERT(0); +        return 0; +    } +} + +/* This function touches every channel of a given timer. The output + * ratios should reflect the ratios of the rate variables.  It + * demonstrates that, over time, the actual timing rates get blown + * away by other system interrupts. */ +void testTimerChannels(timer_dev *dev) { +    t = timerNumber(dev); +    toggleLED(); +    delay(100); +    Serial2.println("-----------------------------------------------------"); +    switch (dev->type) { +    case TIMER_BASIC: +        Serial2.print("NOT testing channels for basic timer "); +        Serial2.println(t); +        break; +    case TIMER_ADVANCED: +    case TIMER_GENERAL: +        Serial2.print("Testing channels for timer "); +        Serial2.println(t); +        timer_pause(dev);          count1 = count2 = count3 = count4 = 0; -        Timers[t].setOverflow(0xFFFF); -        Timers[t].setPrescaleFactor(1); -        Timers[t].setCompare1(65535); -        Timers[t].setCompare2(65535); -        Timers[t].setCompare3(65535); -        Timers[t].setCompare4(65535); -        Timers[t].setChannel1Mode(TIMER_OUTPUTCOMPARE); -        Timers[t].setChannel2Mode(TIMER_OUTPUTCOMPARE); -        Timers[t].setChannel3Mode(TIMER_OUTPUTCOMPARE); -        Timers[t].setChannel4Mode(TIMER_OUTPUTCOMPARE); -        Timers[t].attachCompare1Interrupt(handler1); -        Timers[t].attachCompare2Interrupt(handler2); -        Timers[t].attachCompare3Interrupt(handler3); -        Timers[t].attachCompare4Interrupt(handler4); -        Timers[t].resume(); +        timer_set_reload(dev, 0xFFFF); +        timer_set_prescaler(dev, 1); +        for (int c = 1; c <= 4; c++) { +            timer_set_compare(dev, c, 65535); +            timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE); +            timer_attach_interrupt(dev, c, handlers[c - 1]); +        } +        timer_resume(dev);          delay(3000); -        Timers[t].setChannel1Mode(TIMER_DISABLED); -        Timers[t].setChannel2Mode(TIMER_DISABLED); -        Timers[t].setChannel3Mode(TIMER_DISABLED); -        Timers[t].setChannel4Mode(TIMER_DISABLED); -        SerialUSB.print("Count1: "); SerialUSB.println(count1); -        SerialUSB.print("Count2: "); SerialUSB.println(count2); -        SerialUSB.print("Count3: "); SerialUSB.println(count3); -        SerialUSB.print("Count4: "); SerialUSB.println(count4); +        for (int c = 1; c <= 4; c++) { +            timer_set_mode(dev, c, TIMER_DISABLED); +        } +        Serial2.print("Channel 1 count: "); Serial2.println(count1); +        Serial2.print("Channel 2 count: "); Serial2.println(count2); +        Serial2.print("Channel 3 count: "); Serial2.println(count3); +        Serial2.print("Channel 4 count: "); Serial2.println(count4); +        break; +    } +} + +// FIXME move this into the new wirish timer implementation +void setTimerPeriod(timer_dev *dev, uint32 period_us) { +    if (!period_us) { +        // FIXME handle this case +        ASSERT(0); +        return;      } +    uint32 cycles = period_us * CYCLES_PER_MICROSECOND; +    uint16 pre = (uint16)((cycles >> 16) + 1); +    timer_set_prescaler(dev, pre); +    timer_set_reload(dev, cycles / pre - 1);  }  void handler1(void) {      val1 += rate1; -    Timers[t].setCompare1(val1); +    timer_set_compare(timers[t], TIMER_CH1, val1);      count1++;  }  void handler2(void) {      val2 += rate2; -    Timers[t].setCompare2(val2); +    timer_set_compare(timers[t], TIMER_CH2, val2);      count2++;  }  void handler3(void) {      val3 += rate3; -    Timers[t].setCompare3(val3); +    timer_set_compare(timers[t], TIMER_CH3, val3);      count3++;  }  void handler4(void) {      val4 += rate4; -    Timers[t].setCompare4(val4); +    timer_set_compare(timers[t], TIMER_CH4, val4);      count4++;  }  | 
