From 5bbba0c8a9f6e5432f0e73776035cff31312d6aa Mon Sep 17 00:00:00 2001 From: Richard Unger Date: Sun, 3 Sep 2023 12:20:12 +0200 Subject: [PATCH 1/6] added comments for reverse direction #254 --- .../open_loop_position_example/open_loop_position_example.ino | 1 + .../open_loop_velocity_example/open_loop_velocity_example.ino | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/motion_control/open_loop_motor_control/open_loop_position_example/open_loop_position_example.ino b/examples/motion_control/open_loop_motor_control/open_loop_position_example/open_loop_position_example.ino index 83b1fb32..5a915dd8 100644 --- a/examples/motion_control/open_loop_motor_control/open_loop_position_example/open_loop_position_example.ino +++ b/examples/motion_control/open_loop_motor_control/open_loop_position_example/open_loop_position_example.ino @@ -62,6 +62,7 @@ void setup() { void loop() { // open loop angle movements // using motor.voltage_limit and motor.velocity_limit + // angles can be positive or negative, negative angles correspond to opposite motor direction motor.move(target_position); // user communication diff --git a/examples/motion_control/open_loop_motor_control/open_loop_velocity_example/open_loop_velocity_example.ino b/examples/motion_control/open_loop_motor_control/open_loop_velocity_example/open_loop_velocity_example.ino index 84f87ab9..43fc6f73 100644 --- a/examples/motion_control/open_loop_motor_control/open_loop_velocity_example/open_loop_velocity_example.ino +++ b/examples/motion_control/open_loop_motor_control/open_loop_velocity_example/open_loop_velocity_example.ino @@ -60,6 +60,7 @@ void loop() { // open loop velocity movement // using motor.voltage_limit and motor.velocity_limit + // to turn the motor "backwards", just set a negative target_velocity motor.move(target_velocity); // user communication From 7677c855de85f2e756fa23fb9003bc39968881f5 Mon Sep 17 00:00:00 2001 From: Richard Unger Date: Sun, 10 Sep 2023 20:21:54 +0200 Subject: [PATCH 2/6] swap pow() function for _powtwo() --- src/common/foc_utils.h | 1 + src/sensors/MagneticSensorI2C.cpp | 4 ++-- src/sensors/MagneticSensorSPI.cpp | 6 +++--- src/sensors/MagneticSensorSPI.h | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/common/foc_utils.h b/src/common/foc_utils.h index cf3df719..0efe3b59 100644 --- a/src/common/foc_utils.h +++ b/src/common/foc_utils.h @@ -12,6 +12,7 @@ #define _sqrt(a) (_sqrtApprox(a)) #define _isset(a) ( (a) != (NOT_SET) ) #define _UNUSED(v) (void) (v) +#define _powtwo(x) (1 << (x)) // utility defines #define _2_SQRT3 1.15470053838f diff --git a/src/sensors/MagneticSensorI2C.cpp b/src/sensors/MagneticSensorI2C.cpp index fb4eee03..ac2b273b 100644 --- a/src/sensors/MagneticSensorI2C.cpp +++ b/src/sensors/MagneticSensorI2C.cpp @@ -28,7 +28,7 @@ MagneticSensorI2C::MagneticSensorI2C(uint8_t _chip_address, int _bit_resolution, // angle read register of the magnetic sensor angle_register_msb = _angle_register_msb; // register maximum value (counts per revolution) - cpr = pow(2, _bit_resolution); + cpr = _powtwo(_bit_resolution); // depending on the sensor architecture there are different combinations of // LSB and MSB register used bits @@ -48,7 +48,7 @@ MagneticSensorI2C::MagneticSensorI2C(MagneticSensorI2CConfig_s config){ // angle read register of the magnetic sensor angle_register_msb = config.angle_register; // register maximum value (counts per revolution) - cpr = pow(2, config.bit_resolution); + cpr = _powtwo(config.bit_resolution); int bits_used_msb = config.data_start_bit - 7; lsb_used = config.bit_resolution - bits_used_msb; diff --git a/src/sensors/MagneticSensorSPI.cpp b/src/sensors/MagneticSensorSPI.cpp index 7341c89a..52febc38 100644 --- a/src/sensors/MagneticSensorSPI.cpp +++ b/src/sensors/MagneticSensorSPI.cpp @@ -31,13 +31,13 @@ MagneticSensorSPIConfig_s MA730_SPI = { // cs - SPI chip select pin // _bit_resolution sensor resolution bit number // _angle_register - (optional) angle read register - default 0x3FFF -MagneticSensorSPI::MagneticSensorSPI(int cs, float _bit_resolution, int _angle_register){ +MagneticSensorSPI::MagneticSensorSPI(int cs, int _bit_resolution, int _angle_register){ chip_select_pin = cs; // angle read register of the magnetic sensor angle_register = _angle_register ? _angle_register : DEF_ANGLE_REGISTER; // register maximum value (counts per revolution) - cpr = pow(2,_bit_resolution); + cpr = _powtwo(_bit_resolution); spi_mode = SPI_MODE1; clock_speed = 1000000; bit_resolution = _bit_resolution; @@ -52,7 +52,7 @@ MagneticSensorSPI::MagneticSensorSPI(MagneticSensorSPIConfig_s config, int cs){ // angle read register of the magnetic sensor angle_register = config.angle_register ? config.angle_register : DEF_ANGLE_REGISTER; // register maximum value (counts per revolution) - cpr = pow(2, config.bit_resolution); + cpr = _powtwo(config.bit_resolution); spi_mode = config.spi_mode; clock_speed = config.clock_speed; bit_resolution = config.bit_resolution; diff --git a/src/sensors/MagneticSensorSPI.h b/src/sensors/MagneticSensorSPI.h index a77e7698..03ebde44 100644 --- a/src/sensors/MagneticSensorSPI.h +++ b/src/sensors/MagneticSensorSPI.h @@ -30,7 +30,7 @@ class MagneticSensorSPI: public Sensor{ * @param bit_resolution sensor resolution bit number * @param angle_register (optional) angle read register - default 0x3FFF */ - MagneticSensorSPI(int cs, float bit_resolution, int angle_register = 0); + MagneticSensorSPI(int cs, int bit_resolution, int angle_register = 0); /** * MagneticSensorSPI class constructor * @param config SPI config From 5ef4d9d5a92e03da0dd5af7f624243ab30f1b688 Mon Sep 17 00:00:00 2001 From: Richard Unger Date: Tue, 12 Sep 2023 18:26:19 +0200 Subject: [PATCH 3/6] add some checks to current-sense init --- src/current_sense/GenericCurrentSense.cpp | 2 ++ src/current_sense/InlineCurrentSense.cpp | 8 ++++++++ src/current_sense/LowsideCurrentSense.cpp | 11 ++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/current_sense/GenericCurrentSense.cpp b/src/current_sense/GenericCurrentSense.cpp index d0592ef2..635535fa 100644 --- a/src/current_sense/GenericCurrentSense.cpp +++ b/src/current_sense/GenericCurrentSense.cpp @@ -62,6 +62,8 @@ int GenericCurrentSense::driverAlign(float voltage){ int exit_flag = 1; if(skip_align) return exit_flag; + if (!initialized) return 0; + // // set phase A active and phases B and C down // driver->setPwm(voltage, 0, 0); // _delay(200); diff --git a/src/current_sense/InlineCurrentSense.cpp b/src/current_sense/InlineCurrentSense.cpp index 6a41484a..492b3ac9 100644 --- a/src/current_sense/InlineCurrentSense.cpp +++ b/src/current_sense/InlineCurrentSense.cpp @@ -1,4 +1,5 @@ #include "InlineCurrentSense.h" +#include "communication/SimpleFOCDebug.h" // InlineCurrentSensor constructor // - shunt_resistor - shunt resistor value // - gain - current-sense op-amp gain @@ -93,6 +94,13 @@ int InlineCurrentSense::driverAlign(float voltage){ int exit_flag = 1; if(skip_align) return exit_flag; + if (driver==nullptr) { + SIMPLEFOC_DEBUG("CUR: No driver linked!"); + return 0; + } + + if (!initialized) return 0; + if(_isset(pinA)){ // set phase A active and phases B and C down driver->setPwm(voltage, 0, 0); diff --git a/src/current_sense/LowsideCurrentSense.cpp b/src/current_sense/LowsideCurrentSense.cpp index 21df16e1..a706beeb 100644 --- a/src/current_sense/LowsideCurrentSense.cpp +++ b/src/current_sense/LowsideCurrentSense.cpp @@ -1,4 +1,5 @@ #include "LowsideCurrentSense.h" +#include "communication/SimpleFOCDebug.h" // LowsideCurrentSensor constructor // - shunt_resistor - shunt resistor value // - gain - current-sense op-amp gain @@ -35,6 +36,12 @@ LowsideCurrentSense::LowsideCurrentSense(float _mVpA, int _pinA, int _pinB, int // Lowside sensor init function int LowsideCurrentSense::init(){ + + if (driver==nullptr) { + SIMPLEFOC_DEBUG("CUR: Driver not linked!"); + return 0; + } + // configure ADC variables params = _configureADCLowSide(driver->params,pinA,pinB,pinC); // if init failed return fail @@ -89,10 +96,12 @@ PhaseCurrent_s LowsideCurrentSense::getPhaseCurrents(){ // 3 - success but gains inverted // 4 - success but pins reconfigured and gains inverted int LowsideCurrentSense::driverAlign(float voltage){ - + int exit_flag = 1; if(skip_align) return exit_flag; + if (!initialized) return 0; + if(_isset(pinA)){ // set phase A active and phases B and C down driver->setPwm(voltage, 0, 0); From 132e7b0d90dc429ff9db208bffcaea82d4a8d40d Mon Sep 17 00:00:00 2001 From: Richard Unger Date: Tue, 12 Sep 2023 18:26:30 +0200 Subject: [PATCH 4/6] mark param unused --- src/current_sense/hardware_specific/rp2040/rp2040_mcu.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/current_sense/hardware_specific/rp2040/rp2040_mcu.cpp b/src/current_sense/hardware_specific/rp2040/rp2040_mcu.cpp index 613c6323..d84c2fd5 100644 --- a/src/current_sense/hardware_specific/rp2040/rp2040_mcu.cpp +++ b/src/current_sense/hardware_specific/rp2040/rp2040_mcu.cpp @@ -25,6 +25,7 @@ float _readADCVoltageInline(const int pinA, const void* cs_params) { // return readings from the same ADC conversion run. The ADC on RP2040 is anyway in round robin mode :-( // like this we either have to block interrupts, or of course have the chance of reading across // new ADC conversions, which probably won't improve the accuracy. + _UNUSED(cs_params); if (pinA>=26 && pinA<=29 && engine.channelsEnabled[pinA-26]) { return engine.lastResults.raw[pinA-26]*engine.adc_conv; @@ -36,6 +37,8 @@ float _readADCVoltageInline(const int pinA, const void* cs_params) { void* _configureADCInline(const void *driver_params, const int pinA, const int pinB, const int pinC) { + _UNUSED(driver_params); + if( _isset(pinA) ) engine.addPin(pinA); if( _isset(pinB) ) From c99cc6da8f2e2adc97e4b8d1b3897263de09762f Mon Sep 17 00:00:00 2001 From: Richard Unger Date: Sun, 17 Sep 2023 23:26:17 +0200 Subject: [PATCH 5/6] update README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 47d7540f..729c23c6 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,9 @@ Therefore this is an attempt to: > - Expose I2C errors in MagneticSensorI2C (thanks to [@padok](https://github.com/padok)) > - Improved default trig functions (sine, cosine) - faster, smaller > - Overridable trig functions - plug in your own optimized versions -> - bugfix: microseconds overflow in velocity mode -> - bugfix: KV initialization +> - Bugfix: microseconds overflow in velocity mode +> - Bugfix: KV initialization +> - Compatibility with newest versions of Arduino framework for STM32, Renesas, ESP32, Atmel SAM, Atmel AVR, nRF52 and RP2040 ## Arduino *SimpleFOClibrary* v2.3.1 From fb887073fe08c151eee183505778e0ff063681db Mon Sep 17 00:00:00 2001 From: Richard Unger Date: Sun, 17 Sep 2023 23:26:51 +0200 Subject: [PATCH 6/6] renesas small fixes --- src/drivers/hardware_specific/renesas/renesas.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/drivers/hardware_specific/renesas/renesas.cpp b/src/drivers/hardware_specific/renesas/renesas.cpp index 4a6a3e92..f90a4c56 100644 --- a/src/drivers/hardware_specific/renesas/renesas.cpp +++ b/src/drivers/hardware_specific/renesas/renesas.cpp @@ -13,6 +13,8 @@ #include "communication/SimpleFOCDebug.h" #include "FspTimer.h" +#define GPT_OPEN (0x00475054ULL) + /* We use the GPT timers, there are 2 channels (32 bit) + 6 channels (16 bit) Each channel has 2 outputs (GTIOCAx and GTIOCBx) which can be complimentary. @@ -202,6 +204,7 @@ bool configureTimerPin(RenesasHardwareDriverParams* params, uint8_t index, bool t->timer_cfg.p_context = nullptr; t->timer_cfg.p_extend = &(t->ext_cfg); t->timer_cfg.cycle_end_ipl = BSP_IRQ_DISABLED; + t->timer_cfg.cycle_end_irq = FSP_INVALID_VECTOR; t->ext_cfg.p_pwm_cfg = &(t->pwm_cfg); t->pwm_cfg.trough_ipl = BSP_IRQ_DISABLED; @@ -256,6 +259,14 @@ bool configureTimerPin(RenesasHardwareDriverParams* params, uint8_t index, bool t->ext_cfg.gtior_setting.gtior_b.obdflt = active_high ? 0x00 : 0x01; } + // lets stop the timer in case its running + if (GPT_OPEN == t->ctrl.open) { + if (R_GPT_Stop(&(t->ctrl)) != FSP_SUCCESS) { + SIMPLEFOC_DEBUG("DRV: timer stop failed"); + return false; + } + } + memset(&(t->ctrl), 0, sizeof(gpt_instance_ctrl_t)); err = R_GPT_Open(&(t->ctrl),&(t->timer_cfg)); if ((err != FSP_ERR_ALREADY_OPEN) && (err != FSP_SUCCESS)) { @@ -294,7 +305,7 @@ bool configureTimerPin(RenesasHardwareDriverParams* params, uint8_t index, bool bool startTimerChannels(RenesasHardwareDriverParams* params, int num_channels) { uint32_t mask = 0; for (int i = 0; i < num_channels; i++) { - RenesasTimerConfig* t = params->timer_config[i]; + // RenesasTimerConfig* t = params->timer_config[i]; // if (R_GPT_Start(&(t->ctrl)) != FSP_SUCCESS) { // SIMPLEFOC_DEBUG("DRV: timer start failed"); // return false;