CAN bus bringup (everything works except PWM output)

This commit is contained in:
Oskar Winkels 2025-04-24 20:38:24 +02:00
parent 804bb33064
commit 778e0ae272
Signed by: o.winkels
GPG Key ID: E7484A06E99DAEF1
7 changed files with 147 additions and 24 deletions

File diff suppressed because one or more lines are too long

View File

@ -57,6 +57,10 @@ void PendSV_Handler(void);
void SysTick_Handler(void);
void DMA1_Stream0_IRQHandler(void);
void ADC_IRQHandler(void);
void FDCAN1_IT0_IRQHandler(void);
void FDCAN2_IT0_IRQHandler(void);
void FDCAN1_IT1_IRQHandler(void);
void FDCAN2_IT1_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */

View File

@ -53,9 +53,9 @@ void MX_FDCAN1_Init(void)
hfdcan1.Init.DataTimeSeg1 = 1;
hfdcan1.Init.DataTimeSeg2 = 1;
hfdcan1.Init.MessageRAMOffset = 0;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.StdFiltersNbr = 1;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.RxFifo0ElmtsNbr = 0;
hfdcan1.Init.RxFifo0ElmtsNbr = 16;
hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxFifo1ElmtsNbr = 0;
hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
@ -63,7 +63,7 @@ void MX_FDCAN1_Init(void)
hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.TxEventsNbr = 0;
hfdcan1.Init.TxBuffersNbr = 0;
hfdcan1.Init.TxFifoQueueElmtsNbr = 0;
hfdcan1.Init.TxFifoQueueElmtsNbr = 4;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
@ -101,9 +101,9 @@ void MX_FDCAN2_Init(void)
hfdcan2.Init.DataTimeSeg1 = 1;
hfdcan2.Init.DataTimeSeg2 = 1;
hfdcan2.Init.MessageRAMOffset = 0;
hfdcan2.Init.StdFiltersNbr = 0;
hfdcan2.Init.StdFiltersNbr = 1;
hfdcan2.Init.ExtFiltersNbr = 0;
hfdcan2.Init.RxFifo0ElmtsNbr = 0;
hfdcan2.Init.RxFifo0ElmtsNbr = 16;
hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan2.Init.RxFifo1ElmtsNbr = 0;
hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
@ -111,7 +111,7 @@ void MX_FDCAN2_Init(void)
hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan2.Init.TxEventsNbr = 0;
hfdcan2.Init.TxBuffersNbr = 0;
hfdcan2.Init.TxFifoQueueElmtsNbr = 0;
hfdcan2.Init.TxFifoQueueElmtsNbr = 4;
hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
@ -164,6 +164,11 @@ void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcanHandle)
GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* FDCAN1 interrupt Init */
HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
/* USER CODE BEGIN FDCAN1_MspInit 1 */
/* USER CODE END FDCAN1_MspInit 1 */
@ -201,6 +206,11 @@ void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcanHandle)
GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* FDCAN2 interrupt Init */
HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn);
HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn);
/* USER CODE BEGIN FDCAN2_MspInit 1 */
/* USER CODE END FDCAN2_MspInit 1 */
@ -227,6 +237,9 @@ void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* fdcanHandle)
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9);
/* FDCAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn);
HAL_NVIC_DisableIRQ(FDCAN1_IT1_IRQn);
/* USER CODE BEGIN FDCAN1_MspDeInit 1 */
/* USER CODE END FDCAN1_MspDeInit 1 */
@ -248,6 +261,9 @@ void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* fdcanHandle)
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);
/* FDCAN2 interrupt Deinit */
HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn);
HAL_NVIC_DisableIRQ(FDCAN2_IT1_IRQn);
/* USER CODE BEGIN FDCAN2_MspDeInit 1 */
/* USER CODE END FDCAN2_MspDeInit 1 */

View File

