Skip to content

Commit

Permalink
#8 gatedriver pwm (#31)
Browse files Browse the repository at this point in the history
* Added some pulse-setting functionality

* Fixed signature and variable name typos

* Switched to float array duty cycle parameter

* Fixed signature and removed TODOs

* Moved PWM config to gatedrive struct

* Added mutex for timer

* Fixed typo

---------

Co-authored-by: Ethan Parab <[email protected]>
  • Loading branch information
nwdepatie and MandarinPine18 authored Mar 12, 2024
1 parent f9519d1 commit b03aef8
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 34 deletions.
11 changes: 7 additions & 4 deletions CM7/Core/Inc/gatedriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,22 @@ enum phase{
};

typedef struct {
I2C_HandleTypeDef* hi2c;
TIM_HandleTypeDef* tim;
osMutexId_t* tim_mutex;
TIM_OC_InitTypeDef* pPWMConfig;
uint32_t pulses[];
} gatedriver_t;

gatedriver_t* gatedrv_init(/*TODO: Pass hardware interfaces*/);
gatedriver_t* gatedrv_init(TIM_HandleTypeDef* tim);

int16_t gatedrv_read_dc_voltage(gatedriver_t* drv);

int16_t gatedrv_read_dc_current(gatedriver_t* drv);

/* Note: This has to atomically write to ALL PWM registers */
//TODO: mechanism for PWM synchronization
int16_t gatedrv_write_pwm(gatedriver_t* drv);
int16_t gatedrv_write_pwm(gatedriver_t* drv, float duty_cycles[]);

int16_t gatedrv_read_igbt_temp(gatedriver_t* drv);

#endif /* GATEDRIVER_H */
#endif /* GATEDRIVER_H */
119 changes: 89 additions & 30 deletions CM7/Core/Src/gatedriver.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <stdlib.h>
#include <string.h>

#define PERIOD_VALUE (uint32_t)(2000 - 1)

const static osMutexAttr_t gatedrv_tim_mutex_attr;

//TODO: Look up STM callback func pointer for ADCs
static void gatedrv_current_adc_cb(gatedriver_t* drv)
{
Expand All @@ -31,41 +35,43 @@ static void gatedrv_fault_cb(gatedriver_t* drv)

}

gatedriver_t* gatedrv_init()
gatedriver_t* gatedrv_init(TIM_HandleTypeDef* tim)
{
//TODO: Assert hardware params
//assert(hi2c);
//assert(accel_adc1);
//assert(accel_adc2);
//assert(brake_adc);
//assert(led_gpio);
//assert(watchdog_gpio);
/* Assert hardware params */
assert(tim);

/* Create MPU struct */
gatedriver_t* gatedriver = malloc(sizeof(gatedriver_t));
assert(gatedriver);

//TODO: Set interfaces
//mpu->hi2c = hi2c;
//mpu->accel_adc1 = accel_adc1;
//mpu->accel_adc2 = accel_adc2;
//mpu->brake_adc = brake_adc;
//mpu->led_gpio = led_gpio;
//mpu->watchdog_gpio = watchdog_gpio;

//TODO: Init hardware
/* Initialize the Onboard Temperature Sensor */
//mpu->temp_sensor = malloc(sizeof(sht30_t));
//assert(mpu->temp_sensor);
//mpu->temp_sensor->i2c_handle = hi2c;
//assert(!sht30_init(mpu->temp_sensor)); /* This is always connected */

//TODO: Init Mutexes
/* Set interfaces */
gatedriver->tim = tim;

/* Init hardware */
tim->Init.Prescaler = 0;
tim->Init.Period = PERIOD_VALUE;
tim->Init.ClockDivision = 0;
tim->Init.CounterMode = TIM_COUNTERMODE_UP;
tim->Init.RepetitionCounter = 0;
if(HAL_TIM_PWM_Init(tim) != HAL_OK) {
// TODO: how to handle this error?
}

/* Common configuration for all PWM channels */
TIM_OC_InitTypeDef PWMConfig;
PWMConfig.OCMode = TIM_OCMODE_PWM1;
PWMConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
PWMConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
PWMConfig.OCIdleState = TIM_OCIDLESTATE_SET;
PWMConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
PWMConfig.OCFastMode = TIM_OCFAST_DISABLE;
gatedriver->pPWMConfig = &PWMConfig;

/* Create Mutexes */
//mpu->i2c_mutex = osMutexNew(&mpu_i2c_mutex_attr);
//assert(mpu->i2c_mutex);
gatedriver->tim_mutex = osMutexNew(&gatedrv_tim_mutex_attr);
assert(gatedriver->tim_mutex);

//TODO: Link interrupts to callbacks
//TODO: Link interrupts to callbacks

return gatedriver;
}
Expand All @@ -81,10 +87,63 @@ int16_t gatedrv_read_dc_current(gatedriver_t* drv)
}

/* Note: This has to atomically write to ALL PWM registers */
//TODO: mechanism for PWM synchronization
int16_t gatedrv_write_pwm(gatedriver_t* drv)
int16_t gatedrv_write_pwm(gatedriver_t* drv, float duty_cycles[])
{

/* Acquiring mutex lock */
osStatus_t mut_stat = osMutexAcquire(drv->tim_mutex, osWaitForever);
if (mut_stat) {
return mut_stat;
}

/* Computing pulses */
uint32_t pulses[3];
pulses[0] = (uint32_t) (duty_cycles[0] * PERIOD_VALUE / 100);
pulses[1] = (uint32_t) (duty_cycles[1] * PERIOD_VALUE / 100);
pulses[2] = (uint32_t) (duty_cycles[2] * PERIOD_VALUE / 100);

/* Getting PWM channel config */
TIM_OC_InitTypeDef* config = drv->pPWMConfig;

/* Attempting to set channel 1 */
config->Pulse = pulses[0];
if(HAL_TIM_PWM_ConfigChannel(drv->tim, config, TIM_CHANNEL_1) != HAL_OK)
{
/* Do nothing and return */
return 1;
}

/* Attempting to set channel 2 */
config->Pulse = pulses[1];
if(HAL_TIM_PWM_ConfigChannel(drv->tim, config, TIM_CHANNEL_2) != HAL_OK)
{
/* Attempt to revert last channel change and return */
config->Pulse = drv->pulses[0];
HAL_TIM_PWM_ConfigChannel(drv->tim, config, TIM_CHANNEL_1);

return 1;
}

/* Attempting to set channel 3 */
config->Pulse = pulses[2];
if(HAL_TIM_PWM_ConfigChannel(drv->tim, config, TIM_CHANNEL_3) != HAL_OK)
{
/* Attempt to revert previous channel changes and return */
config->Pulse = drv->pulses[0];
HAL_TIM_PWM_ConfigChannel(drv->tim, config, TIM_CHANNEL_1);

config->Pulse = drv->pulses[1];
HAL_TIM_PWM_ConfigChannel(drv->tim, config, TIM_CHANNEL_2);

return 1;
}

/* Successful PWM modifications - save configuration, release mutex, and return */
drv->pulses[0] = pulses[0];
drv->pulses[1] = pulses[1];
drv->pulses[2] = pulses[2];

osMutexRelease(drv->tim_mutex);
return 0;
}

int16_t gatedrv_read_igbt_temp(gatedriver_t* drv)
Expand Down

0 comments on commit b03aef8

Please sign in to comment.