work on current sense

This commit is contained in:
2023-11-09 18:50:34 -05:00
parent e76815fb03
commit c1d45aa443
18 changed files with 2324 additions and 1938 deletions

View File

@@ -29,15 +29,11 @@ void MX_ADC1_Init(void)
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
SIMPLEFOC_DEBUG("HAL ADC1 Init fail.");
}
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
SIMPLEFOC_DEBUG("HAL ADC1 Multimode configuration fail.");
}
SIMPLEFOC_DEBUG("HAL ADC1 multimode configuration fail.");
sConfig.Channel = ADC_CHANNEL_VOPAMP1;
sConfig.Rank = ADC_REGULAR_RANK_1;
@@ -46,9 +42,12 @@ void MX_ADC1_Init(void)
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
SIMPLEFOC_DEBUG("HAL ADC OPAMP1 init failed!");
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR_ADC1;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
SIMPLEFOC_DEBUG("HAL ADC temp init failed!");
}
void MX_ADC2_Init(void)
@@ -72,9 +71,7 @@ void MX_ADC2_Init(void)
hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc2.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
SIMPLEFOC_DEBUG("HAL ADC2 init failed!");
sConfig.Channel = ADC_CHANNEL_VOPAMP2;
sConfig.Rank = ADC_REGULAR_RANK_1;
@@ -83,19 +80,15 @@ void MX_ADC2_Init(void)
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
SIMPLEFOC_DEBUG("HAL ADC OPAMP2 init failed!");
sConfig.Channel = ADC_CHANNEL_VOPAMP3_ADC2;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
SIMPLEFOC_DEBUG("HAL ADC OPAMP3 init failed!");
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
void ADC_DMA_Init(ADC_HandleTypeDef* adcHandle)
{
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
@@ -165,25 +158,25 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
}
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{
// void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
// {
if(adcHandle->Instance==ADC1)
{
HAL_RCC_ADC12_CLK_ENABLED--;
if(HAL_RCC_ADC12_CLK_ENABLED==0){
__HAL_RCC_ADC12_CLK_DISABLE();
}
// if(adcHandle->Instance==ADC1)
// {
// HAL_RCC_ADC12_CLK_ENABLED--;
// if(HAL_RCC_ADC12_CLK_ENABLED==0){
// __HAL_RCC_ADC12_CLK_DISABLE();
// }
HAL_DMA_DeInit(adcHandle->DMA_Handle);
}
else if(adcHandle->Instance==ADC2)
{
HAL_RCC_ADC12_CLK_ENABLED--;
if(HAL_RCC_ADC12_CLK_ENABLED==0){
__HAL_RCC_ADC12_CLK_DISABLE();
}
// HAL_DMA_DeInit(adcHandle->DMA_Handle);
// }
// else if(adcHandle->Instance==ADC2)
// {
// HAL_RCC_ADC12_CLK_ENABLED--;
// if(HAL_RCC_ADC12_CLK_ENABLED==0){
// __HAL_RCC_ADC12_CLK_DISABLE();
// }
HAL_DMA_DeInit(adcHandle->DMA_Handle);
}
}
// HAL_DMA_DeInit(adcHandle->DMA_Handle);
// }
// }

View File

@@ -1,12 +1,9 @@
#ifndef __ADC_H__
#define __ADC_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32g4xx_hal.h"
#include "stm32g4xx_hal_adc.h"
#include "communication/SimpleFOCDebug.h"
extern ADC_HandleTypeDef hadc1;
extern ADC_HandleTypeDef hadc2;
@@ -15,11 +12,7 @@ extern DMA_HandleTypeDef hdma_adc2;
void MX_ADC1_Init(void);
void MX_ADC2_Init(void);
#ifdef __cplusplus
}
#endif
void ADC_DMA_Init(ADC_HandleTypeDef* adcHandle);
#endif

View File

