[NUCLEO_xxx] Fix issue with attach_us function

pull/165/head
bcostm 2014-02-13 14:11:01 +01:00
parent 156be94791
commit fda11bae82
4 changed files with 146 additions and 124 deletions

View File

@ -37,8 +37,15 @@
static int us_ticker_inited = 0; static int us_ticker_inited = 0;
static uint32_t SlaveCounter = 0; static uint32_t SlaveCounter = 0;
static uint32_t us_ticker_int_counter = 0; static uint32_t oc_int_part = 0;
static uint16_t us_ticker_int_remainder = 0; static uint16_t oc_rem_part = 0;
void set_compare(uint16_t count) {
// Set new output compare value
TIM_SetCompare1(TIM_MST, count);
// Enable IT
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
}
// Used to increment the slave counter // Used to increment the slave counter
static void tim_update_irq_handler(void) { static void tim_update_irq_handler(void) {
@ -50,21 +57,24 @@ static void tim_update_irq_handler(void) {
// Used by interrupt system // Used by interrupt system
static void tim_oc_irq_handler(void) { static void tim_oc_irq_handler(void) {
uint16_t cval = TIM_MST->CNT;
// Clear interrupt flag // Clear interrupt flag
if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) { if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1); TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
} }
if (us_ticker_int_counter > 0) { if (oc_rem_part > 0) {
TIM_SetCompare1(TIM_MST, 0xFFFF); set_compare(oc_rem_part); // Finish the remaining time left
us_ticker_int_counter--; oc_rem_part = 0;
} else { }
if (us_ticker_int_remainder > 0) { else {
TIM_SetCompare1(TIM_MST, us_ticker_int_remainder); if (oc_int_part > 0) {
us_ticker_int_remainder = 0; set_compare(0xFFFF);
} else { oc_rem_part = cval; // To finish the counter loop the next time
// This function is going to disable the interrupts if there are oc_int_part--;
// no other events in the queue }
else {
us_ticker_irq_handler(); us_ticker_irq_handler();
} }
} }
@ -89,13 +99,12 @@ void us_ticker_init(void) {
// Configure interrupts // Configure interrupts
TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE);
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
// For 32-bit counter // Update interrupt used for 32-bit counter
NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)tim_update_irq_handler); NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)tim_update_irq_handler);
NVIC_EnableIRQ(TIM_MST_UP_IRQ); NVIC_EnableIRQ(TIM_MST_UP_IRQ);
// For ouput compare // Output compare interrupt used for timeout feature
NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)tim_oc_irq_handler); NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)tim_oc_irq_handler);
NVIC_EnableIRQ(TIM_MST_OC_IRQ); NVIC_EnableIRQ(TIM_MST_OC_IRQ);
@ -112,10 +121,10 @@ uint32_t us_ticker_read() {
// value in the past. Avoid this by computing consecutive values of the timer until they // value in the past. Avoid this by computing consecutive values of the timer until they
// are properly ordered. // are properly ordered.
counter = (uint32_t)(SlaveCounter << 16); counter = (uint32_t)(SlaveCounter << 16);
counter += (uint32_t)TIM_GetCounter(TIM_MST); counter += TIM_MST->CNT;
while (1) { while (1) {
counter2 = (uint32_t)(SlaveCounter << 16); counter2 = (uint32_t)(SlaveCounter << 16);
counter2 += (uint32_t)TIM_GetCounter(TIM_MST); counter2 += TIM_MST->CNT;
if (counter2 > counter) { if (counter2 > counter) {
break; break;
} }
@ -126,22 +135,21 @@ uint32_t us_ticker_read() {
void us_ticker_set_interrupt(unsigned int timestamp) { void us_ticker_set_interrupt(unsigned int timestamp) {
int delta = (int)(timestamp - us_ticker_read()); int delta = (int)(timestamp - us_ticker_read());
uint16_t cval = TIM_MST->CNT;
if (delta <= 0) { // This event was in the past if (delta <= 0) { // This event was in the past
us_ticker_irq_handler(); us_ticker_irq_handler();
return;
} }
else { else {
us_ticker_int_counter = (uint32_t)(delta >> 16); oc_int_part = (uint32_t)(delta >> 16);
us_ticker_int_remainder = (uint16_t)(delta & 0xFFFF); oc_rem_part = (uint16_t)(delta & 0xFFFF);
if (us_ticker_int_counter > 0) { // means delta > 0xFFFF if (oc_rem_part <= (0xFFFF - cval)) {
TIM_SetCompare1(TIM_MST, 0xFFFF); set_compare(cval + oc_rem_part);
us_ticker_int_counter--; oc_rem_part = 0;
} else { } else {
TIM_SetCompare1(TIM_MST, us_ticker_int_remainder); set_compare(0xFFFF);
us_ticker_int_remainder = 0; oc_rem_part = oc_rem_part - (0xFFFF - cval);
} }
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
} }
} }

View File

@ -37,8 +37,15 @@
static int us_ticker_inited = 0; static int us_ticker_inited = 0;
static uint32_t SlaveCounter = 0; static uint32_t SlaveCounter = 0;
static uint32_t us_ticker_int_counter = 0; static uint32_t oc_int_part = 0;
static uint16_t us_ticker_int_remainder = 0; static uint16_t oc_rem_part = 0;
void set_compare(uint16_t count) {
// Set new output compare value
TIM_SetCompare1(TIM_MST, count);
// Enable IT
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
}
// Used to increment the slave counter // Used to increment the slave counter
static void tim_update_irq_handler(void) { static void tim_update_irq_handler(void) {
@ -50,21 +57,24 @@ static void tim_update_irq_handler(void) {
// Used by interrupt system // Used by interrupt system
static void tim_oc_irq_handler(void) { static void tim_oc_irq_handler(void) {
uint16_t cval = TIM_MST->CNT;
// Clear interrupt flag // Clear interrupt flag
if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) { if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1); TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
} }
if (us_ticker_int_counter > 0) { if (oc_rem_part > 0) {
TIM_SetCompare1(TIM_MST, 0xFFFF); set_compare(oc_rem_part); // Finish the remaining time left
us_ticker_int_counter--; oc_rem_part = 0;
} else { }
if (us_ticker_int_remainder > 0) { else {
TIM_SetCompare1(TIM_MST, us_ticker_int_remainder); if (oc_int_part > 0) {
us_ticker_int_remainder = 0; set_compare(0xFFFF);
} else { oc_rem_part = cval; // To finish the counter loop the next time
// This function is going to disable the interrupts if there are oc_int_part--;
// no other events in the queue }
else {
us_ticker_irq_handler(); us_ticker_irq_handler();
} }
} }
@ -89,13 +99,12 @@ void us_ticker_init(void) {
// Configure interrupts // Configure interrupts
TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE);
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
// For 32-bit counter // Update interrupt used for 32-bit counter
NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)tim_update_irq_handler); NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)tim_update_irq_handler);
NVIC_EnableIRQ(TIM_MST_UP_IRQ); NVIC_EnableIRQ(TIM_MST_UP_IRQ);
// For ouput compare // Output compare interrupt used for timeout feature
NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)tim_oc_irq_handler); NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)tim_oc_irq_handler);
NVIC_EnableIRQ(TIM_MST_OC_IRQ); NVIC_EnableIRQ(TIM_MST_OC_IRQ);
@ -112,10 +121,10 @@ uint32_t us_ticker_read() {
// value in the past. Avoid this by computing consecutive values of the timer until they // value in the past. Avoid this by computing consecutive values of the timer until they
// are properly ordered. // are properly ordered.
counter = (uint32_t)(SlaveCounter << 16); counter = (uint32_t)(SlaveCounter << 16);
counter += (uint32_t)TIM_GetCounter(TIM_MST); counter += TIM_MST->CNT;
while (1) { while (1) {
counter2 = (uint32_t)(SlaveCounter << 16); counter2 = (uint32_t)(SlaveCounter << 16);
counter2 += (uint32_t)TIM_GetCounter(TIM_MST); counter2 += TIM_MST->CNT;
if (counter2 > counter) { if (counter2 > counter) {
break; break;
} }
@ -126,22 +135,21 @@ uint32_t us_ticker_read() {
void us_ticker_set_interrupt(unsigned int timestamp) { void us_ticker_set_interrupt(unsigned int timestamp) {
int delta = (int)(timestamp - us_ticker_read()); int delta = (int)(timestamp - us_ticker_read());
uint16_t cval = TIM_MST->CNT;
if (delta <= 0) { // This event was in the past if (delta <= 0) { // This event was in the past
us_ticker_irq_handler(); us_ticker_irq_handler();
return;
} }
else { else {
us_ticker_int_counter = (uint32_t)(delta >> 16); oc_int_part = (uint32_t)(delta >> 16);
us_ticker_int_remainder = (uint16_t)(delta & 0xFFFF); oc_rem_part = (uint16_t)(delta & 0xFFFF);
if (us_ticker_int_counter > 0) { // means delta > 0xFFFF if (oc_rem_part <= (0xFFFF - cval)) {
TIM_SetCompare1(TIM_MST, 0xFFFF); set_compare(cval + oc_rem_part);
us_ticker_int_counter--; oc_rem_part = 0;
} else { } else {
TIM_SetCompare1(TIM_MST, us_ticker_int_remainder); set_compare(0xFFFF);
us_ticker_int_remainder = 0; oc_rem_part = oc_rem_part - (0xFFFF - cval);
} }
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
} }
} }

View File

@ -31,7 +31,6 @@
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
// Timer selection: // Timer selection:
#define TIM_MST TIM1 #define TIM_MST TIM1
#define TIM_MST_UP_IRQ TIM1_UP_TIM10_IRQn #define TIM_MST_UP_IRQ TIM1_UP_TIM10_IRQn
#define TIM_MST_OC_IRQ TIM1_CC_IRQn #define TIM_MST_OC_IRQ TIM1_CC_IRQn
@ -41,8 +40,15 @@ static TIM_HandleTypeDef TimMasterHandle;
static int us_ticker_inited = 0; static int us_ticker_inited = 0;
static uint32_t SlaveCounter = 0; static uint32_t SlaveCounter = 0;
static uint32_t us_ticker_int_counter = 0; static uint32_t oc_int_part = 0;
static uint16_t us_ticker_int_remainder = 0; static uint16_t oc_rem_part = 0;
void set_compare(uint16_t count) {
// Set new output compare value
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, count);
// Enable IT
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
}
// Used to increment the slave counter // Used to increment the slave counter
static void tim_update_irq_handler(void) { static void tim_update_irq_handler(void) {
@ -55,21 +61,24 @@ static void tim_update_irq_handler(void) {
// Used by interrupt system // Used by interrupt system
static void tim_oc_irq_handler(void) { static void tim_oc_irq_handler(void) {
uint16_t cval = TIM_MST->CNT;
// Clear interrupt flag // Clear interrupt flag
if (__HAL_TIM_GET_ITSTATUS(&TimMasterHandle, TIM_IT_CC1) == SET) { if (__HAL_TIM_GET_ITSTATUS(&TimMasterHandle, TIM_IT_CC1) == SET) {
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1); __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
} }
if (us_ticker_int_counter > 0) { if (oc_rem_part > 0) {
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, 0xFFFF); set_compare(oc_rem_part); // Finish the remaining time left
us_ticker_int_counter--; oc_rem_part = 0;
} else { }
if (us_ticker_int_remainder > 0) { else {
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, us_ticker_int_remainder); if (oc_int_part > 0) {
us_ticker_int_remainder = 0; set_compare(0xFFFF);
} else { oc_rem_part = cval; // To finish the counter loop the next time
// This function is going to disable the interrupts if there are oc_int_part--;
// no other events in the queue }
else {
us_ticker_irq_handler(); us_ticker_irq_handler();
} }
} }
@ -89,31 +98,20 @@ void us_ticker_init(void) {
TimMasterHandle.Init.ClockDivision = 0; TimMasterHandle.Init.ClockDivision = 0;
TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TimMasterHandle.Init.RepetitionCounter = 0; TimMasterHandle.Init.RepetitionCounter = 0;
//HAL_TIM_Base_Init(&TimMasterHandle);
HAL_TIM_OC_Init(&TimMasterHandle); HAL_TIM_OC_Init(&TimMasterHandle);
/*
TIM_OC_InitTypeDef sConfig;
sConfig.OCMode = TIM_OCMODE_INACTIVE;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.Pulse = 0;
HAL_TIM_OC_ConfigChannel(&TimMasterHandle, &sConfig, TIM_CHANNEL_1);
*/
// Configure interrupts // Configure interrupts
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE); __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE);
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
// For 32-bit counter // Update interrupt used for 32-bit counter
NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)tim_update_irq_handler); NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)tim_update_irq_handler);
NVIC_EnableIRQ(TIM_MST_UP_IRQ); NVIC_EnableIRQ(TIM_MST_UP_IRQ);
// For ouput compare // Output compare interrupt used for timeout feature
NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)tim_oc_irq_handler); NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)tim_oc_irq_handler);
NVIC_EnableIRQ(TIM_MST_OC_IRQ); NVIC_EnableIRQ(TIM_MST_OC_IRQ);
// Enable timer // Enable timer
//HAL_TIM_Base_Start(&TimMasterHandle);
HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1); HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
} }
@ -140,22 +138,21 @@ uint32_t us_ticker_read() {
void us_ticker_set_interrupt(unsigned int timestamp) { void us_ticker_set_interrupt(unsigned int timestamp) {
int delta = (int)(timestamp - us_ticker_read()); int delta = (int)(timestamp - us_ticker_read());
uint16_t cval = TIM_MST->CNT;
if (delta <= 0) { // This event was in the past if (delta <= 0) { // This event was in the past
us_ticker_irq_handler(); us_ticker_irq_handler();
return;
} }
else { else {
us_ticker_int_counter = (uint32_t)(delta >> 16); oc_int_part = (uint32_t)(delta >> 16);
us_ticker_int_remainder = (uint16_t)(delta & 0xFFFF); oc_rem_part = (uint16_t)(delta & 0xFFFF);
if (us_ticker_int_counter > 0) { // means delta > 0xFFFF if (oc_rem_part <= (0xFFFF - cval)) {
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, 0xFFFF); set_compare(cval + oc_rem_part);
us_ticker_int_counter--; oc_rem_part = 0;
} else { } else {
__HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, us_ticker_int_remainder); set_compare(0xFFFF);
us_ticker_int_remainder = 0; oc_rem_part = oc_rem_part - (0xFFFF - cval);
} }
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
} }
} }

