Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MID/PWR to APP_CTRL development #65

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions firmware/Sources/HAL/HAL_PWM/hal_pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/**********************************************************************************/
/* Definition of local symbolic constants */
/**********************************************************************************/
#define MAX_DUTY 100000

#define MIN_PWM 96
/**********************************************************************************/
/* Definition of local function like macros */
Expand All @@ -36,6 +36,7 @@
/* Definition of local variables */
/**********************************************************************************/
static HRTIM_CompareCfgTypeDef pCompareCfg = {0};
uint32_t * max_steps;
/**********************************************************************************/
/* Definition of exported variables */
/**********************************************************************************/
Expand Down Expand Up @@ -70,6 +71,8 @@ HAL_PWM_result_e HAL_PwmInit(void){
EPC_ST_ERR_COUNTER = 0;
MX_HRTIM1_Init();
if (EPC_ST_ERR_COUNTER==0){
//get from hrtim the max value for the PWM counter
max_steps = (uint32_t*) &(hhrtim1.Instance->sTimerxRegs[0].PERxR);
res = HAL_PWM_RESULT_SUCCESS;
}
return res;
Expand All @@ -78,15 +81,15 @@ HAL_PWM_result_e HAL_PwmInit(void){

HAL_PWM_result_e HAL_PwmSetDuty(const uint32_t duty){
// Get the period of the timer, as will be the maximum value to compare
uint32_t max = hhrtim1.Instance->sTimerxRegs[0].PERxR;

uint32_t pwm_duty;
if (duty>MAX_DUTY){
if (duty>=HAL_PWM_MAX_DUTY){
// The maximum duty to apply is the period configured
pwm_duty = max -1;
pwm_duty = *max_steps -1;
}
//If duty is 0 no division is allow so duty has to be greater than 0
else if (duty>0){
pwm_duty = duty * max/MAX_DUTY - 1;
pwm_duty = duty * (*max_steps)/HAL_PWM_MAX_DUTY - 1; //duty * max maximum result is .9215e9 (ok in uint32)
}
else{
// Otherwise assigned directly to the pwm
Expand All @@ -98,6 +101,7 @@ HAL_PWM_result_e HAL_PwmSetDuty(const uint32_t duty){
}
// Write the value to compare in the register.
pCompareCfg.CompareValue = pwm_duty;
// pCompareCfg.CompareValue = 5007;
// Apply the compare configuration to the dessire timer unit in this case HRTIM-A1
HAL_PWM_result_e res = HAL_HRTIM_WaveformCompareConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, &pCompareCfg);;
return res;
Expand Down
2 changes: 1 addition & 1 deletion firmware/Sources/HAL/HAL_PWM/hal_pwm.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ typedef enum
/**********************************************************************************/
/* Definition of exported constant data */
/**********************************************************************************/

#define HAL_PWM_MAX_DUTY 100000 //steps of duty
/**********************************************************************************/
/* Declaration of exported function prototypes */
/**********************************************************************************/
Expand Down
192 changes: 192 additions & 0 deletions firmware/Sources/MID/MID_PWR/mid_pwr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/*********************************************************************************
* @file : mid_pwr.c
* @brief : Implementation of MID_PWR
***********************************************************************************/

/**********************************************************************************/
/* Include common and project definition header */
/**********************************************************************************/
#include "hal_pwm.h"
#include "hal_gpio.h"
#include "epc_conf.h"

/**********************************************************************************/
/* Include headers of the component */
/**********************************************************************************/
#include "mid_pwr.h"
#include "mid_reg.h"

/**********************************************************************************/
/* Include other headers */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of local symbolic constants */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of local function like macros */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of local types (typedef, enum, struct, union) */
/**********************************************************************************/

typedef enum{
SOA_ok = 0x0u,
SOA_over_pwr,
SOA_under_pwr
}SOA_e;
/**********************************************************************************/
/* Definition of exported constant data */
/**********************************************************************************/

/**********************************************************************************/
/* Declaration of local function prototypes */
/**********************************************************************************/
static MID_PWR_result_e _calculatePI(const int16_t ref, const int16_t meas,
const MID_PWR_Mode_e mode, const MID_REG_limit_s limits, int32_t * action);

static SOA_e _checkSOA(const int16_t I, const uint16_t V, const MID_REG_limit_s limits);
/**********************************************************************************/
/* Definition of local constant data */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of local variables */
/**********************************************************************************/
static uint16_t kp[3] = {6,0,0}, ki[3] = {5,0,0}; //TODO: EPC_CONF
static int32_t integral_value[3] = {0, 0, 0}; //I, V, P PI values
static uint8_t saturation_flag[3] = {0,0,0}; //I, V, P PI saturation flags
static uint32_t duty, d0 = 0; //action duty goes from 0 to 100000 (in m%)

/**********************************************************************************/
/* Definition of exported variables */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of imported variables */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of local functions */
/**********************************************************************************/
//TODO: rewrite
static SOA_e _checkSOA(const int16_t I, const uint16_t V, const MID_REG_limit_s limits){
SOA_e res = SOA_ok;
int16_t power = (int16_t)(((int32_t)I * (int32_t)V) /100000); // 10^-3(mW) *10^-3 (mW) / 10^-5 -> dW
if (power > limits.lsPwrMax)
res = SOA_over_pwr;
else if (power < limits.lsPwrMin)
res = SOA_under_pwr;
return res;
}

//TODO: rewrite
/**
* @fn MID_PWR_result_t SetLeds()
* @brief Set the leds to the state indicated by the input
* @param state, 8bit input but only needed the last 4 bits as there are only 4 leds
* @return @ref MID_PWR_RESULT_SUCCESS if measured correctly,
* @ref MID_PWR_RESULT_BUSY, @ref MID_PWR_RESULT_TIMEOUT or
* @ref MID_PWR_RESULT_ERROR otherwise.
*/
static MID_PWR_result_e _calculatePI(const int16_t ref, const int16_t meas, const MID_PWR_Mode_e mode,
const MID_REG_limit_s limits, int32_t * action){

// Get values for the specific PI
int32_t upper_limit, lower_limit; //int32 because of duty
int32_t error = ref - meas;

// set limits for saturation
if (mode != MID_PWR_MODE_CC){ //out for pwr or v PI is allways current
upper_limit = limits.lsCurrMax ;
lower_limit = limits.lsCurrMin ;
}else{ // for i PI actions is the deltaDuty to apply
upper_limit = HAL_PWM_MAX_DUTY - d0;
lower_limit= - d0;
}

// check if already saturated
if(saturation_flag[mode]){
integral_value[mode] += error;
}

//set new action
*action = kp[mode] * error + ki[mode] * integral_value[mode];

// check action and saturate if needed
if(*action > upper_limit){
*action = upper_limit;
saturation_flag[mode] = 1;
}else if(*action < lower_limit){
*action = lower_limit;
saturation_flag[mode] = 1;
}else{
saturation_flag[mode] = 0;
}

return MID_PWR_RESULT_SUCCESS;
}

/**********************************************************************************/
/* Definition of exported functions */
/**********************************************************************************/

MID_PWR_result_e MID_PwrSetOutput(const MID_PWR_Output_e outputMode){
MID_PWR_result_e res = MID_PWR_RESULT_ERROR;
res = (MID_PWR_result_e) HAL_GpioSet(HAL_GPIO_OUT_OutDisable, outputMode);
return res;
}

MID_PWR_result_e MID_PwrApplyCtrl(const int16_t ref, const uint16_t V_LS, const int16_t I_LS, const MID_PWR_Mode_e control_mode, const MID_REG_limit_s limits){
MID_PWR_result_e res = MID_PWR_RESULT_ERROR;
int32_t curr_ref, delta_duty;
int16_t actual_power;
switch (control_mode) { //first PI, if needed (in Pwr and V refs)
case MID_PWR_MODE_CP:
actual_power = (int16_t)(((int32_t)I_LS * (int32_t)V_LS) /100); // dW
res = _calculatePI(ref, actual_power, MID_PWR_MODE_CP, limits, &curr_ref);
break;
case MID_PWR_MODE_CV:
res = _calculatePI(ref, V_LS, MID_PWR_MODE_CV, limits, &curr_ref);
break;
case MID_PWR_MODE_CC: //not first PI needed.
curr_ref = ref;
res = MID_PWR_RESULT_SUCCESS;
break;
default:
res = MID_PWR_RESULT_ERROR;
}
if (res == MID_PWR_RESULT_SUCCESS){

// I action at this point is allways under the limits. The pwr and V PI saturate the action
// and I ref from APP_CTRL is allways in limit

SOA_e SOA_status = _checkSOA(curr_ref, V_LS, limits);
if (SOA_status == SOA_over_pwr){
curr_ref = (int32_t)(limits.lsPwrMax*100) / V_LS;
}
else if (SOA_status == SOA_under_pwr){
curr_ref = (int32_t)(limits.lsPwrMin*100) / V_LS;
}
// calculate current PI
res = _calculatePI(curr_ref, I_LS, MID_PWR_MODE_CC, limits, &delta_duty);
if (res == MID_PWR_RESULT_SUCCESS){
duty = delta_duty + d0;
res = (MID_PWR_result_e) HAL_PwmSetDuty(duty);
}
}

return res;
}

MID_PWR_result_e MID_PwrCalculateD0(const uint16_t V_HS, const uint16_t V_LS){
MID_PWR_result_e res = MID_PWR_RESULT_ERROR;
uint32_t new_d0 = V_LS * HAL_PWM_MAX_DUTY / V_HS;
if (new_d0 <= HAL_PWM_MAX_DUTY && new_d0 >= 0){
d0 = new_d0;
res = MID_PWR_RESULT_SUCCESS;
}
return res;
}
114 changes: 114 additions & 0 deletions firmware/Sources/MID/MID_PWR/mid_pwr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*********************************************************************************
* @file : mid_pwr.h
* @brief : Middleware header file for Device ABStraction
***********************************************************************************/

#ifndef MID_PWR_H_
#define MID_PWR_H_

/**********************************************************************************/
/* Project Includes */
/**********************************************************************************/
#include "mid_reg.h"
/**********************************************************************************/
/* Include other headers */
/**********************************************************************************/
#include <stdint.h>

/**********************************************************************************/
/* Definition of local symbolic constants */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of local function like macros */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of exported types (typedef, enum, struct, union) */
/**********************************************************************************/
/**
* @enum MID_PWR_meas_e
* @brief Enum of available outputs for MID_PWR.
*
*/
typedef enum {
MID_PWR_Disable = 0x00U,
MID_PWR_Enable = 0x01U
}MID_PWR_Output_e;

/**
* @enum MID_PWR_Mode_e
* @brief Enum of available control modes for MID_PWR.
*
*/
typedef enum{
MID_PWR_MODE_CC = 0x0u,
MID_PWR_MODE_CV,
MID_PWR_MODE_CP,
MID_PWR_COUNT
}MID_PWR_Mode_e;

/**
* @enum MID_PWR_result_e
* @brief Structure of available response values for MID_PWR operations.
*
*/
typedef enum
{
MID_PWR_RESULT_SUCCESS = 0x0U, /**< MID_PWR_RESULT_SUCCESS success operation result */
MID_PWR_RESULT_ERROR = 0x1U, /**< MID_PWR_RESULT_ERROR error operation result */
MID_PWR_RESULT_BUSY = 0x2U, /**< MID_PWR_RESULT_ERROR busy operation result */
MID_PWR_RESULT_TIMEOUT = 0x3U, /**< MID_PWR_RESULT_ERROR timeout operation result */
} MID_PWR_result_e;

/**********************************************************************************/
/* Definition of exported variables */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of local constant data */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of exported variables */
/**********************************************************************************/

/**********************************************************************************/
/* Definition of exported constant data */
/**********************************************************************************/

/**********************************************************************************/
/* Declaration of exported function prototypes */
/**********************************************************************************/
//TODO: rewrite
/**
* @fn MID_PWR_result_e MID_PwrSetOutput(const MID_PWR_Output_e outputMode)
* @brief Enable or disable the output pwr.
* @param outputMode Input variable to use to set the mode
* @return @ref MID_PWR_RESULT_SUCCESS if set correctly,
* @ref MID_PWR_RESULT_BUSY, @ref MID_PWR_RESULT_TIMEOUT or
* @ref MID_PWR_RESULT_ERROR otherwise.
*/
MID_PWR_result_e MID_PwrSetOutput(const MID_PWR_Output_e outputMode);
//TODO: rewrite
/**
* @fn MID_PWR_result_e MID_PwrApplyPI(const uint16_t ref, const uint16_t actual_value, const MID_PWR_Mode_e, const XXXX limits)
* @brief Enable or disable the output pwr.
* @param outputMode Input variable to use to set the mode
* @return @ref MID_PWR_RESULT_SUCCESS if set correctly,
* @ref MID_PWR_RESULT_BUSY, @ref MID_PWR_RESULT_TIMEOUT or
* @ref MID_PWR_RESULT_ERROR otherwise.
*/
MID_PWR_result_e MID_PwrApplyCtrl(const int16_t ref, const uint16_t V_LS, const int16_t I_LS, const MID_PWR_Mode_e control_mode, const MID_REG_limit_s limits);
//TODO: rewrite
/**
* @fn MID_PWR_result_e MID_PwrCalculateD0(const uint16_t V_HS, const uint16_t V_LS)
* @brief Enable or disable the output pwr.
* @param outputMode Input variable to use to set the mode
* @return @ref MID_PWR_RESULT_SUCCESS if set correctly,
* @ref MID_PWR_RESULT_BUSY, @ref MID_PWR_RESULT_TIMEOUT or
* @ref MID_PWR_RESULT_ERROR otherwise.
*/
MID_PWR_result_e MID_PwrCalculateD0(const uint16_t V_HS, const uint16_t V_LS);

#endif /* MID_PWR_H_ */
Loading