An example Discovery program built on Anton's refactor branch.
/*
Example for Discovery board built on Anton's refactor branch.
Shows:
LCD module library
GPIO inputs and outputs
Timers
Timer interrupts
External interrupts
Interrupt handlers
 Demonstrates usage of the HardwareTimer classes by blinking the LEDs
 Created 22 April 2010, By Bryan Newbold for LeafLabs
 Updated 8 June 2010,   By Bryan Newbold for LeafLabs
 Modified 21 March 2011, for Discovery board  By ridgebackred
 Modified  6 April 2011, for Discovery board refactor branch  By ridgebackred
 This code is released with no strings attached.
 Demonstrates the use a 20x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
  The circuit:
 * LCD +5V to        5V
 * LCD GND to        GND
 * LCD RS pin to     PB10, digital pin 29, 5 Volt tolerant
 * LCD Enable pin to PB11, digital pin 30, 5 Volt tolerant
 * LCD D4 pin to     PB12, digital pin 31, 5 Volt tolerant
 * LCD D5 pin to     PB13, digital pin 32, 5 Volt tolerant
 * LCD D6 pin to     PB14, digital pin 33, 5 Volt tolerant
 * LCD D7 pin to     PB15, digital pin 34, 5 Volt tolerant
 * LCD R/W pin to    GND
 * 10K potentiometer:
 * one end to GND
 * wiper to LCD VO pin (pin 3)
 ************************************************************/
#include "wirish.h"
//Change the path name for your system...
#include <C:\libmaple\discovery2\libraries\LiquidCrystal\LiquidCrystal.h>
 // Initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(29, 30, 31, 32, 33, 34);
void handler_green_led (void);
void handler_blue_led  (void);
void handler1          (void);
void handler2          (void);
voidFuncPtr handlers[] = {handler1, handler2};
timer_dev *timers[] = {TIMER1, TIMER2, TIMER3, TIMER4};
void initTimer(timer_dev *dev);
void setTimerPeriod(timer_dev *dev, uint32 period_us);
void testTimerChannels(timer_dev *dev);
int timerNumber(timer_dev *dev);
 // These variables won't change during program execution
const int blueledPin    = 37;
const int greenledPin   = 38;
const int userbuttonPin = 2;
const int BLUE_LED_RATE = 500000;   // Units = microseconds; should give 0.5Hz toggles
 // These variables change during program execution
int count1       = 0;
int count2       = 0;
int toggle_blue  = 0;
 // Do housekeeping activities once at power-up
void setup()
{
    // Set up the LED pins as outputs
    pinMode(blueledPin,  OUTPUT);
    pinMode(greenledPin, OUTPUT);
    // Set up User Button pin as input and attach interrupt handler
    pinMode(userbuttonPin, INPUT);
    attachInterrupt(userbuttonPin, handler_green_led, RISING);
    // Set up the LCD's number of rows and columns:
    lcd.begin(20, 2);
    lcd.print("LibMaple ~ Discovery");
    lcd.setCursor(0, 1);
    lcd.print("IDE0.0.9 refactor");
    delay(1500);                      // Show splash screen for a few seconds
    lcd.clear();
    lcd.setCursor(0, 0);              // 1st column, 1st row
    lcd.print("Count1    Count2");
    // Setup blue LED toggle Timer
    timer_set_mode(TIMER2, TIMER_CH1, TIMER_OUTPUT_COMPARE);
    setTimerPeriod(TIMER2, BLUE_LED_RATE);
    timer_set_compare(TIMER2, 1, 1);                   // Overflow might be small
    timer_attach_interrupt(TIMER2, TIMER_CC1_INTERRUPT, handler_blue_led);
    // Setup the counting Timers
    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, 15000);
    timer_set_reload(TIMER4, 30000);
    timer_set_compare(TIMER3, 1, 1000);
    timer_set_compare(TIMER4, 1, 1000);
    timer_attach_interrupt(TIMER3, TIMER_CC1_INTERRUPT, handler1);
    timer_attach_interrupt(TIMER4, TIMER_CC1_INTERRUPT, handler2);
    timer_resume(TIMER3);
    timer_resume(TIMER4);
}
 // Forever loop after running setup()
void loop() {
    delay(250);                       // Slow down the updates to the LCD
    lcd.setCursor(0, 1);              // 1st column,  2nd row
    lcd.print(count1);
    lcd.setCursor(10, 1);             // 11th column, 2nd row
    lcd.print(count2);
    digitalWrite(greenledPin, LOW);   // in case the button interrupt was hit
    timer_resume(TIMER4);             // in case the button interrupt was hit, restart timer
}
 // User Button interrupt handler
 // Will ignore the delay in the 'loop' to become active
void handler_green_led(void) {
    digitalWrite(greenledPin, HIGH);
    timer_pause(TIMER4);     //Stop TIMER4 until restarted in loop()
} 
 // Timer2 interrupt handler
void handler_blue_led(void) {
    toggle_blue ^= 1;
    digitalWrite(blueledPin, toggle_blue);
} 
 // Timer3 interrupt handler
void handler1(void) {
    count1++;
}
 // Timer4 interrupt handler
void handler2(void) {
    count2++;
} 
//The following will probably change with release of IDE0.0.10
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;
    }
}
// FIXME move this into the new wirish timer implementation
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;
    }
}
// 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);
}
// Force init to be called *first*, i.e. before static object allocation.
// Otherwise, statically allocated objects that need libmaple may fail.
__attribute__(( constructor )) void premain() {
    init();
}
int main(void) {
    setup();
    while (1) {
        loop();
    }
    return 0;
}