Closed npetersen2 closed 1 month ago
To validate these changes:
Test with a range of values for X
, Y
, and Z
:
X
: 1 Hz , 2000 Hz, 10 kHzY
: 20 kHz, 66 kHz, 100 kHz, 200 kHz, 1 MHzZ
: 10, 20, 50Validate the baseline default firmware still operates as expected:
X
Hz (see example on creating tasks) and toggles a GPIO pin every time it runs
a. To toggle the pin, use the gpio_direct
driver, see C code API and hw
command handler1/X
seconds.loop time
is 1/X
secondsValidate correct handling of PWM carrier frequency:
Y
kHz1/X
secondsloop time
is still 1/X
secondsValidate correct handling of PWM frequency to scheduler ratio:
20
to Z
1/X
secondsloop time
is still 1/X
seconds@annikaolson has implemented this and been testing it. Once #377 is merged, let's close this issue.
Let's close this as we have implemented this a bit differently, see latest v1.3-staging
branch commits
In the
v1.0
firmware, all tasks in the C code run in a single time slice using the cooperative scheduler in thesys/scheduler
module, read more about this here. The base scheduler time slice quantum defaults to 100 usec (10 kHz), and can be updated by the user via theusr/user_config.h
file and theSYS_TICK_FREQ
define, see here.The way this ISR is generated is by the FPGA using the Xilinx-provided Timer IP core. We have a wrapper C code API located in
drv/timer
to set up the timer and clear the ISR. This line of code is what sets up the ISR to run at the desired rate.Problem
This code works just fine: it triggers the scheduler to run at the desired rate. However, this timer is totally separate from the PWM carrier which interfaces to the motor which the AMDC is trying to drive. This creates a timing delay between when the PWM carrier operates and when the Timer module calls the scheduler. This is bad--we want the scheduler to run synchronized to the PWM carrier!
Note: the PWM carrier is a triangle wave in the FPGA (simple counter register which goes up and down). The user configures its frequency and this sets the switching frequency of the power electronics connected to the motor.
Solution
Let's align the scheduler and the PWM carrier by implementing the following:
amdc_isr_gen
pwm_carrier_high
andpwm_carrier_low
signals into this new IP corev1.0
firmware, the default PWM carrier freq is 100 kHz, but the default control rate is 10 kHz. This means the default ratio is10
drv/timer
moduletimer_init()
fromscheduler_init()
--- now it should call the new driver to set the ratio to the default10
value.usr/user_config.h
file to expose aSYS_PWM_CARRIER_CONTROL_RATIO
define which defaults to10
but allows the user to change it.sys/scheduler
internal state stays intact---it keeps track of elapsed usec in order to know when to trigger the registered tasks. The new ISR should update the scheduler state so that every still works as desired.Note: be sure to write the code remembering that the user is free to change the PWM switching frequency at any time during operation. They might change it from 100 kHz to 50 kHz or 200 kHz, etc. The new code should be able to handle this! When the user changes the PWM switching frequency, for the same ratio between control and PWM carrier, the scheduler base quantum will change! This means, each ISR from the FPGA, a different number of usec will have elapsed. You must handle this correctly for the user tasks to still be called at the correct rate.
Testing
By default, this change should be transparent to the C code. The default firmware should still run the scheduler at 10 kHz, but now the relative timing of the scheduler will be aligned to the PWM carrier triangle wave.
The user should be able to change the ratio and see their control code run at a different subrate of the PWM carrier.
Validate this by running the baseline
blink
user application and confirm that it still runs at its desired rate (i.e., 5 Hz). Use the task timing stats or thedrv/cpu_timer
to check. Change the PWM switching frequency and ensure nothing changes with the user task rate.