diff --git a/src/current_sense/phoque1/Phoque1_CurrentSense.cpp b/src/current_sense/phoque1/Phoque1_CurrentSense.cpp new file mode 100644 index 0000000..2943af9 --- /dev/null +++ b/src/current_sense/phoque1/Phoque1_CurrentSense.cpp @@ -0,0 +1,219 @@ +#if defined(ARDUINO_PHOQUE1) + +#include "Phoque1_CurrentSense.hpp" +#include "communication/SimpleFOCDebug.h" +#include "current_sense/hardware_specific/stm32/stm32_adc_utils.h" + +static OPAMP_HandleTypeDef hopamp1; +static OPAMP_HandleTypeDef hopamp2; +static OPAMP_HandleTypeDef hopamp3; + +Phoque1_CurrentSense::Phoque1_CurrentSense(float _shunt_resistor, float _gain, bool _read_bemf) + :Phoque_CurrentSense(_shunt_resistor, _gain, _read_bemf) +{ + pinA = A_CURRU_H; + pinB = A_CURRV_H; + pinC = A_CURRW_H; +} + +Phoque1_CurrentSense::Phoque1_CurrentSense(float mVpA, bool _read_bemf) + :Phoque_CurrentSense(mVpA, _read_bemf) +{ + pinA = A_CURRU_H; + pinB = A_CURRV_H; + pinC = A_CURRW_H; +} + +Phoque1_CurrentSense::~Phoque1_CurrentSense() +{ +} + +void Phoque1_CurrentSense::Opamp_Init() +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_3 | GPIO_PIN_5|GPIO_PIN_7; //Opamp 1 | Opamp 2 + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2; // Opamp 3 + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + OPAMP_HandleTypeDef *opamp_handles[] = {&hopamp1, &hopamp2, &hopamp3}; + OPAMP_TypeDef *opamp_instances[] = {OPAMP1, OPAMP2, OPAMP3}; + static_assert(sizeof(opamp_handles)/sizeof(opamp_handles[0]) == sizeof(opamp_instances)/sizeof(opamp_instances[0])); + + for (size_t i = 0; i < sizeof(opamp_handles)/sizeof(opamp_handles[0]); i++) + { + auto hopamp = opamp_handles[i]; + hopamp->Instance = opamp_instances[i]; + hopamp->Init.PowerMode = OPAMP_POWERMODE_HIGHSPEED; + hopamp->Init.Mode = OPAMP_PGA_MODE; + hopamp->Init.NonInvertingInput = OPAMP_NONINVERTINGINPUT_IO0; + hopamp->Init.InternalOutput = ENABLE; + hopamp->Init.TimerControlledMuxmode = OPAMP_TIMERCONTROLLEDMUXMODE_DISABLE; + hopamp->Init.PgaConnect = OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0_BIAS; + hopamp->Init.PgaGain = OPAMP_PGA_GAIN_16_OR_MINUS_15; + hopamp->Init.UserTrimming = OPAMP_TRIMMING_FACTORY; + if (HAL_OPAMP_Init(hopamp) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_OPAMP_Init failed!"); + } + HAL_OPAMP_Start(hopamp); + } +} + +int Phoque1_CurrentSense::ADC1_Init(ADC_HandleTypeDef* hadc1) +{ + ADC_ChannelConfTypeDef sConfig = {0}; + sConfig.SingleDiff = ADC_SINGLE_ENDED; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; + + hadc1->Init.NbrOfConversion += 3 + read_bemf * 2; + Phoque_CurrentSense::ADC1_Init(hadc1); + + /** Configure Regular Channel (Opamp 1 / phase W current) + */ + sConfig.Channel = ADC_CHANNEL_13; // OP1_OUT is ADC1_IN13 for internal channel + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + + if(read_bemf) + { + /* Configure Regular Channel (PA0 / BEMFU / Phase U) + */ + sConfig.Channel = _getADCChannel(analogInputToPinName(A_BEMFU), ADC1); + sConfig.Rank = ADC_REGULAR_RANK_2; + sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + + /* Configure Regular Channel (PC4 / BEMFV / Phase V) + */ + sConfig.Channel = _getADCChannel(analogInputToPinName(A_BEMFV), ADC1); + sConfig.Rank = ADC_REGULAR_RANK_3; + sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + } + + //****************************************************************** + // Aux analog readings + /* Configure Regular Channel (PC1, supply voltage) + */ + sConfig.Channel = _getADCChannel(analogInputToPinName(A_VBUS), ADC1); + sConfig.Rank = read_bemf ? ADC_REGULAR_RANK_4 : ADC_REGULAR_RANK_2; + sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + + /** Configure Regular Channel (PC0, Potentiometer) + */ + sConfig.Channel = _getADCChannel(analogInputToPinName(A_POTENTIOMETER), ADC1); + sConfig.Rank = read_bemf ? ADC_REGULAR_RANK_5 : ADC_REGULAR_RANK_3; + sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + return hadc1->Init.NbrOfConversion; +} + +int Phoque1_CurrentSense::ADC2_Init(ADC_HandleTypeDef* hadc2) +{ + ADC_ChannelConfTypeDef sConfig = {0}; + sConfig.SingleDiff = ADC_SINGLE_ENDED; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; + + hadc2->Init.NbrOfConversion += 3 + read_bemf; + Phoque_CurrentSense::ADC2_Init(hadc2); + + /** Configure Regular Channel (Opamp 2 / phase U current) + */ + sConfig.Channel = ADC_CHANNEL_16; // OP2_OUT is ADC2_IN16 for internal channel + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + /** Configure Regular Channel (Opamp 3 / phase V current) + */ + sConfig.Channel = ADC_CHANNEL_18; // OP3_OUT is ADC2_IN18 for internal channel + sConfig.Rank = ADC_REGULAR_RANK_2; + sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + + if(read_bemf) + { + /** Configure Regular Channel (PA2 / BEMFW / Phase W) + */ + sConfig.Channel = _getADCChannel(analogInputToPinName(A_BEMFW), ADC2); + sConfig.Rank = ADC_REGULAR_RANK_3; + sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + } + + /** Configure Regular Channel (PF1 / Mosfet temperature) + */ + sConfig.Channel = _getADCChannel(analogInputToPinName(A_TEMPERATURE), ADC2); + sConfig.Rank = read_bemf ? ADC_REGULAR_RANK_4 : ADC_REGULAR_RANK_3; + sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; + if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) + { + SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); + } + return hadc2->Init.NbrOfConversion; +} + +uint16_t Phoque1_CurrentSense::readRaw(const int pin) +{ + switch (pin) + { + case A_CURRU_H: + case -1: + return adc2_buffer[0]; + case A_CURRV_H: + case -2: + return adc2_buffer[1]; + case A_CURRW_H: + case -3: + return adc1_buffer[0]; + + case A_BEMFU: + return adc1_buffer[1]; + case A_BEMFV: + return adc1_buffer[2]; + case A_BEMFW: + return adc2_buffer[2]; + + case A_POTENTIOMETER: + return adc1_buffer[2+read_bemf*2]; + case A_TEMPERATURE: + return adc2_buffer[2+read_bemf]; + case A_VBUS: + return adc1_buffer[1+read_bemf*2]; + default: + return 0; + } +} + +#endif \ No newline at end of file diff --git a/src/current_sense/phoque1/Phoque1_CurrentSense.hpp b/src/current_sense/phoque1/Phoque1_CurrentSense.hpp new file mode 100644 index 0000000..ddf2890 --- /dev/null +++ b/src/current_sense/phoque1/Phoque1_CurrentSense.hpp @@ -0,0 +1,26 @@ +#pragma once + +#if defined(ARDUINO_PHOQUE1) + +#include "current_sense/phoque/Phoque_CurrentSense.hpp" + +class Phoque1_CurrentSense : public Phoque_CurrentSense +{ +private: + volatile uint16_t *adc1_buffer = nullptr; + volatile uint16_t *adc2_buffer = nullptr; + bool read_bemf; +public: + Phoque1_CurrentSense(float shunt_resistor, float gain, bool read_bemf=false); + Phoque1_CurrentSense(float mVpA, bool read_bemf=false); + ~Phoque1_CurrentSense(); + + uint16_t readRaw(const int pin); + +private: + void Opamp_Init(); + int ADC1_Init(ADC_HandleTypeDef* hadc1); + int ADC2_Init(ADC_HandleTypeDef* hadc2); +}; + +#endif \ No newline at end of file diff --git a/src/current_sense/phoque2a/Phoque2a_CurrentSense.cpp b/src/current_sense/phoque2a/Phoque2a_CurrentSense.cpp index b7fbe80..2a8e957 100644 --- a/src/current_sense/phoque2a/Phoque2a_CurrentSense.cpp +++ b/src/current_sense/phoque2a/Phoque2a_CurrentSense.cpp @@ -29,6 +29,9 @@ Phoque2a_CurrentSense::~Phoque2a_CurrentSense() int Phoque2a_CurrentSense::ADC1_Init(ADC_HandleTypeDef* hadc1) { ADC_ChannelConfTypeDef sConfig = {0}; + sConfig.SingleDiff = ADC_SINGLE_ENDED; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; hadc1->Init.NbrOfConversion += 3 + read_bemf * 2; @@ -39,9 +42,6 @@ int Phoque2a_CurrentSense::ADC1_Init(ADC_HandleTypeDef* hadc1) sConfig.Channel = _getADCChannel(analogInputToPinName(A_CURRU), ADC1); //ADC_CHANNEL_2; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -54,9 +54,6 @@ int Phoque2a_CurrentSense::ADC1_Init(ADC_HandleTypeDef* hadc1) sConfig.Channel = _getADCChannel(analogInputToPinName(A_BEMFV), ADC1); //ADC_CHANNEL_15; sConfig.Rank = ADC_REGULAR_RANK_2; sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -67,9 +64,6 @@ int Phoque2a_CurrentSense::ADC1_Init(ADC_HandleTypeDef* hadc1) sConfig.Channel = _getADCChannel(analogInputToPinName(A_BEMFW), ADC1); //ADC_CHANNEL_12; sConfig.Rank = ADC_REGULAR_RANK_3; sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -83,9 +77,6 @@ int Phoque2a_CurrentSense::ADC1_Init(ADC_HandleTypeDef* hadc1) sConfig.Channel = _getADCChannel(analogInputToPinName(A_TEMPERATURE), ADC1); //ADC_CHANNEL_11; sConfig.Rank = read_bemf ? ADC_REGULAR_RANK_4 : ADC_REGULAR_RANK_2; sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -96,9 +87,6 @@ int Phoque2a_CurrentSense::ADC1_Init(ADC_HandleTypeDef* hadc1) sConfig.Channel = _getADCChannel(analogInputToPinName(A_VBUS), ADC1); //ADC_CHANNEL_4; sConfig.Rank = read_bemf ? ADC_REGULAR_RANK_5 : ADC_REGULAR_RANK_3; sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc1, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -109,6 +97,9 @@ int Phoque2a_CurrentSense::ADC1_Init(ADC_HandleTypeDef* hadc1) int Phoque2a_CurrentSense::ADC2_Init(ADC_HandleTypeDef* hadc2) { ADC_ChannelConfTypeDef sConfig = {0}; + sConfig.SingleDiff = ADC_SINGLE_ENDED; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; hadc2->Init.NbrOfConversion += 3 + read_bemf; @@ -119,9 +110,6 @@ int Phoque2a_CurrentSense::ADC2_Init(ADC_HandleTypeDef* hadc2) sConfig.Channel = _getADCChannel(analogInputToPinName(A_CURRV), ADC2); //ADC_CHANNEL_5; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -131,9 +119,6 @@ int Phoque2a_CurrentSense::ADC2_Init(ADC_HandleTypeDef* hadc2) sConfig.Channel = _getADCChannel(analogInputToPinName(A_CURRW), ADC2); //ADC_CHANNEL_12; sConfig.Rank = ADC_REGULAR_RANK_2; sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -146,9 +131,6 @@ int Phoque2a_CurrentSense::ADC2_Init(ADC_HandleTypeDef* hadc2) sConfig.Channel = _getADCChannel(analogInputToPinName(A_BEMFU), ADC2); //ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_3; sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!"); @@ -160,9 +142,6 @@ int Phoque2a_CurrentSense::ADC2_Init(ADC_HandleTypeDef* hadc2) sConfig.Channel = _getADCChannel(analogInputToPinName(A_POTENTIOMETER), ADC2); //ADC_CHANNEL_17; sConfig.Rank = read_bemf ? ADC_REGULAR_RANK_4 : ADC_REGULAR_RANK_3; sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; - sConfig.SingleDiff = ADC_SINGLE_ENDED; - sConfig.OffsetNumber = ADC_OFFSET_NONE; - sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(hadc2, &sConfig) != HAL_OK) { SIMPLEFOC_DEBUG("HAL_ADC_ConfigChannel failed!");