@@ -4,6 +4,7 @@ void MX_DMA_Init(void)
{
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
@@ -11,6 +12,11 @@ void MX_DMA_Init(void)
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
RCC_PeriphCLKInitTypeDef PeriphClkInit;
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
}
extern "C" {

View File

@@ -1,20 +1,13 @@
#ifndef __DMA_H__
#define __DMA_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stm32g4xx_hal.h>
#include <stm32g4xx_hal_dma.h>
#include "stm32g4xx_hal.h"
#include "stm32g4xx_hal_dma.h"
extern DMA_HandleTypeDef hdma_adc1;
extern DMA_HandleTypeDef hdma_adc2;
void MX_DMA_Init(void);
void DMA1_Channel1_IRQHandler(void);
void DMA2_Channel2_IRQHandler(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -4,7 +4,7 @@ OPAMP_HandleTypeDef hopamp1;
OPAMP_HandleTypeDef hopamp2;
OPAMP_HandleTypeDef hopamp3;
void opamp_init(OPAMP_HandleTypeDef *hopamp, OPAMP_TypeDef *opamp)
void initOPAMP(OPAMP_HandleTypeDef *hopamp, OPAMP_TypeDef *opamp)
{
hopamp1.Instance = opamp;
hopamp1.Init.PowerMode = OPAMP_POWERMODE_NORMALSPEED;
@@ -15,17 +15,15 @@ void opamp_init(OPAMP_HandleTypeDef *hopamp, OPAMP_TypeDef *opamp)
hopamp1.Init.PgaConnect = OPAMP_PGA_CONNECT_INVERTINGINPUT_NO;
hopamp1.Init.PgaGain = OPAMP_PGA_GAIN_16_OR_MINUS_15; // Adjust this to change the gains of the opamp.
hopamp1.Init.UserTrimming = OPAMP_TRIMMING_FACTORY;
if (HAL_OPAMP_Init(&hopamp) != HAL_OK)
{
Error_Handler();
}
if (HAL_OPAMP_Init(hopamp) != HAL_OK)
SIMPLEFOC_DEBUG("HAL OPAMP Init failed!");
}
void configureOPAMPs(void)
{
opamp_init(&hopamp1, OPAMP1); // PA3
opamp_init(&hopamp2, OPAMP2); // PB0
opamp_init(&hopamp3, OPAMP3); // PA1
initOPAMP(&hopamp1, OPAMP1); // PA3
initOPAMP(&hopamp2, OPAMP2); // PB0
initOPAMP(&hopamp3, OPAMP3); // PA1
}
void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef* opampHandle)

View File

@@ -1,22 +1,19 @@
#ifndef __OPAMP_H__
#define __OPAMP_H__
#ifdef __cplusplus
extern "C" {
#endif
#if defined(SIMPLEFOC_STM32_CUSTOMCURRENTSENSE)
#include "stm32g4xx_hal.h"
#include "stm32g4xx_hal_opamp.h"
#include "communication/SimpleFOCDebug.h"
extern OPAMP_HandleTypeDef hopamp1;
extern OPAMP_HandleTypeDef hopamp2;
extern OPAMP_HandleTypeDef hopamp3;
void configureOPAMP(void);
void configureOPAMPs(void);
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@@ -1,97 +0,0 @@
#if
#include "adc.h"
#include "opamp.h"
#include "dma.h"
#include "Arduino-FOC/src/current_sense/hardware_api.h"
#include "Arduino-FOC/src/current_sense/hardware_specific/stm32_mcu.h"
#include "Arduino-FOC/src/drivers/hardware_specific/stm32/stm32_mcu.h"
#include "communication/SimpleFOCDebug.h"
float adcResolution = 4096.0f; // 12 bit ADC
float voltageScale = 3.3f; // full scale voltage range of ADC
float adcSens = adcResolution * voltageScale
volatile uint16_t adc1Result[2] = {0};
volatile uint16_t adc2Result[2] = {0};
float adcSens = 3.3f * 1.440f / 4096.0f;
float _readVoltageInline(const uint8_t pin, const void *cs_params)
{
switch (pin)
{
case PA3:
return adc1Result[0]; // ADC1 CH13 -> Vopamp1 internal output
break;
case PB0:
return adc2Result[0]; //ADC2 CH16 -> Vopamp2 internal output
break;
case PA1:
return adc2Result[1]; //ADC2 CH18 -> Vopamp3 internal output
break;
case TS:
return adc1Result[1];
break;
default:
return 0.0f;
break;
}
}
float _readVoltageLowSide(const int pinA, const void* cs_params){
return 0.0f;
}
void* _configureADCInline(const void *driver_params, const int pinA, const int pinB, const int pinC)
{
_UNUSED(driver_params);
HAL_Init();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init(&hadc1);
MX_ADC2_Init(&hadc2);
configureOPAMPs();
MX_DMA1_Init(&hadc1, &hdma_adc1, DMA1_Channel1, DMA_REQUEST_ADC1);
MX_DMA1_Init(&hadc2, &hdma_adc2, DMA1_Channel2, DMA_REQUEST_ADC2);
if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc1Result, 1) != HAL_OK)
{
SIMPLEFOC_DEBUG("DMA1 read init failed");
}
if (HAL_ADC_Start_DMA(&hadc2, (uint32_t *)adc2Result, 2) != HAL_OK)
{
SIMPLEFOC_DEBUG("DMA2 read init failed");
}
HAL_OPAMP_Start(&hopamp1);
HAL_OPAMP_Start(&hopamp2);
HAL_OPAMP_Start(&hopamp3);
Stm32CurrentSenseParams *params = new Stm32CurrentSenseParams{
.pins = {pinA, pinB, pinC},
.adc_voltage_conv = adcSens,
.timer_handle = (HardwareTimer *)(HardwareTimer_Handle[get_timer_index(TIM3)]->__this)};
return params;
}
void* _configureADCLowSide(const void *driver_params, const int pinA, const int pinB, const int pinC)
{
_UNUSED(driver_params);
_UNUSED(pinA);
_UNUSED(pinB);
_UNUSED(pinC);
SIMPLEFOC_DEBUG("Lemon-Pepper does not use lowside sensing. Use inline current sense instead.");
return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
}
void _driverSyncLowSide(void* driver_params, void* cs_params){
}

