cancel
Showing results for 
Search instead for 
Did you mean: 

ADC DMA pointer issues

dweggg
Associate

Hello everyone,

First of all, I want to say that I have a very limited knowledge about C memory stuff, so a bit of guidance would be of help. I am trying to set up a timer-triggered multi channel ADC with DMA, which I have already succesfully achieved, but as I implement other pieces of code, the DMA buffer either fully stops or does very strange things like swapping around the positions of the channels. I have realized this because commenting out parts of the interrupt of the timer or setting up the ADC with another timer works, so I suspect I am doing something very wrong with pointers usage or variable declaration. I would like to ask for a bit of help figuring out what am I doing wrong. I'll attach the whole project for if anyone wants to take a closer look.

 

Thank you in advance! 🙂 Here are the code snippets

 

Here's the code ran just before the while(1) loop (invLeft is declared as extern and it's just a big struct holding everything).

 

 

 

inverterStruct invLeft = {0};

void inv_init(inverterStruct *inv, LED *led, GPIO_TypeDef *enable_port, uint16_t enable_pin, TIM_HandleTypeDef *htim, ADC_HandleTypeDef *hadc) {

// Initialize inverter structure

inv->state = INV_STATE_STARTUP;
inv->led = led;
inv->enable_pin = enable_pin;
inv->enable_port = enable_port;
inv->htim = htim;
inv->hadc = hadc;

inv->duties.Da = 0.5;
inv->duties.Db = 0.5;
inv->duties.Dc = 0.5;

HAL_TIM_Base_Start_IT(inv->htim); // Initializes Inverter timer with interrupt

HAL_ADC_Start_DMA(hadc, (uint32_t *) inv->ADC_raw,4); // Starts ADC DMA

enable_PWM(inv->htim);
}

 

 

Here's the interrupt code:

 

 

 

void TIM1_UP_TIM10_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */

/* USER CODE END TIM1_UP_TIM10_IRQn 0 */

HAL_TIM_IRQHandler(&htim1);

/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */

getADCelec(invLeft.ADC_raw, &invLeft.measurements);
calc_duties(&invLeft.duties); // this function should have more inputs using numbers makes the ADC work, calculating stuff does not
set_PWM(invLeft.htim, invLeft.duties);

/* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}

 

 

The functions called:

 

 

uint8_t getADCelec(volatile uint32_t* ADC_raw, volatile Measurements* measurements) {
// Calculate currents and voltage
float ia = getLinear(ADC_raw[0], CURRENT_SLOPE, CURRENT_OFFSET);
float ib = getLinear(ADC_raw[1], CURRENT_SLOPE, CURRENT_OFFSET);
float ic = getLinear(ADC_raw[2], CURRENT_SLOPE, CURRENT_OFFSET);
float VDC = getLinear(ADC_raw[3], VOLTAGE_SLOPE, VOLTAGE_OFFSET);
// Store the measurements
measurements->ia = ia;
measurements->ib = ib;
measurements->ic = ic;
measurements->VDC = VDC;

return 1; // Success

}

void calc_duties(Duties *duties) {

// irot_struct irot;
// irot.d = vd/vDC;
// irot.q = vq/vDC;
// irot.sinFi = sin(thetae);
// irot.cosFi = cos(thetae);
// irot_calc(&irot);

// svpwm_struct svpwm;
// Assign values to SVPWM structure
// svpwm.alpha = irot.alpha;
// svpwm.beta = irot.beta;
// svpwm_calc(&svpwm);

// Just use the constant numbers instead
duties->Da = 0.5F;
duties->Db = 0.5F;
duties->Dc = 0.5F;
}

void set_PWM(TIM_HandleTypeDef *htim, Duties duties) {
Compare3F_struct Compare = {0};
Compare.alphaA = 1.0F - duties.Da;
Compare.alphaB = 1.0F - duties.Db;
Compare.alphaC = 1.0F - duties.Dc;
Compare3F_calc(htim, &Compare);

htim->Instance->CCR1 = Compare.compA;
htim->Instance->CCR2 = Compare.compB;
htim->Instance->CCR3 = Compare.compC;
}

 

 

0 REPLIES 0