-
Notifications
You must be signed in to change notification settings - Fork 10
Port Speed Controller Firmware to PlatformIO, Clean up, and Correct Driver Implementations #23
base: master
Are you sure you want to change the base?
Port Speed Controller Firmware to PlatformIO, Clean up, and Correct Driver Implementations #23
Conversation
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ | ||
/* Enable HSE in BYPASS mode (no crystal, oscillator bypassed by an external clock signal) */ | ||
/* On a Nucleo board, this external clock signal comes from the built-in ST Link */ | ||
RCC->CR |= (uint32_t)(RCC_CR_HSEBYP | RCC_CR_HSEON); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RCC_CR_HSEBYP
bit was not being set in the old default clock configuration generated by Kiel
TIM2->CR1 &= ~TIM_CR1_CKD; // Set the timer to use default clock division | ||
TIM2->CR1 |= TIM_CR1_OPM; // Set the timer to use one pulse mode | ||
|
||
TIM2->ARR = 10 * period - 1;// Set autoreload value to set the period |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adjusted this to assume and use a reset value of 0 instead of 1 for the timer counter. The hardware always uses a 0 reset.
|
||
/** Interrupt handler for Timer 2. | ||
static volatile int8_t timeoutFlag = FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be volatile since it is set from an interrupt service routine. It has also been made static, and a getter and setter pair have been added for this flag to be used by main.c.
/** | ||
* Get the timer timeout flag to see if the timer period has elapsed | ||
* | ||
* @returns The state of the timeout flag | ||
*/ | ||
uint8_t GetTimeoutFlag(void) | ||
{ | ||
return timeoutFlag; | ||
} | ||
|
||
/** | ||
* Stops the counter on the timer | ||
* Clear the timer timeout flag | ||
*/ | ||
void StopTimer(void){ | ||
TIM2->CR1 &= ~(0x1UL); //disable TIM2 | ||
|
||
void ClearTimeoutFlag(void) | ||
{ | ||
timeoutFlag = FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New getter and setter functions for timeoutFlag
. Now it can only be read and cleared by external code. Only the TIM2 ISR sets the flag.
|
||
TIM2->ARR = 10*period; //set autoreload to reset every period | ||
|
||
TIM2->CR1 &= (0x11UL << 8); //set the timer to use default clock division |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing ~
here, this has been corrected
SendInt(ADC_reading); | ||
#endif /* ADC_DEBUG */ | ||
|
||
#if ADC_REVERSE_READING |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New preprocessor flags!
// Enable capture/compare channels 1 and 2, other channels disabled and all polarities default | ||
TIM1->CCER = (TIM_CCER_CC2E | TIM_CCER_CC1E); | ||
|
||
TIM1->SMCR |= 0x3 << TIM_SMCR_SMS_Pos; // Set timer to encoder mode 3 (clocked by both TI1FP1 and TI2FP2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was an easy and rather significant mistake here - the STM32F1 reference manual specifies a value of '011' for the SMCR register SMS bitfield for encoder mode 3 (where edges of both encoder signals increment/decrement the timer counter). This is the mode we want. The '011' is binary (ie. = 0x3); however, it was entered in the code as hex 0x011 (= 0b0001_0001) instead.
Not only did this put the timer in encoder mode 1 instead of 3, it also changed the TS bitfield unintentionally. The effect of doing this for TIM1 is to enable the trigger output (TRGO signal) of TIM2 as a trigger source. By default it triggers a reset of the TIM1 counter (which tracks the encoder position). This is not good, because TIM2 is used to provide a countdown for the maximum time interval between speed control CAN messages. However, I think by default the TIM2 TRGO is configured to only assert upon software setting the UG bit in TIM2's register, which the software definitely isn't doing. Needs a bit more investigation.
GPIOC->CRL |= (0x4 << 24); //C6 | ||
|
||
//CAN receive setup | ||
VirtualComInit(BAUD_115200); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New baud 115200 instead of 9600
if (GetTimeoutFlag() == TRUE) | ||
{ | ||
#if PRINT_DEBUG | ||
SendString(", timout "); | ||
#endif /* PRINT_DEBUG */ | ||
|
||
#if SEND_CAN_MSG | ||
CANSend(&CAN_drive); | ||
#endif /* SEND_CAN_MSG */ | ||
|
||
ClearTimeoutFlag(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's where the new timeout flag getter and setter are used
static void sendMotorCommand(float curr, float vel); | ||
static void sendReverseToggle(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to bottom of file and made static
|
||
DBGMCU->CR |= DBGMCU_CR_DBG_TIM2_STOP; // Halt TIM2 upon debug halt | ||
|
||
TIM2->CR1 |= TIM_CR1_CEN; // Enable TIM2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enabling the timer should be the very last step of the initialization. This was corrected.
CAN1->FM1R |= 0x1C << 8; // Assign all filters to CAN1 | ||
CAN1->FMR |= 0x1UL; // Set to filter initialization mode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CAN1->FM1R |= 0x1C << 8
is supposed to be a write to CAN1->FMR
. Although it was done wrong, fortunately the FM1R register is locked until the next operation CAN1->FMR |= 0x1UL;
(enter filter initialization mode). So, it just did nothing rather than what it was supposed to do. This has been corrected.
int CANSetFilter(uint16_t id); | ||
int CANSetFilters(uint16_t *ids, uint8_t num); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added completion status return values
Towards the effort to debug the faulty accelerator pedal behaviour, this PR introduces several improvements to the Speed Controller (SCN) firmware that runs on one of the STM32 Nucleo boards on Daybreak's dashboard.
The following improvements were made:
static
type