Add PWM control functionality

This commit is contained in:
2025-04-20 17:30:52 +02:00
parent 1a517299a0
commit 804bb33064
5 changed files with 104 additions and 12 deletions

View File

@ -37,7 +37,7 @@
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define TIM_BASE_FREQ 96000000UL
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
@ -51,6 +51,9 @@
/* Declare buffer in D1 domain SRAM */
static uint16_t adc_values[NUM_ADC_PINS];
static uint8_t dio_values[NUM_DIO_PINS];
// See mappings.h pwm_tim_t
TIM_HandleTypeDef* PWM_TIM_MAP[3] = {&htim1, &htim4, &htim3};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
@ -137,7 +140,16 @@ int main(void)
FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE) != HAL_OK)
Error_Handler();
// TODO: Add Filters and Rx Handler
FDCAN_FilterTypeDef filter;
filter.IdType = FDCAN_STANDARD_ID;
filter.FilterIndex = 0;
filter.FilterType = FDCAN_FILTER_MASK;
filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
filter.FilterID1 = 0x0DD;
filter.FilterID2 = 0x7FE; // Match 0x0DC and 0x0DD
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &filter) != HAL_OK)
Error_Handler();
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
Error_Handler();
@ -293,6 +305,51 @@ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
__asm volatile ("NOP");
}
}
void SetCCR(TIM_TypeDef* Instance, unsigned int ch, uint8_t dc) {
(&(Instance->CCR1))[ch] = dc;
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *handle, uint32_t RxFifo0ITs)
{
if (handle != &hfdcan1 || (RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) == RESET)
return;
static FDCAN_RxHeaderTypeDef header;
static uint8_t data[8];
if (HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &header, data) != HAL_OK)
return;
if (header.FDFormat != FDCAN_CLASSIC_CAN ||
header.RxFrameType != FDCAN_DATA_FRAME ||
header.IdType != FDCAN_STANDARD_ID)
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]);
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;
}
}
/* USER CODE END 4 */
/**