@ -111,6 +111,9 @@ int main(void)
MX_NVIC_Init();
/* USER CODE BEGIN 2 */
FDCAN_HandleTypeDef* hMainCAN = &hfdcan2;
//FDCAN_HandleTypeDef* hPeriCAN = &hfdcan1;
if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
Error_Handler();
@ -133,10 +136,10 @@ int main(void)
txHeader.TxFrameType = FDCAN_DATA_FRAME;
txHeader.DataLength = 8;
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
if (HAL_FDCAN_ActivateNotification(hMainCAN, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
Error_Handler();
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT,
if (HAL_FDCAN_ConfigGlobalFilter(hMainCAN, FDCAN_REJECT, FDCAN_REJECT,
FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE) != HAL_OK)
Error_Handler();
@ -148,12 +151,22 @@ int main(void)
filter.FilterID1 = 0x0DD;
filter.FilterID2 = 0x7FE; // Match 0x0DC and 0x0DD
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &filter) != HAL_OK)
if (HAL_FDCAN_ConfigFilter(hMainCAN, &filter) != HAL_OK)
Error_Handler();
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
if (HAL_FDCAN_Start(hMainCAN) != HAL_OK)
Error_Handler();
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
/* USER CODE END 2 */
/* Infinite loop */
@ -174,6 +187,9 @@ int main(void)
can_pkt_t* pktinfo = &(CAN_SIGNAL_MAP[pi]);
if (pktinfo->num_signals < 0)
continue;
if (mscounter % pktinfo->period == 0) {
txHeader.Identifier = pktinfo->can_id;
@ -206,7 +222,7 @@ int main(void)
}
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &txHeader, (uint8_t*) &txData) != HAL_OK)
if (HAL_FDCAN_AddMessageToTxFifoQ(hMainCAN, &txHeader, (uint8_t*) &txData) != HAL_OK)
Error_Handler();
}
@ -312,12 +328,15 @@ void SetCCR(TIM_TypeDef* Instance, unsigned int ch, uint8_t dc) {
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *handle, uint32_t RxFifo0ITs)
{
if (handle != &hfdcan1 || (RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) == RESET)
return;
FDCAN_HandleTypeDef* hMainCAN = &hfdcan2;
//FDCAN_HandleTypeDef* hPeriCAN = &hfdcan1;
if (handle != hMainCAN || (RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) == RESET)
return; // TODO: handle Peripheral CAN
static FDCAN_RxHeaderTypeDef header;
static uint8_t data[8];
if (HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &header, data) != HAL_OK)
if (HAL_FDCAN_GetRxMessage(hMainCAN, FDCAN_RX_FIFO0, &header, data) != HAL_OK)
return;
if (header.FDFormat != FDCAN_CLASSIC_CAN ||
@ -326,26 +345,39 @@ void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *handle, uint32_t RxFifo0ITs)
return;
switch (header.Identifier) {
case CAN_PWM_DC_ID:
uint8_t* dcs = data;
for (int i = 0; i < header.DataLength; i++) {
TIM_HandleTypeDef* htim = PWM_TIM_MAP[PWM_CH_MAP[i].tim];
SetCCR(htim->Instance, PWM_CH_MAP[i].ch, dcs[i]);
// TODO: This does not work, apparently they don't start in RESET
// Maybe have our own init bool array instead
// Manually enabling doesn't seem to work either
if (htim->ChannelState[PWM_CH_MAP[i].ch] == HAL_TIM_CHANNEL_STATE_RESET)
HAL_TIM_PWM_Start(htim, PWM_CH_MAP[i].ch << 2);
// MAYBE: Stop Timer when DC == 0 on all channels?
// HAL_TIM_PWM_Stop(htim, channel);
}
break;
case CAN_PWM_CONF_ID:
uint16_t* freqs = (uint16_t*) data;
for (int i = 0; i < (header.DataLength/2); i++) {
uint32_t prescaler = (TIM_BASE_FREQ / (255UL * freqs[i])); // cast?
PWM_TIM_MAP[i]->Instance->PSC = prescaler;
}
break;
default:
break;
}
}

View File

