|
Motor Driver Evaluation Kit NEVB-MTR1-t01-1.1.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 | |
| 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 void | SetDuty (const uint16_t duty) |
| Set duty cycle for TIM4. | |
| static void | TimersSetModeBlockCommutation (void) |
| Configures timers for block commutation. | |
| static void | TimersWaitForNextPWMCycle (void) |
| Wait for the start of the next PWM cycle. | |
| static void | BlockCommutate (const uint8_t direction, uint8_t hall) |
| Perform block commutation based on direction and hall sensor input. | |
| static uint8_t | GetHall (void) |
| Read the hall sensor inputs and decode the hall state. | |
| static void | DesiredDirectionUpdate (void) |
| Updates global desired direction flag. | |
| static void | ActualDirectionUpdate (uint8_t lastHall, const uint8_t newHall) |
| Update the global actual direction flag based on the two latest hall values. | |
| static void | ReverseRotationSignalUpdate (void) |
| Update the reverse rotation flag. | |
| static void | EnablePWMOutputs (void) |
| Enable PWM output pins. | |
| static void | DisablePWMOutputs (void) |
| Disable PWM output pins. | |
| static void | ClearPWMPorts (void) |
| Clear PWM output ports. | |
| static void | CommutationTicksUpdate (void) |
| Update the 'tick' counter and check for a stopped motor. | |
| ISR (INT0_vect) | |
| Enable interrupt service routine. | |
| ISR (PCINT0_vect) | |
| Hall sensor change interrupt service routine. | |
| ISR (INT2_vect) | |
| Direction input change interrupt service routine. | |
| ISR (TIMER4_OVF_vect) | |
| Timer4 Overflow Event Interrupt Service Routine. | |
| ISR (TIMER1_OVF_vect) | |
| Timer1 Overflow Interrupt Service Routine. | |
| ISR (ADC_vect) | |
| ADC Conversion Complete Interrupt Service Routine. | |
| static void | SetFaultFlag (fault_flag_t flag, uint8_t value) |
| Sets a fault flag value. | |
Variables | |
| volatile motorflags_t | motorFlags |
| Motor control flags placed in I/O space for fast access. | |
| volatile faultflags_t | faultFlags |
| Fault flags placed in I/O space for fast access. | |
| 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) | |
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.
|
static |
Update the global actual direction flag based on the two latest hall values.
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 943 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 536 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 600 of file main.ino.
|
static |
Perform block commutation based on direction and hall sensor input.
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. |
Definition at line 865 of file main.ino.
|
static |
Clear PWM output ports.
This function clears the PWM output ports by setting the corresponding bits of the port registers to low. It effectively turns off the PWM signals on the specified ports while leaving the port directions unchanged.
Definition at line 1018 of file main.ino.
|
static |
Update the 'tick' counter and check for a stopped motor.
This function should be called at every PWM timer overflow to update the 'tick' counter. It increments the 'tick' counter until it reaches the maximum tick limit, indicating a potentially stopped or stalled motor. If the limit is reached, the global motor stopped flag is set.
Definition at line 1040 of file main.ino.
|
static |
Initializes motorConfigs.
This function initializes motorConfigs to their default values.
Definition at line 366 of file main.ino.
|
static |
Updates global desired direction flag.
Running this function triggers a reading of the direction input pin. The desiredDirection flag is set accordingly.
Definition at line 918 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 659 of file main.ino.
|
static |
Disable PWM output pins.
This function disables PWM outputs by setting the port direction for all PWM pins as inputs. This action overrides the PWM signals, effectively stopping the generation of PWM. The PWM configuration itself remains unchanged.
Definition at line 1005 of file main.ino.
|
static |
Enable PWM output pins.
This function sets the port direction for all PWM pins as output, allowing PWM signals to be generated on these pins. It does not modify the PWM configuration itself.
Definition at line 992 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 633 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 781 of file main.ino.
|
static |
Initializes motorFlags and faultFlags.
This function initializes both motorFlags and faultFlags to their default values.
Definition at line 339 of file main.ino.
|
static |
Read the hall sensor inputs and decode the hall state.
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. |
Definition at line 903 of file main.ino.
| ISR | ( | ADC_vect | ) |
ADC Conversion Complete Interrupt Service Routine.
This interrupt service routine is automatically executed every time an AD conversion is finished, and the converted result is available in the ADC data register.
The switch/case construct ensures that the converted value is stored in the variable corresponding to the selected channel and changes the channel for the next ADC measurement.
Additional ADC measurements can be added to the cycle by extending the switch/case construct.
Definition at line 1263 of file main.ino.
| ISR | ( | INT0_vect | ) |
Enable interrupt service routine.
This interrupt service routine is called if the enable pin changes state.
Definition at line 1101 of file main.ino.
| ISR | ( | INT2_vect | ) |
Direction input change interrupt service routine.
This interrupt service routine is called every time the direction input pin changes state. The motor is stopped and the desired direction flag is updated accordingly. The motor will not start again until the enable pin is turned on again.
Definition at line 1156 of file main.ino.
| ISR | ( | PCINT0_vect | ) |
Hall sensor change interrupt service routine.
This interrupt service routine is called every time any of the hall sensors change. The actual direction, the reverse rotation and no hall connections flags are updated.
The motor stopped flag is also set to FALSE, since the motor is obviously not stopped when there is a hall change.
Definition at line 1115 of file main.ino.
| ISR | ( | TIMER1_OVF_vect | ) |
Timer1 Overflow Interrupt Service Routine.
This interrupt service routine (ISR) is triggered on Timer1 overflow. It calls the faultSequentialStateMachine() function to handle motor fault reporting.
Definition at line 1244 of file main.ino.
| ISR | ( | TIMER4_OVF_vect | ) |
Timer4 Overflow Event Interrupt Service Routine.
This interrupt service routine is trigger on Timer4 overflow. It manages the commutation ticks, which determines motor status. It also controls the execution of the speed regulation loop at constant intervals.
Definition at line 1173 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 321 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 500 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 381 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 407 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 679 of file main.ino.
|
static |
Update the reverse rotation flag.
This function compares the actual and desired direction flags to determine if the motor is running in the opposite direction of what is requested.
Definition at line 974 of file main.ino.
|
static |
Set duty cycle for TIM4.
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. |
Definition at line 799 of file main.ino.
|
static |
Sets a fault flag value.
This function sets the specified fault flag to the value given.
| [in] | flags | Pointer to a faultflags_t structure. |
| [in] | flag | The fault flag to set as defined in the fault_flag_t enumeration. |
| [in] | value | The boolean value to set the fault flag to. |
Definition at line 1382 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 716 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 455 of file main.ino.
|
static |
Configures timers for block commutation.
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.
Definition at line 817 of file main.ino.
|
static |
Wait for the start of the next PWM cycle.
This function waits for the beginning of the next PWM cycle to ensure smooth transitions between different PWM modes and avoid shoot-through conditions.
Definition at line 844 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.
| volatile faultflags_t faultFlags |
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 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 motorflags_t motorFlags |
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.
| 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.