diff --git a/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/atmel_start_config.atstart b/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/atmel_start_config.atstart index 94e76c3..05d550c 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/atmel_start_config.atstart +++ b/2_Motor_Master/Motor_Master/Motor_Master/.atmelstart/atmel_start_config.atstart @@ -116,10 +116,17 @@ drivers: adc_freerunning_mode: false adc_pinmux_negative: Internal ground adc_pinmux_positive: ADC AIN6 pin - adc_prescaler: Peripheral clock divided by 8 + adc_prescaler: Peripheral clock divided by 16 adc_reference: External reference A adc_resolution: 12-bit optional_signals: + - identifier: ADC_1:AIN/0 + pad: PB08 + mode: Enabled + configuration: null + definition: Atmel:SAME51_Drivers:0.0.1::SAME51J19A-MF::optional_signal_definition::ADC1.AIN.0 + name: ADC1/AIN/0 + label: AIN/0 - identifier: ADC_1:AIN/6 pad: PB04 mode: Enabled diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_adc_config.h b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_adc_config.h index 5543dd3..a4ed186 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_adc_config.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_adc_config.h @@ -339,7 +339,7 @@ // These bits define the ADC clock relative to the peripheral clock (PRESCALER) // adc_prescaler #ifndef CONF_ADC_1_PRESCALER -#define CONF_ADC_1_PRESCALER 0x2 +#define CONF_ADC_1_PRESCALER 0x3 #endif // Free Running Mode diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_tcc_config.h b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_tcc_config.h index 3a934bb..9872a15 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_tcc_config.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/Config/hpl_tcc_config.h @@ -688,7 +688,7 @@ // Dual-slope, interrupt/event at Top (DSTOP) // tcc_arch_wavegen #ifndef CONF_TCC1_WAVEGEN -#define CONF_TCC1_WAVEGEN TCC_WAVE_WAVEGEN_NPWM_Val +#define CONF_TCC1_WAVEGEN TCC_WAVE_WAVEGEN_DSBOTTOM_Val #endif // TCC1 Auto Lock // Indicates whether the TCC1 Auto Lock is enabled or not @@ -762,7 +762,7 @@ // Indicates whether the TCC1 Lock update is enabled or not // tcc_arch_lupd #ifndef CONF_TCC1_LUPD -#define CONF_TCC1_LUPD 1 +#define CONF_TCC1_LUPD 0 #endif /* Commented intentionally. Timer uses fixed value of the following bit(s)/bitfield(s) of CTRL B register. diff --git a/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj b/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj index d4697ea..f3debeb 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj +++ b/2_Motor_Master/Motor_Master/Motor_Master/Motor_Master.cproj @@ -150,7 +150,7 @@ - + @@ -207,7 +207,7 @@ - + @@ -221,7 +221,7 @@ - + @@ -387,7 +387,6 @@ %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include ../Config ../ ../examples @@ -412,13 +411,14 @@ ../hpl/tc ../hpl/tcc ../hri + %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include Optimize more (-O2) True Maximum (-g3) True - -std=gnu11 -mfloat-abi=hard -mfpu=fpv4-sp-d16 + -std=gnu99 -mfloat-abi=hard -mfpu=fpv4-sp-d16 True @@ -439,7 +439,6 @@ %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include ../Config ../ ../examples @@ -464,13 +463,13 @@ ../hpl/tc ../hpl/tcc ../hri + %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include Default (-g) %24(PackRepoDir)\arm\CMSIS\5.4.0\CMSIS\Core\Include\ - %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include ../Config ../ ../examples @@ -495,6 +494,7 @@ ../hpl/tc ../hpl/tcc ../hri + %24(PackRepoDir)\atmel\SAME51_DFP\1.1.139\include Default (-Wa,-g) diff --git a/2_Motor_Master/Motor_Master/Motor_Master/bldc.c b/2_Motor_Master/Motor_Master/Motor_Master/bldc.c index f606c6c..eb4b285 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/bldc.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/bldc.c @@ -18,13 +18,13 @@ void BldcInitStruct(BLDCMotor_t *motor, BLDCMotor_param_t *motor_param) motor->motor_param = motor_param; motor->motor_status.actualDirection = 0; motor->motor_setpoints.desiredDirection = 0; - motor->motor_status.duty_cycle = 100; + motor->motor_status.duty_cycle = 200; motor->motor_status.calc_rpm = 0; motor->motor_status.Num_Steps = 0; motor->motor_status.cur_comm_step = 0; motor->motor_status.currentHallPattern = 1; motor->motor_status.nextHallPattern = 3; - motor->motor_setpoints.directionOffset = 0; + motor->motor_setpoints.directionOffset = 8; motor->Iphase_pu.A = 0; motor->Iphase_pu.B = 0; @@ -321,4 +321,104 @@ uint8_t readHallSensorM2(void) return ((a << 2) | (b << 1) | (c << 0)); +} + +// ---------------------------------------------------------------------- +// Before Power up, Measure and average offset voltage for Current Sensor +// This voltage is subtracted from all reading for Bi-Directional Current +// Measurement +// ---------------------------------------------------------------------- +void read_zero_current_offset_value(BLDCMotor_t *motor1, BLDCMotor_t *motor2) +{ + uint32_t phase_A_zero_current_offset_temp = 0; + uint32_t phase_B_zero_current_offset_temp = 0; + volatile uint16_t zero_current_offset_temp[2] = {0,0}; + uint8_t samples = 32; + uint8_t i; + + // ------------------------- Motor 1 --------------------------------- + adc_sync_enable_channel(&ADC_1, 9); + //adc_sync_enable_channel(&ADC_1, 0); + + ADC1->INPUTCTRL.reg = 0x1809; + while (ADC1->STATUS.bit.ADCBUSY) {}; /* Wait for bus synchronization. */ + + for (i=0; iSTATUS.bit.ADCBUSY) {}; /* Wait for bus synchronization. */ + ADC1->SWTRIG.bit.START = true; /* Start the ADC using a software trigger. */ + while (ADC1->INTFLAG.bit.RESRDY == 0); /* Wait for the result ready flag to be set. */ + ADC1->INTFLAG.reg = ADC_INTFLAG_RESRDY; /* Clear the flag. */ + zero_current_offset_temp[0] = ADC1->RESULT.reg; /* Read the value. */ + + phase_A_zero_current_offset_temp += zero_current_offset_temp[0]; + } + + /* Set Motor Variables */ + motor1->Voffset_lsb.A = phase_A_zero_current_offset_temp/samples; + + ADC1->INPUTCTRL.reg = 0x1808; + while (ADC1->STATUS.bit.ADCBUSY) {}; /* Wait for bus synchronization. */ + + for (i=0; iSTATUS.bit.ADCBUSY) {}; /* Wait for bus synchronization. */ + ADC1->SWTRIG.bit.START = true; /* Start the ADC using a software trigger. */ + while (ADC1->INTFLAG.bit.RESRDY == 0); /* Wait for the result ready flag to be set. */ + ADC1->INTFLAG.reg = ADC_INTFLAG_RESRDY; /* Clear the flag. */ + zero_current_offset_temp[1] = ADC1->RESULT.reg; /* Read the value. */ + + phase_B_zero_current_offset_temp += zero_current_offset_temp[1]; + } + + + /* Set Motor Variables */ + motor1->Voffset_lsb.B = phase_B_zero_current_offset_temp/samples; + adc_sync_disable_channel(&ADC_1, 8); + + adc_sync_enable_channel(&ADC_1, 7); + //adc_sync_enable_channel(&ADC_1, 0); + + phase_A_zero_current_offset_temp = 0; + phase_B_zero_current_offset_temp = 0; + + ADC1->INPUTCTRL.reg = 0x1807; + while (ADC1->STATUS.bit.ADCBUSY) {}; /* Wait for bus synchronization. */ + + for (i=0; iSTATUS.bit.ADCBUSY) {}; /* Wait for bus synchronization. */ + ADC1->SWTRIG.bit.START = true; /* Start the ADC using a software trigger. */ + while (ADC1->INTFLAG.bit.RESRDY == 0); /* Wait for the result ready flag to be set. */ + ADC1->INTFLAG.reg = ADC_INTFLAG_RESRDY; /* Clear the flag. */ + zero_current_offset_temp[0] = ADC1->RESULT.reg; /* Read the value. */ + + phase_A_zero_current_offset_temp += zero_current_offset_temp[0]; + } + + /* Set Motor Variables */ + motor2->Voffset_lsb.A = phase_A_zero_current_offset_temp/samples; + + ADC1->INPUTCTRL.reg = 0x1806; + while (ADC1->STATUS.bit.ADCBUSY) {}; /* Wait for bus synchronization. */ + + for (i=0; iSTATUS.bit.ADCBUSY) {}; /* Wait for bus synchronization. */ + ADC1->SWTRIG.bit.START = true; /* Start the ADC using a software trigger. */ + while (ADC1->INTFLAG.bit.RESRDY == 0); /* Wait for the result ready flag to be set. */ + ADC1->INTFLAG.reg = ADC_INTFLAG_RESRDY; /* Clear the flag. */ + zero_current_offset_temp[1] = ADC1->RESULT.reg; /* Read the value. */ + + phase_B_zero_current_offset_temp += zero_current_offset_temp[1]; + } + + /* Set Motor Variables */ + motor2->Voffset_lsb.B = phase_B_zero_current_offset_temp/samples; + adc_sync_disable_channel(&ADC_1, 6); + //adc_sync_disable_channel(&ADC_1, 0); } \ No newline at end of file diff --git a/2_Motor_Master/Motor_Master/Motor_Master/bldc.h b/2_Motor_Master/Motor_Master/Motor_Master/bldc.h index 285d3a0..788f891 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/bldc.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/bldc.h @@ -69,8 +69,6 @@ static const uint8_t MOTOR_COMMUTATION_STEPS[8] = {9, 1, 3, 2, 5, 6, 4, 9}; volatile BLDCMotor_t Motor1; volatile BLDCMotor_t Motor2; - - // ---------------------------------------------------------------------- // functions // ---------------------------------------------------------------------- diff --git a/2_Motor_Master/Motor_Master/Motor_Master/configuration.h b/2_Motor_Master/Motor_Master/Motor_Master/configuration.h index 8a1858a..30adfb2 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/configuration.h +++ b/2_Motor_Master/Motor_Master/Motor_Master/configuration.h @@ -12,6 +12,7 @@ // ---------------------------------------------------------------------- // Header Files // ---------------------------------------------------------------------- +#include "atmel_start_pins.h" #include "bldc.h" #include "interrupts.h" @@ -19,12 +20,22 @@ #define DMAC_CHANNEL_ADC_SRAM 3U const uint32_t adc_seq_regs[4] = {0x1806, 0x1807, 0x1808, 0x1809}; -volatile uint16_t adc_res[4] = {0}; +//const uint32_t adc_seq_regs[5] = {0x0086, 0x0087, 0x0088, 0x0089}; +//uint32_t adc_seq_regs[4] = {0x0006, 0x0007, 0x0008, 0x0009}; +//const uint32_t adc_seq_regs[5] = {0x1800, 0x1806, 0x1807, 0x1808, 0x1809}; +volatile int16_t adc_res[4] = {0}; struct _dma_resource *adc_sram_dma_resource; struct _dma_resource *adc_dmac_sequence_resource; inline static void configure_tcc_pwm(void) { + gpio_set_pin_pull_mode(M1_HALLA, GPIO_PULL_UP); + gpio_set_pin_pull_mode(M1_HALLB, GPIO_PULL_UP); + gpio_set_pin_pull_mode(M1_HALLC, GPIO_PULL_UP); + gpio_set_pin_pull_mode(M2_HALLA, GPIO_PULL_UP); + gpio_set_pin_pull_mode(M2_HALLB, GPIO_PULL_UP); + gpio_set_pin_pull_mode(M2_HALLC, GPIO_PULL_UP); + /* TCC0 */ hri_tcc_set_WEXCTRL_OTMX_bf(TCC0, 0x02); diff --git a/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c b/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c index ec85799..2e6da97 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/driver_init.c @@ -60,6 +60,11 @@ void ADC_0_init(void) void ADC_1_PORT_init(void) { + // Disable digital pin circuitry + gpio_set_pin_direction(half_VREF, GPIO_DIRECTION_OFF); + + gpio_set_pin_function(half_VREF, PINMUX_PB08B_ADC1_AIN0); + // Disable digital pin circuitry gpio_set_pin_direction(M1_IA, GPIO_DIRECTION_OFF); @@ -98,22 +103,16 @@ void DIGITAL_GLUE_LOGIC_0_PORT_init(void) { gpio_set_pin_function(M1_HALLA, PINMUX_PA04N_CCL_IN0); - gpio_set_pin_pull_mode(M1_HALLA, GPIO_PULL_UP); gpio_set_pin_function(M1_HALLB, PINMUX_PA05N_CCL_IN1); - gpio_set_pin_pull_mode(M1_HALLB, GPIO_PULL_UP); gpio_set_pin_function(M1_HALLC, PINMUX_PA06N_CCL_IN2); - gpio_set_pin_pull_mode(M1_HALLC, GPIO_PULL_UP); gpio_set_pin_function(M2_HALLA, PINMUX_PA22N_CCL_IN6); - gpio_set_pin_pull_mode(M2_HALLA, GPIO_PULL_UP); gpio_set_pin_function(M2_HALLB, PINMUX_PA23N_CCL_IN7); - gpio_set_pin_pull_mode(M2_HALLB, GPIO_PULL_UP); gpio_set_pin_function(M2_HALLC, PINMUX_PA24N_CCL_IN8); - gpio_set_pin_pull_mode(M2_HALLC, GPIO_PULL_UP); } void DIGITAL_GLUE_LOGIC_0_CLOCK_init(void) @@ -713,13 +712,6 @@ void system_init(void) gpio_set_pin_function(SPI3_SS, GPIO_PIN_FUNCTION_OFF); - // GPIO on PB08 - - // Disable digital pin circuitry - gpio_set_pin_direction(half_VREF, GPIO_DIRECTION_OFF); - - gpio_set_pin_function(half_VREF, GPIO_PIN_FUNCTION_OFF); - // GPIO on PB22 gpio_set_pin_function(SPI1_CS, GPIO_PIN_FUNCTION_OFF); diff --git a/2_Motor_Master/Motor_Master/Motor_Master/main.c b/2_Motor_Master/Motor_Master/Motor_Master/main.c index 06504e7..61a3cac 100644 --- a/2_Motor_Master/Motor_Master/Motor_Master/main.c +++ b/2_Motor_Master/Motor_Master/Motor_Master/main.c @@ -21,17 +21,17 @@ void process_currents() volatile int16_t phase_A_current_raw, phase_B_current_raw; /* Motor 1 */ - phase_A_current_raw = (adc_res[0] - Motor1.Voffset_lsb.A); - phase_B_current_raw = (adc_res[1] - Motor1.Voffset_lsb.B)*-1; + phase_A_current_raw = (adc_res[3] - Motor1.Voffset_lsb.A); + phase_B_current_raw = (adc_res[2] - Motor1.Voffset_lsb.B)*-1; // Covert from LSB to PU (A) and filter out small readings Motor1.Iphase_pu.A = phase_A_current_raw * LSB_TO_PU; Motor1.Iphase_pu.B = phase_B_current_raw * LSB_TO_PU; // i_c = -i_a - i_b because i_a + i_b + i_c = 0 Motor1.Iphase_pu.C = -Motor1.Iphase_pu.A - Motor1.Iphase_pu.B; - /* Motor 2 */ - phase_A_current_raw = (adc_res[2] - Motor2.Voffset_lsb.A); - phase_B_current_raw = (adc_res[3] - Motor2.Voffset_lsb.B)*-1; + /* Motor 2 negative is A instead of B*/ + phase_A_current_raw = (adc_res[1] - Motor2.Voffset_lsb.A); + phase_B_current_raw = (adc_res[0] - Motor2.Voffset_lsb.B)*-1; // Covert from LSB to PU (A) and filter out small readings Motor2.Iphase_pu.A = phase_A_current_raw * LSB_TO_PU; Motor2.Iphase_pu.B = phase_B_current_raw * LSB_TO_PU; @@ -148,7 +148,6 @@ inline void CONTROLLER_StateMachine(void) int main(void) { - volatile uint8_t m2_hall, m1_hall, x= 0; /* Initializes MCU, drivers and middleware */ atmel_start_init(); //initMotorParameters(); @@ -156,11 +155,11 @@ int main(void) BldcInitStruct(&Motor2, &FH_32mm24BXTR); Motor1.readHall = &readHallSensorM1; Motor2.readHall = &readHallSensorM2; - + read_zero_current_offset_value(&Motor1, &Motor2); config_qspi(); One_ms_timer_init(); configure_tcc_pwm(); - adc_sync_enable_channel(&ADC_1, 0); + adc_sync_enable_channel(&ADC_1, 6); adc_init_dma(); ECAT_STATE_MACHINE(); enable_NVIC_IRQ();