
Chibios/RT -- A basic example #2 GPT
This example program provides an example of the essential elements required to use Chibios to solve a simple timing issue./* * * Chibios Example program #2 GPT * */ // standard 'C' include files #include <stdio.h> #include <string.h> #include <stdlib.h> // chibios specific include files #include "ch.h" #include "hal.h" /* * GREEN blinker thread, times are in milliseconds. * * This function will become a thread that will execute independent * of the other threads. We will call this thread 2 */ // This macro creates the working space and stack space for thread 2 static WORKING_AREA(waThread2, 128); // This function will become the code for thread 2 static msg_t Thread2(void *arg) { (void)arg; chRegSetThreadName("Green Blinker"); while (TRUE) { palClearPad(GPIOD, GPIOD_LED4); // PD12 - Green LED chThdSleepMilliseconds( 200 ); // delay 200mS palSetPad(GPIOD, GPIOD_LED4); // PD12 - Green LED chThdSleepMilliseconds( 20 ); // delay 20mS } return 0; } /* * RED blinker thread, times are in milliseconds. * * This function will become a thread that will execute independent * of the other threads. We will call this thread 3 * */ // This macro creates the working space and stack space for thread 3 static WORKING_AREA(waThread3, 128); // This function will become the code for thread 3 static msg_t Thread3(void *arg) { (void)arg; chRegSetThreadName("Red Blinker"); while (TRUE) { palSetPad(GPIOD, GPIOD_LED5); // PD14 - Red LED chThdSleepMilliseconds( 100 ); // delay 100mS palClearPad(GPIOD, GPIOD_LED5); // PD14 - Red LED chThdSleepMilliseconds( 100 ); // delay 100mS } return 0; } /* * GPT2 callback. * Every time the timer fires send a new sample to the output port */ static void sample_output_callback(GPTDriver *gptp) { /* counter to waste some time... */ uint32_t delay_count; /* define the pattern index, dataset and datasize size */ static uint16_t pattern_index = 0; static uint8_t pattern_data[] = { 0x00,0x00,0x00,0x00,0x00,0x3a,0x00,0x00, 0x30,0x00,0x30,0x00,0x3e,0x14,0x3e,0x14, 0x1a,0x3b,0x16,0x00,0x24,0x08,0x12,0x00, 0x14,0x2a,0x14,0x02,0x00,0x30,0x00,0x00, 0x00,0x1e,0x21,0x00,0x21,0x1e,0x00,0x00, 0x2a,0x1c,0x2a,0x00,0x08,0x3e,0x08,0x00, 0x01,0x02,0x00,0x00,0x08,0x08,0x08,0x00, 0x00,0x02,0x00,0x00,0x06,0x08,0x30,0x00, 0x1c,0x2a,0x1c,0x00,0x12,0x3e,0x02,0x00, }; #define PATTERN_SIZE sizeof( pattern_data ) /* define the output port -- yea, yea... this is just an example.... */ volatile uint8_t port; volatile uint8_t port2; /* turn on the LED to give us an indication of when this code is running */ /* you will need a logic sniffer or scope to see the pulses */ palSetPad(GPIOD, GPIOD_LED6); // Turn off the Blue LED port = pattern_data[ pattern_index ]; pattern_index++; if( pattern_index > PATTERN_SIZE ) { pattern_index = 0; } /* waste some time, otherwise this callback will run so quick */ /* you won't be able to see it. We have to do something */ /* or our loop could be optimized out */ for( delay_count = 0; delay_count < 100000; delay_count++ ) { port2 = (uint8_t)delay_count % 256; } /* turn off the port to indicate how long this code took to execute */ /* yep, still need that logic sniffer to see it */ palClearPad(GPIOD, GPIOD_LED6); // Turn off the Blue LED } /* * GPT2 configuration. * This configuration block defines a time with a 200kHz counting clock, * and our callback function named sample_output_callback. When we start * the timer we will specify the numbers of clock ticks we want to elapse * between callback execution. * * NOTE: Be sure the execution of the callback is done before calling it * again. Otherwise, strange things may happen.... * Generally, you will want to define the callback function above * this or the compiler will complain about it being undefined. */ static GPTConfig gpt2cfg = { 200000, /* timer clock.*/ sample_output_callback /* Timer callback.*/ }; /* * Application entry point. */ // main() function will become thread 1 // we do not need to allocate working space and stack space for this function, // as this is handled by the startup code for us. int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Creates the blinker threads. */ chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, NULL); chThdCreateStatic(waThread3, sizeof(waThread3), NORMALPRIO, Thread3, NULL); // configure the GPT timer gptStart(&GPTD2, &gpt2cfg); // start the GPT in continuous mode. dT is the time between triggers // Here, we have set the timer clock to 200,000Hz, and we want // to call the callback function every 25 GPT clock cycles. This // means we call the callback function every 125uS or 8,000 time // per second gptStartContinuous(&GPTD2, 25); // dT = 200,000 / 25 = 8,000Hz /* * Main loop, flash Orange LED */ while (TRUE) { palSetPad(GPIOD, GPIOD_LED3); // PD13 - Orange LED chThdSleepMilliseconds( 750 ); // delay 750mS palClearPad(GPIOD, GPIOD_LED3); // PD13 - Orange LED chThdSleepMilliseconds( 750 ); // delay 750mS } }