View File

@ -36,10 +36,19 @@
static int us_ticker_inited = 0; static int us_ticker_inited = 0;
static uint32_t SlaveCounter = 0; static uint32_t SlaveCounter = 0;
static uint32_t us_ticker_int_counter = 0; static uint32_t oc_int_part = 0;
static uint16_t us_ticker_int_remainder = 0; static uint16_t oc_rem_part = 0;
void set_compare(uint16_t count) {
// Set new output compare value
TIM_SetCompare1(TIM_MST, count);
// Enable IT
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
}
static void tim_update_oc_irq_handler(void) { static void tim_update_oc_irq_handler(void) {
uint16_t cval = TIM_MST->CNT;
// Update interrupt: increment the slave counter // Update interrupt: increment the slave counter
if (TIM_GetITStatus(TIM_MST, TIM_IT_Update) == SET) { if (TIM_GetITStatus(TIM_MST, TIM_IT_Update) == SET) {
TIM_ClearITPendingBit(TIM_MST, TIM_IT_Update); TIM_ClearITPendingBit(TIM_MST, TIM_IT_Update);
@ -49,18 +58,20 @@ static void tim_update_oc_irq_handler(void) {
// Output compare interrupt: used by interrupt system // Output compare interrupt: used by interrupt system
if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) { if (TIM_GetITStatus(TIM_MST, TIM_IT_CC1) == SET) {
TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1); TIM_ClearITPendingBit(TIM_MST, TIM_IT_CC1);
if (us_ticker_int_counter > 0) { }
TIM_SetCompare1(TIM_MST, 0xFFFF);
us_ticker_int_counter--; if (oc_rem_part > 0) {
} else { set_compare(oc_rem_part); // Finish the remaining time left
if (us_ticker_int_remainder > 0) { oc_rem_part = 0;
TIM_SetCompare1(TIM_MST, us_ticker_int_remainder); }
us_ticker_int_remainder = 0; else {
} else { if (oc_int_part > 0) {
// This function is going to disable the interrupts if there are set_compare(0xFFFF);
// no other events in the queue oc_rem_part = cval; // To finish the counter loop the next time
us_ticker_irq_handler(); oc_int_part--;
} }
else {
us_ticker_irq_handler();
} }
} }
} }
@ -84,7 +95,6 @@ void us_ticker_init(void) {
// Configure interrupts // Configure interrupts
TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE);
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
// For 32-bit counter and output compare // For 32-bit counter and output compare
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)tim_update_oc_irq_handler); NVIC_SetVector(TIM_MST_IRQ, (uint32_t)tim_update_oc_irq_handler);
@ -103,10 +113,10 @@ uint32_t us_ticker_read() {
// value in the past. Avoid this by computing consecutive values of the timer until they // value in the past. Avoid this by computing consecutive values of the timer until they
// are properly ordered. // are properly ordered.
counter = (uint32_t)(SlaveCounter << 16); counter = (uint32_t)(SlaveCounter << 16);
counter += (uint32_t)TIM_GetCounter(TIM_MST); counter += TIM_MST->CNT;
while (1) { while (1) {
counter2 = (uint32_t)(SlaveCounter << 16); counter2 = (uint32_t)(SlaveCounter << 16);
counter2 += (uint32_t)TIM_GetCounter(TIM_MST); counter2 += TIM_MST->CNT;
if (counter2 > counter) { if (counter2 > counter) {
break; break;
} }
@ -117,22 +127,21 @@ uint32_t us_ticker_read() {
void us_ticker_set_interrupt(unsigned int timestamp) { void us_ticker_set_interrupt(unsigned int timestamp) {
int delta = (int)(timestamp - us_ticker_read()); int delta = (int)(timestamp - us_ticker_read());
uint16_t cval = TIM_MST->CNT;
if (delta <= 0) { // This event was in the past if (delta <= 0) { // This event was in the past
us_ticker_irq_handler(); us_ticker_irq_handler();
return;
} }
else { else {
us_ticker_int_counter = (uint32_t)(delta >> 16); oc_int_part = (uint32_t)(delta >> 16);
us_ticker_int_remainder = (uint16_t)(delta & 0xFFFF); oc_rem_part = (uint16_t)(delta & 0xFFFF);
if (us_ticker_int_counter > 0) { // means delta > 0xFFFF if (oc_rem_part <= (0xFFFF - cval)) {
TIM_SetCompare1(TIM_MST, 0xFFFF); set_compare(cval + oc_rem_part);
us_ticker_int_counter--; oc_rem_part = 0;
} else { } else {
TIM_SetCompare1(TIM_MST, us_ticker_int_remainder); set_compare(0xFFFF);
us_ticker_int_remainder = 0; oc_rem_part = oc_rem_part - (0xFFFF - cval);
} }
TIM_ITConfig(TIM_MST, TIM_IT_CC1, ENABLE);
} }
} }