Motor Driver Evaluation Kit NEVB-MTR1-t01-1.0.0
Firmware for NEVB-MTR1-KIT1 for trapezoidal control of BLDC motors using Hall-effect sensors
|
Motor control implementation. More...
Go to the source code of this file.
Functions | |
volatile motorflags_t motorFlags | __attribute__ ((address(0x4A))) |
Motor control flags placed in I/O space for fast access. | |
volatile faultflags_t faultFlags | __attribute__ ((address(0x3E))) |
Fault flags placed in I/O space for fast access. | |
void | setup (void) |
Main initialization function. | |
void | loop () |
Main Loop Function. | |
static void | FlagsInit (void) |
Initializes motorFlags and faultFlags. | |
static void | ConfigsInit (void) |
Initializes motorConfigs. | |
static void | PLLInit (void) |
Initialize PLL (Phase-Locked Loop) | |
static void | PortsInit (void) |
Initialize I/O port directions and pull-up resistors. | |
void | TimersInit (void) |
Initializes and synchronizes Timers. | |
static void | PinChangeIntInit (void) |
Initialize pin change interrupts. | |
static void | ADCInit (void) |
Initializes the ADC. | |
static uint16_t | ADCSingleConversion (void) |
Perform a single ADC conversion. | |
static void | EnableUpdate (void) |
Check whether the enable pin is set and update flags accordingly. | |
static void | DisableMotor (void) |
Disable motor. | |
static void | RemoteUpdate (void) |
Check whether the remote pin is set and update flags accordingly. | |
static void | SpeedController (void) |
Speed regulator loop. | |
static void | FatalError () |
Handle a fatal error and enter a fault state. | |
static | __attribute__ ((always_inline)) void SetDuty(const uint16_t duty) |
Set duty cycle for TIM4. | |
if (direction==0) | |
ClearPWMPorts () | |
TCCR4E & | DisablePWMOutputs () |
EnablePWMOutputs () | |
Variables | |
volatile motorconfigs_t | motorConfigs |
Motor Configs. | |
volatile uint16_t | commutationTicks = 0 |
The number of 'ticks' between two hall sensor changes (counter). | |
volatile uint16_t | lastCommutationTicks = 0xffff |
The number of 'ticks' between two hall sensor changes (store). | |
volatile uint8_t | speedInput = 0 |
The most recent "speed" input measurement. | |
volatile uint8_t | speedOutput = 0 |
The most recent "speed" output from the speed controller. | |
volatile uint16_t | ibus = 0 |
Hi-side Current (IBUS) measurement (Register Value). | |
volatile int16_t | iphaseU = 0 |
In-line Phase U current current measurement (Register Value). | |
volatile int16_t | iphaseV = 0 |
In-line Phase V current current measurement (Register Value). | |
volatile int16_t | iphaseW = 0 |
In-line Phase W current current measurement (Register Value). | |
volatile uint16_t | vbusVref = 0 |
VBUS voltage measurement (Register Value) | |
static uint8_t | hall |
else | |
tableAddress = (hall * 4) | |
PORTB = (uint8_t)pgm_read_byte_near(tableAddress++) | |
PORTC = (uint8_t)pgm_read_byte_near(tableAddress++) | |
PORTD = (uint8_t)pgm_read_byte_near(tableAddress++) | |
TCCR4E = (uint8_t)pgm_read_byte_near(tableAddress) | |
Motor control implementation.
This file contains the full implementation of the motor control, except the PID-controller, filter, fault, SCPI and table implementations and definitions.
Definition in file main.ino.
volatile faultflags_t faultFlags __attribute__ | ( | (address(0x3E)) | ) |
Fault flags placed in I/O space for fast access.
This variable contains all the flags used for faults. It is placed in GPIOR0 register, which allows usage of several fast bit manipulation/branch instructions.
volatile motorflags_t motorFlags __attribute__ | ( | (address(0x4A)) | ) |
Motor control flags placed in I/O space for fast access.
This variable contains all the flags used for motor control. It is placed in GPIOR1 and GPIOR2 registers, which allows usage of several fast bit manipulation/branch instructions.
|
inlinestatic |
Set duty cycle for TIM4.
Update the global actual direction flag based on the two latest hall values.
Updates global desired direction flag.
Read the hall sensor inputs and decode the hall state.
Perform block commutation based on direction and hall sensor input.
Wait for the start of the next PWM cycle.
Configures timers for block commutation.
This function sets the duty cycle for block commutation, where the duty range is 0-1023 (not in percentage). To convert to percentage, use: duty * 100 / 1023.
duty | New duty cycle, range 0-1023. |
This function is called every time the drive waveform is changed and block commutation is needed. PWM outputs are safely disabled while configuration registers are changed to avoid unintended driving or shoot-through.
The function sets the PWM pins to input (High-Z) while changing modes and configures the timers. The output duty cycle is set to zero initially. It waits for the next PWM cycle to ensure that all outputs are updated, and then the motor drive waveform is set to block commutation. Finally, the PWM pins are changed back to output mode to allow PWM control.
This function waits for the beginning of the next PWM cycle to ensure smooth transitions between different PWM modes and avoid shoot-through conditions.
This function performs block commutation according to the specified direction of rotation and the hall sensor input. Block commutation is used to control motor phases during operation.
direction | Direction of rotation (DIRECTION_FORWARD or DIRECTION_REVERSE). |
hall | Hall sensor input value corresponding to the rotor position. |
This function reads the hall sensor inputs and converts them into a number ranging from 1 to 6, where the hall sensors' states are represented as bits: H3|H2|H1.
0 | Illegal hall state. Possible hardware error. |
1-6 | Valid hall sensor values. |
7 | Illegal hall state. Possible hardware error. |
Running this function triggers a reading of the direction input pin. The desiredDirection flag is set accordingly.
Calling this function with the last two hall sensor values as parameters triggers an update of the global actualDirection flag.
lastHall | The previous hall sensor value. |
newHall | The current hall sensor value. |
Definition at line 823 of file main.ino.
|
static |
Initializes the ADC.
This function initializes the ADC for speed reference, current and gate voltage measurements.
The function performs self-tests to ensure the ADC's accuracy:
If any of the self-tests fail, a fatal error is indicated.
After self-testing, the ADC is configured for speed reference measurements and set to trigger on ADC_TRIGGER.
Definition at line 538 of file main.ino.
|
static |
Perform a single ADC conversion.
This function initiates a single ADC conversion to measure a voltage. It waits for the conversion to complete and then reads the ADC result.
Definition at line 624 of file main.ino.
|
static |
Initializes motorConfigs.
This function initializes motorConfigs to their default values.
Definition at line 368 of file main.ino.
|
static |
Disable motor.
This function disables the motor by clearing the enable flag and performing specific actions based on the TURN_OFF_MODE configuration:
Definition at line 683 of file main.ino.
|
static |
Check whether the enable pin is set and update flags accordingly.
This function checks the state of the enable pin and updates the motorFlags and faultFlags accordingly. If the enable pin is not set, it can perform specific actions based on the TURN_OFF_MODE configuration:
Definition at line 657 of file main.ino.
|
static |
Handle a fatal error and enter a fault state.
This function is called in response to a fatal error condition. It performs the following actions:
Definition at line 805 of file main.ino.
|
static |
Initializes motorFlags and faultFlags.
This function initializes both motorFlags and faultFlags to their default values.
Definition at line 341 of file main.ino.
if | ( | direction | = = 0 | ) |
Definition at line 893 of file main.ino.
void loop | ( | ) |
Main Loop Function.
The main loop function is executed continuously in normal operation after the program has configured everything. It continually checks if the speed controller needs to be run.
Definition at line 323 of file main.ino.
|
static |
Initialize pin change interrupts.
This function initializes pin change interrupt on hall sensor input pins input, shutdown input and motor direction control input.
Definition at line 502 of file main.ino.
|
static |
Initialize PLL (Phase-Locked Loop)
This function configures and initializes the PLL for clock generation. It sets the PLL frequency control register and waits until the PLL is locked and stable before returning.
Definition at line 383 of file main.ino.
|
static |
Initialize I/O port directions and pull-up resistors.
This function initializes all I/O ports with the correct directions and enables pull-up resistors, if needed, for various pins and signals used in the motor control.
Definition at line 409 of file main.ino.
|
static |
Check whether the remote pin is set and update flags accordingly.
This function checks the state of the remote pin and updates the motorFlags.
Definition at line 703 of file main.ino.
void setup | ( | void | ) |
Main initialization function.
The main initialization function initializes all subsystems needed for motor control.
Definition at line 267 of file main.ino.
|
static |
Speed regulator loop.
This function is called periodically every SPEED_CONTROLLER_TIME_BASE ticks. In this implementation, a simple PID controller loop is called, but this function could be replaced by any speed or other regulator.
If the SPEED_CONTROL_METHOD is set to SPEED_CONTROL_CLOSED_LOOP, a PID controller is used to regulate the speed. The speed input is converted into an increment set point, and a PID controller computes the output value. The output is limited to a maximum value of 255.
If the SPEED_CONTROL_METHOD is not set to SPEED_CONTROL_CLOSED_LOOP, a simple speed control mechanism is applied. If the motor is enabled, the function calculates the delta between the speed input and the current speed output. If the delta exceeds the maximum allowed change, it limits the change to SPEED_CONTROLLER_MAX_DELTA. If the motor is disabled, the speed output is set to 0.
Definition at line 740 of file main.ino.
void TimersInit | ( | void | ) |
Initializes and synchronizes Timers.
This function sets the correct pre-scaler and starts all required timers.
Timer 1 is used to trigger the fault multiplexing on overflow. Timer 3 is used, if EMULATE_HALL is set, to trigger the change in hall output on overflow. Timer 4 is used to generate PWM outputs for the gates and trigger the commutation tick counter and check if the motor is spinning on overflow. The overflow event interrupt for Timer 4 is set outside this function at the end of the main initialization function.
Timer 0 is used by the Ardiono core to generate interrupts. For reference, it is set up in mode 3 (Fast PWM, TOP=0xFF) with a prescaler of 64. This means ovwerflow occurs ~977 times per second. The overflow interrupt is used to trigger the ADC conversion unless changed by the user.
Definition at line 457 of file main.ino.
volatile uint16_t commutationTicks = 0 |
The number of 'ticks' between two hall sensor changes (counter).
This variable is used to count the number of 'ticks' between each hall sensor change. It is cleared when the hall sensor change occurs. One 'tick' is one PWM period.
else |
volatile uint16_t ibus = 0 |
Hi-side Current (IBUS) measurement (Register Value).
The most recent current measurement is stored in this variable.
The range is 0-1023.
This value is not scaled and represents the raw ADC register value. To obtain the scaled current value in amperes, you can use the formula:
\[ \text{Current (A)} = \frac{\text{REGISTER_VALUE} \times 0.004888 \times 1000000}{\text{IBUS_GAIN} \times \text{IBUS_SENSE_RESISTOR}} \]
Where:
The NEVB-MTR1-I56-1 comes with a current op-amp with a gain factor of 50 and a current sense resistor of value 4 mΩ. This corresponds to approximately 0.0244 amperes (A) per register value.
volatile int16_t iphaseU = 0 |
In-line Phase U current current measurement (Register Value).
The most recent current measurement is stored in this variable.
The range is 0-1023.
This value is not scaled and represents the raw ADC register value. To obtain the scaled current value in amperes, you can use the formula:
\[ \text{Current (A)} = \frac{\text{REGISTER_VALUE} \times 0.004888 \times 1000000}{\text{IBUS_GAIN} \times \text{IBUS_SENSE_RESISTOR}} \]
Where:
The NEVB-MTR1-I56-1 comes with a current op-amp with a gain factor of 20 and a current sense resistor of value 2.5 mΩ. This corresponds to approximately TODO: amperes (A) per register value.
volatile int16_t iphaseV = 0 |
In-line Phase V current current measurement (Register Value).
The most recent current measurement is stored in this variable.
The range is 0-1023.
This value is not scaled and represents the raw ADC register value. To obtain the scaled current value in amperes, you can use the formula:
\[ \text{Current (A)} = \frac{\text{REGISTER_VALUE} \times 0.004888 \times 1000000}{\text{IBUS_GAIN} \times \text{IBUS_SENSE_RESISTOR}} \]
Where:
The NEVB-MTR1-I56-1 comes with a current op-amp with a gain factor of 20 and a current sense resistor of value 2.5 mΩ. This corresponds to approximately TODO: amperes (A) per register value.
volatile int16_t iphaseW = 0 |
In-line Phase W current current measurement (Register Value).
The most recent current measurement is stored in this variable.
The range is 0-1023.
This value is not scaled and represents the raw ADC register value. To obtain the scaled current value in amperes, you can use the formula:
\[ \text{Current (A)} = \frac{\text{REGISTER_VALUE} \times 0.004888 \times 1000000}{\text{IBUS_GAIN} \times \text{IBUS_SENSE_RESISTOR}} \]
Where:
The NEVB-MTR1-I56-1 comes with a current op-amp with a gain factor of 20 and a current sense resistor of value 2.5 mΩ. This corresponds to approximately TODO: amperes (A) per register value.
volatile uint16_t lastCommutationTicks = 0xffff |
The number of 'ticks' between two hall sensor changes (store).
This variable is used to store the number of 'ticks' between each hall sensor change. It is set to the value in commutationTicks before it is cleared when the hall sensor change occurs.
One 'tick' is one PWM period. The speed of the motor is inversely proportional to this value.
volatile motorconfigs_t motorConfigs |
volatile uint8_t speedInput = 0 |
volatile uint8_t speedOutput = 0 |
volatile uint16_t vbusVref = 0 |
VBUS voltage measurement (Register Value)
The most recent VBUS voltage measurement is stored in this variable.
The range is 0-1023.
This value is not scaled and represents the raw ADC register value. To obtain the scaled VBUS voltage in volts, you can use the formula:
\[ \text{Voltage (V)} = \frac{\text{REGISTER_VALUE} \times 0.004888 \times (\text{VBUS_RTOP} + \text{VBUS_RBOTTOM})}{\text{VBUS_RBOTTOM}} \]
Where:
The NEVB-MTR1-C-1 has a resistor divider with RTOP of 100 kΩ and RBOTTOM of 6.2 kΩ, so it corresponds to approximately 0.0837 volts (V) per register value.