View File

@@ -0,0 +1,124 @@
#if defined(SIMPLEFOC_STM32_CUSTOMCURRENTSENSE)
#include "utils.h"
#include "adc.h"
#include "dma.h"
#include "opamp.h"
float adcResolution = 4096.0f; // 12 bit ADC
float voltageScale = 3.3f; // full scale voltage range of ADC
float adcSens = adcResolution * voltageScale;
volatile uint16_t adc1Result[2] = {0};
volatile uint16_t adc2Result[2] = {0};
void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_ADC12_CLK_ENABLE();
}
float _readVoltageInline(const uint8_t pin, const void *cs_params)
{
uint32_t rawResult;
switch (pin)
{
case PA3:
rawResult = adc1Result[0]; // ADC1 CH13 -> Vopamp1 internal output
break;
case PB0:
rawResult = adc2Result[0]; // ADC2 CH16 -> Vopamp2 internal output
break;
case PA1:
rawResult = adc2Result[1]; // ADC2 CH18 -> Vopamp3 internal output
break;
case PA2:
rawResult = adc1Result[1]; // ADC1 CH16 -> not sure what pin should represent this?
break;
default:
return 0.0f;
break;
}
return rawResult * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv;
}
float _readVoltageLowSide(const int pinA, const void *cs_params)
{
return 0.0f;
}
void *_configureADCInline(const void *driver_params, const int pinA, const int pinB, const int pinC)
{
_UNUSED(driver_params);
HAL_Init();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_ADC2_Init();
configureOPAMPs();
ADC_DMA_Init(&hadc1);
ADC_DMA_Init(&hadc2);
if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc1Result, 1) != HAL_OK)
{
SIMPLEFOC_DEBUG("DMA1 read init failed");
}
if (HAL_ADC_Start_DMA(&hadc2, (uint32_t *)adc2Result, 2) != HAL_OK)
{
SIMPLEFOC_DEBUG("DMA2 read init failed");
}
HAL_OPAMP_Start(&hopamp1);
HAL_OPAMP_Start(&hopamp2);
HAL_OPAMP_Start(&hopamp3);
Stm32CurrentSenseParams *params = new Stm32CurrentSenseParams{
.pins = {pinA, pinB, pinC},
.adc_voltage_conv = adcSens,
.timer_handle = (HardwareTimer *)(HardwareTimer_Handle[get_timer_index(TIM2)]->__this)};
return params;
}
void *_configureADCLowSide(const void *driver_params, const int pinA, const int pinB, const int pinC)
{
_UNUSED(driver_params);
_UNUSED(pinA);
_UNUSED(pinB);
_UNUSED(pinC);
SIMPLEFOC_DEBUG("This board does not use lowside sensing. Use inline current sense instead.");
return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
}
void _driverSyncLowSide(void *_driver_params, void *_cs_params)
{
STM32DriverParams* driver_params = (STM32DriverParams*)_driver_params;
Stm32CurrentSenseParams* cs_params = (Stm32CurrentSenseParams*)_cs_params;
_stopTimers(driver_params->timers, 6);
// See RM0440 pg. 1169
// This grabs the timer handle used for ADC and sets the direction bit as upcounting (?)
cs_params->timer_handle->getHandle()->Instance->CR1 |= TIM_CR1_DIR;
// This sets the value of the timer to the reload value. I think this is so that an event is immediately fired
cs_params->timer_handle->getHandle()->Instance->CNT = cs_params->timer_handle->getHandle()->Instance->ARR;
_startTimers(driver_params->timers, 6);
}
#endif

View File

@@ -0,0 +1,14 @@
#ifndef __UTILS_H__
#define __UTILS_H__
#if defined(SIMPLEFOC_STM32_CUSTOMCURRENTSENSE)
#include "stm32g4xx_hal.h"
#include "communication/SimpleFOCDebug.h"
#include "current_sense/hardware_api.h"
#include "current_sense/hardware_specific/stm32/stm32_mcu.h"
#include "drivers/hardware_specific/stm32/stm32_mcu.h"
#endif
#endif

View File

@@ -12,6 +12,7 @@
#include "can.h"
#include "dfu.h"
#include "utils.h"
#include "lemon-pepper.h"
#define USBD_MANUFACTURER_STRING "matei repair lab"
@@ -235,10 +236,10 @@ uint8_t configureFOC(void)
motor.linkSensor(&sensor);
motor.linkDriver(&driver);
// currentsense.linkDriver(&driver);
// currentsense.init();
currentsense.linkDriver(&driver);
currentsense.init();
// motor.linkCurrentSense(&currentsense);
motor.linkCurrentSense(&currentsense);
motor.target = 10;