@ -57,6 +57,8 @@
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_adc1;
extern ADC_HandleTypeDef hadc1;
extern FDCAN_HandleTypeDef hfdcan1;
extern FDCAN_HandleTypeDef hfdcan2;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
@ -227,6 +229,62 @@ void ADC_IRQHandler(void)
/* USER CODE END ADC_IRQn 1 */
}
/**
* @brief This function handles FDCAN1 interrupt 0.
*/
void FDCAN1_IT0_IRQHandler(void)
{
/* USER CODE BEGIN FDCAN1_IT0_IRQn 0 */
/* USER CODE END FDCAN1_IT0_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan1);
/* USER CODE BEGIN FDCAN1_IT0_IRQn 1 */
/* USER CODE END FDCAN1_IT0_IRQn 1 */
}
/**
* @brief This function handles FDCAN2 interrupt 0.
*/
void FDCAN2_IT0_IRQHandler(void)
{
/* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */
/* USER CODE END FDCAN2_IT0_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan2);
/* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */
/* USER CODE END FDCAN2_IT0_IRQn 1 */
}
/**
* @brief This function handles FDCAN1 interrupt 1.
*/
void FDCAN1_IT1_IRQHandler(void)
{
/* USER CODE BEGIN FDCAN1_IT1_IRQn 0 */
/* USER CODE END FDCAN1_IT1_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan1);
/* USER CODE BEGIN FDCAN1_IT1_IRQn 1 */
/* USER CODE END FDCAN1_IT1_IRQn 1 */
}
/**
* @brief This function handles FDCAN2 interrupt 1.
*/
void FDCAN2_IT1_IRQHandler(void)
{
/* USER CODE BEGIN FDCAN2_IT1_IRQn 0 */
/* USER CODE END FDCAN2_IT1_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan2);
/* USER CODE BEGIN FDCAN2_IT1_IRQn 1 */
/* USER CODE END FDCAN2_IT1_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@ -46,9 +46,9 @@ void MX_TIM1_Init(void)
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.Prescaler = 753;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.Period = 255;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
@ -122,9 +122,9 @@ void MX_TIM3_Init(void)
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.Prescaler = 1203;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65535;
htim3.Init.Period = 255;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
@ -170,9 +170,9 @@ void MX_TIM4_Init(void)
/* USER CODE END TIM4_Init 1 */
htim4.Instance = TIM4;
htim4.Init.Prescaler = 0;
htim4.Init.Prescaler = 19;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 65535;
htim4.Init.Period = 255;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)

View File

@ -127,17 +127,23 @@ Dma.RequestsNb=1
FDCAN1.CalculateBaudRateNominal=500000
FDCAN1.CalculateTimeBitNominal=2000
FDCAN1.CalculateTimeQuantumNominal=125.0
FDCAN1.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,NominalPrescaler,NominalTimeSeg1,NominalTimeSeg2
FDCAN1.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,NominalPrescaler,NominalTimeSeg1,NominalTimeSeg2,RxFifo0ElmtsNbr,StdFiltersNbr,TxFifoQueueElmtsNbr
FDCAN1.NominalPrescaler=3
FDCAN1.NominalTimeSeg1=13
FDCAN1.NominalTimeSeg2=2
FDCAN1.RxFifo0ElmtsNbr=16
FDCAN1.StdFiltersNbr=1
FDCAN1.TxFifoQueueElmtsNbr=4
FDCAN2.CalculateBaudRateNominal=500000
FDCAN2.CalculateTimeBitNominal=2000
FDCAN2.CalculateTimeQuantumNominal=125.0
FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,NominalPrescaler,NominalTimeSeg1,NominalTimeSeg2
FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,NominalPrescaler,NominalTimeSeg1,NominalTimeSeg2,StdFiltersNbr,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr
FDCAN2.NominalPrescaler=3
FDCAN2.NominalTimeSeg1=13
FDCAN2.NominalTimeSeg2=2
FDCAN2.RxFifo0ElmtsNbr=16
FDCAN2.StdFiltersNbr=1
FDCAN2.TxFifoQueueElmtsNbr=4
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
@ -258,6 +264,10 @@ NVIC.ADC_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.DMA1_Stream0_IRQn=true\:0\:0\:false\:true\:true\:1\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.FDCAN1_IT0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.FDCAN1_IT1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.FDCAN2_IT0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.FDCAN2_IT1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false