I have a problem understanding GPT. I belived that it will use a hardware timer to trigger a function periodically, but it seems to me that, if I don't put a minimum sleep in the code, the callback is never called. I would use the callback to update a timestamp variable. Any clue about what I'm doing wrong? If I use the CubeMx project with interrupt handler, it works fine as I am expected.
Many thanks
Code: Select all
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include "shell.h"
#include "usbcfg.h"
static uint32_t timestamp = 0;
static void TimeStampCallback()
{
timestamp += 1;
}
static GPTConfig gptCfg = {
1000000, /* timer clock.*/
TimeStampCallback, /* Timer callback.*/
0,
0
};
#define GPT_RESOLUTION (5) // 5us each tick
/*
* Green LED blinker thread, times are in milliseconds.
*/
static THD_WORKING_AREA(waThread2, 128);
static THD_FUNCTION(Thread2, arg) {
(void)arg;
chRegSetThreadName("blinker2");
while (true) {
if(timestamp > 50000)
{
palClearPad(GPIOG, GPIOG_LED3_GREEN);
timestamp = 0;
}
// chThdSleepMicroseconds(1); // with the sleep it works, without the timestamp variable seems to be never updated
}
}
/*===========================================================================*/
/* Command line related. */
/*===========================================================================*/
#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(2048)
static const ShellCommand commands[] = {
{NULL, NULL}
};
static const ShellConfig shell_cfg1 = {
(BaseSequentialStream *)&SDU1,
commands
};
/*===========================================================================*/
/* Initialization and main thread. */
/*===========================================================================*/
/*
* Application entry point.
*/
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();
/*
* Shell manager initialization.
*/
shellInit();
/*
* Initializes a serial-over-USB CDC driver.
*/
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg);
// configure the GPT timer
gptStart(&GPTD1, &gptCfg);
gptStartContinuous(&GPTD1, GPT_RESOLUTION); // dT = 1,000,000 / GPT_RESOLUTION = x us
/*
* Activates the USB driver and then the USB bus pull-up on D+.
* Note, a delay is inserted in order to not have to disconnect the cable
* after a reset.
*/
usbDisconnectBus(serusbcfg.usbp);
chThdSleepMilliseconds(1000);
usbStart(serusbcfg.usbp, &usbcfg);
usbConnectBus(serusbcfg.usbp);
/*
* Creating the blinker threads.
*/
chThdCreateStatic(waThread2, sizeof(waThread2),
NORMALPRIO, Thread2, NULL);
/*
* Normal main() thread activity, spawning shells.
*/
while (true) {
if (SDU1.config->usbp->state == USB_ACTIVE) {
thread_t *shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
"shell", NORMALPRIO + 1,
shellThread, (void *)&shell_cfg1);
chThdWait(shelltp); /* Waiting termination. */
}
chThdSleepMilliseconds(1000);
}
}