-
Notifications
You must be signed in to change notification settings - Fork 0
First draft for the thruster MCU #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jhub04
wants to merge
211
commits into
main
Choose a base branch
from
feat/thruster-mcu
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
211 commits
Select commit
Hold shift + click to select a range
504c535
Generate peripheral drivers with MCC
jhub04 fefd480
feat: enable LED as output
jhub04 2ec4fad
feat/change pwm frequency to 50Hz
jhub04 eed639e
feat/configure CAN1 TX and RX on PB12 and PB13 respectively
jhub04 a4ecb80
feat: change CAN FD bit rates
jhub04 8a237c5
feat: configure SERCOM1 as I2C master
jhub04 319c78a
feat: reconfigure tcc periods and prescalers
jhub04 251d340
feat: create table of thrusters' tcc channels
jhub04 b4cf015
feat: add method to set PWM dutycycle
jhub04 76823be
chore: disable treat warnings as errors
jhub04 f7e0abb
feat: add methods to start and stop all thrusters
jhub04 545153c
feat: configure wdt
jhub04 d89fccf
feat: clear wdt after setting pwms
jhub04 74b9392
feat: use can0 instead of can1
jhub04 db500eb
feat: create can rx and tx callbacks for debugging purposes
jhub04 1c14a23
docs: add TODO reminder to remove CAN callback methods after CAN veri…
jhub04 c422510
feat: change CAN-FD element size from 8 to 64 bytes
jhub04 2971c1f
feat: read can messages from Rx FIFO0
jhub04 2ffb14d
feat: enable WDT
jhub04 c74949d
feat: configure power manager
jhub04 c8f1147
feat: enter idle mode in main loop to reduce power consumption
jhub04 d1dfa88
feat: add CAN message handler
jhub04 8edf829
feat: add message handler function declaration and refactoring of consts
jhub04 c929b9e
refactor: make messages_to_read const
jhub04 02ce9d6
refactor: separate app logic from main.c
jhub04 f9681c4
feat: make rx and tx callbacks static
jhub04 ed4a82a
refactor: rename variable name for thruster pwm period
jhub04 f351a0a
refactor: use NVIC_SystemReset instead of manual wdt reset
jhub04 5f8db5c
refactor: rename tcc_num to instance
jhub04 5d4fdc8
feat: set light pwm period to 20000ms
jhub04 16b9e8b
feat: create method to set light pwm
jhub04 f94b623
feat: add state set_light_pwm
jhub04 f7950de
feat: pet watchdog after setting light pwm
jhub04 ffa5026
refactor: use switch statement instead of hardcoded tcc instance for …
jhub04 bdbd88a
refactor: rename light to lights
jhub04 e3ce66b
docs: add TODO reminder to clamp tcc value
jhub04 cb2eeb0
style: remove leading whitespace
jhub04 12ddaff
feat: add clamping for thrusters and lights
jhub04 913a34d
refactor: extract switch for setting tcc into function
jhub04 fae6149
refactor: rename duty_cycle to us and tcc_value to ticks
jhub04 a573447
refactor: rename tcc period to tcc period_ticks
jhub04 14e5b9e
refactor: extract separate function to convert pulse us to ticks
jhub04 2432bc8
refactor: rename pwm period consts to us for consistent naming
jhub04 54fd486
refactor: rename us to pulse_us
jhub04 3707258
fix: stop_thrusters neutralizes thrusters
jhub04 9369b00
style: use u instead of mu symbol in comments
jhub04 e444df2
feat: set start_thrusters to no-op
jhub04 5711f2d
feat: add method to turn lights off
jhub04 dde5b12
feat: add turn lights off event
jhub04 86407a0
feat: configure ADC0 with sleep during standby
jhub04 0939222
feat: set up adc variables
jhub04 abbee2e
feat: enable ADC0 in app_init
jhub04 7697731
feat: create method to read thruster's current draw
jhub04 77528cc
feat: break out of function if overcurrent detected
jhub04 92adba2
feat: read current draw after each CAN receive
jhub04 fd7627a
refactor: add function prototype and move read_current_draw
jhub04 634548a
fix: adc actually converts now
jhub04 a9f6d14
feat: configure adc0 for adc dma sequencing
jhub04 907283f
feat: enable result ready input for adc
jhub04 f992273
feat: configure tc0 witt timer period overflow event enabled
jhub04 579e2fb
feat: configure dmac channels 0 and 1
jhub04 7d0ca86
Enable adc input control
jhub04 8748806
feat: configure evsys user and event channel
jhub04 6ed4476
feat: enable adc start event input on rising edge
jhub04 251b089
feat: disable run during standby
jhub04 f0f56e9
feat: configure adc dma sequencing
jhub04 4240764
feat: implement minimal overcurrent check
jhub04 8d1c903
feat: reduce callback time complexity
jhub04 43f3c4a
refactor: rename variable i to sample
jhub04 2842d2a
style: use consistent curly bracket indentation
jhub04 15ece22
refactor: make rated current unsigned
jhub04 1c31277
feat: add logging
jhub04 64dd3e9
fix: valid printf
jhub04 77ba63a
fix: change adc_seq_regs to uint32_t array
jhub04 b1f810b
feat: add adc average control
jhub04 2e69f24
feat: enable adc sample averaging
jhub04 2590b87
chore: remove adc averaging to avoid merge conflicts in the developme…
jhub04 d3b21fb
refactor: make clamp function easier to read
jhub04 d995048
refactor: remove unused global variable input_voltage
jhub04 192f8ea
feat: add realistic values for current monitoring
jhub04 39cfba2
feat: configure adc pins for testing
jhub04 d63ce3a
feat: add debugging prints
jhub04 3849a28
test: current readings on a simple circuit
jhub04 c18e3bc
feat: configure CAN1
jhub04 3a2a94a
Reconfigure can states and import some function from demo
jhub04 14f0327
fix: handle can frames correctly
jhub04 9ec25d0
feat: implement can id check
jhub04 c8c5975
feat: improve can receive callback
jhub04 6a56c90
feat: add debugging prints to can transmit callback
jhub04 93e4990
refactor: remove unused demo functions
jhub04 35702b6
style: remove outdated comments
jhub04 17c7d65
refactor: remove unused functions turn_thrusters_on and turn_lights_on
jhub04 01ad09b
feat: configure tcc0 pin
jhub04 66d9704
feat: update can1 configuration
jhub04 ac7b283
feat: change tcc0/1 period to 75000ms
jhub04 5169d3a
fix: initialize PWM
jhub04 7356cc1
feat: only enter message_handler after received flag is true
jhub04 78fc231
refactor: add debugging statements
jhub04 64712e9
Set thrusters and lights to neutral on initialization
jhub04 f08aadc
refactor: check adc_dma_done before entering overcurrent check
jhub04 5fa600a
Merge branch 'main' into feat/thruster-mcu
jhub04 327afa9
refactor: use plib function to retrieve pwm period instead of hardcod…
jhub04 68f1c77
fix: mcc merge conflict
jhub04 211115f
refactor: call turn_thrusters_off directly instead of setting flag
jhub04 311ff4d
style: space out switch statement
jhub04 3f96af0
refactor: remove all printf's
jhub04 774acc1
revert: use hardcoded values for tccx period
jhub04 45aefea
refactor: remove unused can state enum
jhub04 ac54230
feat: configure can to automatically handle id filtering
jhub04 ca6f4fb
refactor: directly map can states enum to the ID's
jhub04 5ab88db
refactor: use snake-case for structs and use structs instead of typedefs
jhub04 ac9fba7
style: more precise comment
jhub04 78b7342
refactor: remove sys_tasks function in main loop
jhub04 bd204fb
docs: add Doxygen comments to utility functions
jhub04 c98c6c1
refactor: rename functions to snake_case for consistency
jhub04 26c79f8
refactor: move hardware constants to local scope in check_overcurrent()
jhub04 8e3189c
refactor: move defines after include and before constants
jhub04 862455d
refactor: combine thruster and light struct into one generic struct
jhub04 9c5f514
refactor: combine set_thruster_pwm and set_light_pwm into one generic…
jhub04 0064529
refactor: combine turn_thrusters_off and turn_lights_off into one gen…
jhub04 55a0079
docs: add TODO reminder to send can transmit on overcurrent fault
jhub04 0be419e
feat: transmits fault message over CAN if overcurrent flagged
jhub04 b53c999
fix: initialize txBuffer to txFiFo after zeroing out
jhub04 f977211
feat: transmit 64 bytes instead of 7 bytes
jhub04 c907323
refactor: log error if can message transmit fails
jhub04 5853718
feat: enable can timestamps
jhub04 a1bc772
fix: read CAN data in little-endian format instead of big-endian
jhub04 70687f7
refactor: send 8 byte payload instead of 64 bytes
jhub04 a84dce5
refactor: include min_us, max_us, neutral_us and frame_us as part of …
jhub04 7707b09
feat!: migrate from SAME54P20A to SAMC21J18A
jhub04 81b52a7
fix: reenable WDT
jhub04 268a38b
feat: configure DMAC for adc sleepwalking
jhub04 0d15d1a
refactor: initialize adc before dma
jhub04 3581609
feat: add simple adc dma callback
jhub04 2cbf740
feat: register DMAC callback and transfer protocol
jhub04 5ddca2f
feat: adc averaging of 1024 samples
jhub04 1eb1392
feat: configure pins for the SAMC21 Xplained Pro
jhub04 63c2778
feat: enable starte event input on rising edge
jhub04 bcde4c1
feat: configure EIC
jhub04 b4a9e1e
feat: configure eic interrupt line on debboard pin
jhub04 041ee58
feat: configure ISR for EXTINT0
jhub04 439fcdf
feat: configure 8 EXTINT channels
jhub04 a4da8ba
feat: register callback for all EXTINT channels
jhub04 73d3846
fix: correct function call
jhub04 d95e772
fix: re-arm DMA for next conversion
jhub04 e6f6e9e
refactor: uncomment check_overcurrent()
jhub04 add545d
fix: miscellaneous issues
jhub04 b177de5
fix: reconfigure dmac
jhub04 ab6e233
fix: create new project
jhub04 2c662f1
fix: duplicated project
jhub04 e1ac622
fix: add app.h include in main.c
jhub04 3bdf716
refactor: remove comment to remember average sampling
jhub04 dfedf62
fix: implement correct padding for thruster fault transmission
jhub04 70be031
feat: configure TCC2
jhub04 2644739
feat: configure eight independent PWM output pins
jhub04 41ccfda
feat: configure killswitch pin as input
jhub04 f3fbdb2
feat: configure TC3 and light PWM pi (PWM_9)
jhub04 6b1cf6e
feat: enable external interrupt for killswitch
jhub04 f1a1db4
feat: configure PG_THx pins as input
jhub04 ba63432
feat: configure CAN1 TX and RX pins
jhub04 85e0301
feat: configure FLT_THx pins
jhub04 3da48b2
feat: configure IMON_THx
jhub04 965ba39
feat: configure RESET_TH
jhub04 b7218b4
feat: add PWM writer for TCC2
jhub04 f49515f
fix: update pwm_ouput struct with updated pwm outputs
jhub04 8cec09a
feat: enable ADC AIN pins
jhub04 a77e798
feat: configure TC3 with MPWM
jhub04 16bb47f
fix: correct period_ticks for pwm_outputs
jhub04 f202775
fix: separate TCC and TC outputs
jhub04 699ed41
fix: only update CC1 for TC
jhub04 9833866
fix: correct instance and channel of lights struct
jhub04 1926b3c
feat: adjust TC3 period
jhub04 4965289
fix: initialize TCC2
jhub04 cf98d7b
fix: initialize TC3
jhub04 384115e
test: simple pmw signal for TCC0 and TCC1
jhub04 ba6a1ad
fix: clear wdt after pwm set
jhub04 9a31be6
test: current attempt of TC3 MPWM generation
jhub04 4957110
refactor: update pins according to new schematic
jhub04 a540bf8
feat: reconfigure pin config to utilize all interrupts
jhub04 8b20a6c
feat: enable NMI control for EIC
jhub04 f8a5a7d
feat: enable callbacks for killswitch and flt pins
jhub04 041a951
feat: remove software overcurrent check and log IMON output
jhub04 8637f88
feat: simplify send_thruster_fault() to just log thruster no
jhub04 491e08e
fix: correct implementation of raw ADC data conversion
jhub04 3fda5d2
fix: use WO1 as output channel for TC3
jhub04 b2a15cc
docs: update TCC testing reminder
jhub04 1496b28
fix: configure usart and reset thrusters pins
jhub04 114c9d5
fix: correct configuration of TCC0
jhub04 0c0829d
fix: correct configuration of all TCC instances
jhub04 e1e1f85
fix: correct CAN config
jhub04 37b76f4
fix: update R_IMON to correct value
jhub04 7dea121
fix: configure ADC sleepwalking correctly
jhub04 76fdfab
refactor: move ADC conversion start into app_task()
jhub04 33d86b7
refactor: move initial conversion start into app_init()
jhub04 d5c8c8b
fix: disable adc result averaging
jhub04 54cc0a3
feat: enable interrupts for pgood pins
jhub04 2694d71
feat: log_current() prints correct IMON order
jhub04 771acda
feat: make thruster and light table const
jhub04 06a7a76
fix: update efuse resistance to updated value
jhub04 95f7086
feat: add corresponding pwm value for adc readings
jhub04 fed7534
feat: update thruster table to go in increasing thruster order
jhub04 aac89b6
docs: remove unneccessary comment
jhub04 9adc4e8
feat: dispatch hardware event cna messages
jhub04 eb5102c
refactor: delete dead send_thruster_fault function
jhub04 5310337
feat: send can message with current measurements
jhub04 e29b084
refactor: move can tx logic out of log_current()
jhub04 641cc0a
feat: handle lights in set_pwm_neutral()
jhub04 92602ea
fix: matching channel numbers for thruster id's
jhub04 21588cb
feat: increase WDT period
jhub04 1db4474
refactor: remove pure test functions
jhub04 6257943
refactor: remove newline print
jhub04 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,396 @@ | ||
| #include <string.h> | ||
| #include <stdbool.h> | ||
| #include <stddef.h> | ||
| #include "definitions.h" | ||
| #include "app.h" | ||
|
|
||
| #define WRITE_ID(id) (id << 18) | ||
| #define READ_ID(id) (id >> 18) | ||
|
|
||
| #define TRANSFER_SIZE 16 | ||
|
|
||
| /* --- Constants --- */ | ||
| static const uint32_t TCC0_PERIOD = 75000U; | ||
| static const uint32_t TCC1_PERIOD = 75000U; | ||
| static const uint32_t TCC2_PERIOD = 18500U; | ||
| static const uint32_t THRUSTER_PWM_PERIOD_US = 20000U; // 50Hz | ||
| static const uint32_t LIGHT_PWM_PERIOD_US = 20000U; // 50Hz | ||
|
|
||
| /* --- Types --- */ | ||
| struct pwm_output { | ||
| uint8_t instance; | ||
| uint8_t channel; | ||
| uint32_t period_ticks; | ||
| uint16_t min_us; | ||
| uint16_t max_us; | ||
| uint16_t neutral_us; | ||
| uint32_t frame_us; | ||
| }; | ||
|
|
||
| enum can_events { | ||
| TURN_THRUSTERS_OFF = 0x369, | ||
| TURN_LIGHTS_OFF = 0x36A, | ||
| RESET = 0x36B, | ||
| SET_THRUSTER_PWM = 0x36C, | ||
| SET_LIGHT_PWM = 0x36D | ||
| }; | ||
|
|
||
| /* --- Private states --- */ | ||
| /* CAN */ | ||
| static uint8_t Can1MessageRAM[CAN1_MESSAGE_RAM_CONFIG_SIZE] __attribute__((aligned(32))); | ||
|
|
||
| static volatile uint32_t can_status = 0; | ||
| static volatile bool can_message_received = false; | ||
|
|
||
| static uint8_t txFiFo[CAN1_TX_FIFO_BUFFER_SIZE]; | ||
| static uint8_t rxFiFo0[CAN1_RX_FIFO0_SIZE]; | ||
|
|
||
| /* ADC */ | ||
| static volatile bool adc_dma_done = false; | ||
| static uint16_t adc_result_array[TRANSFER_SIZE]; | ||
|
|
||
|
|
||
| /* Application */ | ||
| static struct pwm_output thrusters[8] = { | ||
| {0, 0, TCC0_PERIOD, 1000, 2000, 1500, THRUSTER_PWM_PERIOD_US}, // TCC0_CHANNEL0 | ||
| {0, 1, TCC0_PERIOD, 1000, 2000, 1500, THRUSTER_PWM_PERIOD_US}, // TCC0_CHANNEL1 | ||
| {0, 2, TCC0_PERIOD, 1000 ,2000, 1500, THRUSTER_PWM_PERIOD_US}, // TCC0_CHANNEL2 | ||
| {0, 3, TCC0_PERIOD, 1000 ,2000, 1500, THRUSTER_PWM_PERIOD_US}, // TCC0_CHANNEL3 | ||
| {0, 4, TCC0_PERIOD, 1000 ,2000, 1500, THRUSTER_PWM_PERIOD_US}, // TCC0_CHANNEL4 | ||
| {0, 5, TCC0_PERIOD, 1000 ,2000, 1500, THRUSTER_PWM_PERIOD_US}, // TCC0_CHANNEL5 | ||
| {1, 0, TCC1_PERIOD, 1000 ,2000, 1500, THRUSTER_PWM_PERIOD_US}, // TCC1_CHANNEL0 | ||
| {1, 1, TCC1_PERIOD, 1000 ,2000, 1500, THRUSTER_PWM_PERIOD_US} // TCC1_CHANNEL1 | ||
| }; | ||
|
|
||
| static struct pwm_output lights[1] = {{1, 2, TCC1_PERIOD, 1100, 1900, 1100, LIGHT_PWM_PERIOD_US}}; // TCC1_CHANNEL2 | ||
|
|
||
| /* --- Private function prototypes --- */ | ||
|
|
||
| /** | ||
| * @brief Sets PWM pulse widths for multiple PWM outputs (e.g Thrusters and/or lights). | ||
| * | ||
| * Parses the data buffer containing pulse width values, | ||
| * clamps each to the valid range, and updates the corresponding PWM channels. | ||
| * | ||
| * @param data Pointer to buffer containing pulse widths in microseconds (format: [MSB, LSB] per output) | ||
| * @param outputs Pointer to array of pwm_output structs | ||
| * @param count Number of outputs to set | ||
| */ | ||
| static void set_pwm_outputs(const uint8_t *data, struct pwm_output *outputs, size_t count); | ||
|
|
||
| /** | ||
| * @brief Handles incoming CAN messages and dispatches them to their corresponding action. | ||
| */ | ||
| static void message_handler(void); | ||
|
|
||
| /** | ||
| * @brief Monitors thruster current draw and shuts down on overcurrent condition. | ||
| * | ||
| * Reads ADC samples for all 8 thruster channels, calculates output current from | ||
| * the voltage, and disables all thrusters if any channel exceeds the rated current limit. | ||
| */ | ||
| static void check_overcurrent(void); | ||
|
|
||
| /** | ||
| * @brief Sends an overcurrent fault message over CAN | ||
| * | ||
| * Constructs and transmits a 7-byte CAN FD fault message containing diagnostic information about the fault condition. | ||
| * | ||
| * @param thruster_id Thruster identifier (0-7) | ||
| * @param current Measured current value in Amperes | ||
| * @param adc_raw Raw ADC reading | ||
| * @return true if message was transmitted successfully, false if not | ||
| */ | ||
| static bool send_thruster_fault(uint8_t thruster_id, float current, uint16_t adc_raw); | ||
|
|
||
| /** | ||
| * @brief Sets PWM outputs to their neutral/off position | ||
| * | ||
| * @param outputs Pointer to array of pwm_output structs | ||
| * @param count Number of outputs to set | ||
| */ | ||
| static void set_pwm_neutral(struct pwm_output *outputs, size_t count); | ||
|
|
||
| /** | ||
| * @brief Clamps a value between a minimum and maximum bound. | ||
| * | ||
| * @param value The value to clamp | ||
| * @param low The lower bound (inclusive) | ||
| * @param high The higher bound (inclusive) | ||
| * @return The clamped value: low if value < low, high if value > high, otherwise value | ||
| */ | ||
| static inline uint16_t clamp(uint16_t value, uint16_t low, uint16_t high); | ||
|
|
||
| /** | ||
| * @brief Write PWM duty cycle to the specified TCC instance and channel. | ||
| * | ||
| * Routes the PWM write to the appropriate TCC peripheral based on instance number. | ||
| * | ||
| * @param instance TCC instance number (0, 1 or 2) | ||
| * @param channel PWM channel number within the instance | ||
| * @param ticks Duty cycle value in timer ticks | ||
| */ | ||
| static inline void tcc_write(uint8_t instance, uint8_t channel, uint32_t ticks); | ||
|
|
||
| /** | ||
| * @brief Converts a pulse width in microseconds to timer ticks. | ||
| * | ||
| * Calculates the timer tick count needed to produce a specific pulse width | ||
| * based on the timer's period and the PWM frame duration. | ||
| * | ||
| * @param period_ticks Timer period in ticks | ||
| * @param pulse_us Desired pulse width in microseconds | ||
| * @param frame_us Total PWM frame duration in microseconds | ||
| * @return Number of timer ticks corresponding to the pulse width | ||
| */ | ||
| static inline uint32_t us_to_ticks(uint32_t period_ticks, uint16_t pulse_us, uint32_t frame_us); | ||
|
|
||
| /* Callbacks */ | ||
| static void can_receive_callback(uint8_t numberOfMessage, uintptr_t context); | ||
| static void can_transmit_callback(uintptr_t context); | ||
| static void adc_dma_callback(DMAC_TRANSFER_EVENT returned_event, uintptr_t MyDmacContext); | ||
| static void eic_pin_flt_thruster(uintptr_t context); | ||
|
|
||
| /* --- Public functions --- */ | ||
|
|
||
| void app_init(void) { | ||
| // Configure CAN RAM & callbacks | ||
| CAN1_MessageRAMConfigSet(Can1MessageRAM); | ||
| CAN1_RxFifoCallbackRegister(CAN_RX_FIFO_0, can_receive_callback, (uintptr_t)NULL); | ||
| CAN1_TxFifoCallbackRegister(can_transmit_callback, (uintptr_t)NULL); | ||
|
|
||
| // Configure external interrupts | ||
| EIC_CallbackRegister(EIC_PIN_0, eic_pin_flt_thruster, 0); | ||
| EIC_CallbackRegister(EIC_PIN_1, eic_pin_flt_thruster, 1); | ||
| EIC_CallbackRegister(EIC_PIN_2, eic_pin_flt_thruster, 2); | ||
| EIC_CallbackRegister(EIC_PIN_3, eic_pin_flt_thruster, 3); | ||
| EIC_CallbackRegister(EIC_PIN_4, eic_pin_flt_thruster, 4); | ||
| EIC_CallbackRegister(EIC_PIN_5, eic_pin_flt_thruster, 5); | ||
| EIC_CallbackRegister(EIC_PIN_6, eic_pin_flt_thruster, 6); | ||
| EIC_CallbackRegister(EIC_PIN_7, eic_pin_flt_thruster, 7); | ||
|
|
||
| ADC0_Enable(); // TODO: Remember to manually configure sample averaging in plib_adc0 before testing | ||
|
|
||
| // Configure DMA | ||
| DMAC_ChannelCallbackRegister(DMAC_CHANNEL_0, adc_dma_callback, 0); | ||
| DMAC_ChannelTransfer(DMAC_CHANNEL_0, (const void *)&ADC0_REGS->ADC_RESULT, (const void *)adc_result_array, sizeof(adc_result_array)); | ||
|
|
||
| TCC0_PWMStart(); | ||
| TCC1_PWMStart(); | ||
| //TCC2_PWMStart(); | ||
|
|
||
| // Set all thrusters and lights to neutral on startup | ||
| set_pwm_neutral(thrusters, 8); | ||
| set_pwm_neutral(lights, 1); | ||
|
|
||
|
|
||
|
|
||
| TC0_TimerStart(); | ||
|
|
||
| // Enable watchdog | ||
| WDT_Enable(); | ||
| } | ||
|
|
||
| void app_task(void) { | ||
| if (adc_dma_done) { | ||
| adc_dma_done = false; | ||
| check_overcurrent(); | ||
| } | ||
|
|
||
| if (can_message_received) { | ||
| can_message_received = false; | ||
| message_handler(); | ||
| } | ||
| } | ||
|
|
||
| /* --- Private helpers --- */ | ||
|
|
||
| static void message_handler(void) { | ||
| // Interpret event from CAN frame id | ||
| CAN_RX_BUFFER *rxBuf = (CAN_RX_BUFFER *)rxFiFo0; | ||
|
|
||
| uint32_t id = rxBuf->xtd ? rxBuf->id : READ_ID(rxBuf->id); | ||
| const uint8_t *pData = rxBuf->data; | ||
|
|
||
| switch (id) { | ||
| case TURN_THRUSTERS_OFF: | ||
| set_pwm_neutral(thrusters, 8); | ||
| break; | ||
|
|
||
| case TURN_LIGHTS_OFF: | ||
| set_pwm_neutral(lights, 1); | ||
| break; | ||
|
|
||
| case RESET: | ||
| /* Force a system reset */ | ||
| NVIC_SystemReset(); | ||
| break; | ||
|
|
||
| case SET_THRUSTER_PWM: | ||
| set_pwm_outputs(pData, thrusters, 8); | ||
| break; | ||
|
|
||
| case SET_LIGHT_PWM: | ||
| set_pwm_outputs(pData, lights, 1); | ||
| break; | ||
|
|
||
| default: | ||
| /* Unknown event: ignore */ | ||
| break; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| static void check_overcurrent(void) { | ||
| const float ADC_VREF = 3.3f; | ||
| const float G_IMON = 18.18e-6f; // Amplifier gain 18.18 uA/A -> in A/A | ||
| const float R_IMON = 2550.0f; // 2.55 kilo ohms resistor | ||
| const uint8_t THRUSTER_RATED_CURRENT = 15U; // From TSD7 datasheet | ||
|
|
||
| for (size_t sample = 0; sample < 8; sample++) { | ||
| float V_Imon = (float)adc_result_array[sample] * ADC_VREF / 65535U; | ||
| float I_out = V_Imon / (G_IMON * R_IMON); | ||
|
|
||
| //printf("raw=%u V_Imon=%.4f V I_out=%.3f A\r\n",(unsigned)adc_result_array[sample], (double)((float)adc_result_array[sample]*ADC_VREF/4095.0f), (double)I_out); | ||
| if (I_out > THRUSTER_RATED_CURRENT) { | ||
| set_pwm_neutral(thrusters, 8); | ||
|
|
||
| if (!send_thruster_fault(sample, I_out, adc_result_array[sample])) { | ||
| // Handle retransmission? | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static bool send_thruster_fault(uint8_t thruster_id, float current, uint16_t adc_raw) { | ||
| CAN_TX_BUFFER *txBuffer = NULL; | ||
|
|
||
| memset(txFiFo, 0x00, CAN1_TX_FIFO_BUFFER_SIZE); | ||
| txBuffer = (CAN_TX_BUFFER*)txFiFo; | ||
|
|
||
| txBuffer->id = WRITE_ID(0x45A); // Just a random ID | ||
| txBuffer->dlc = 8; // DLC 8 -> 8 Byte Payload | ||
| txBuffer->fdf = 1; | ||
| txBuffer->brs = 1; | ||
|
|
||
| txBuffer->data[0] = thruster_id; | ||
| txBuffer->data[1] = 0x00; // Padding for alignment | ||
| memcpy(&txBuffer->data[2], ¤t, sizeof(float)); | ||
| memcpy(&txBuffer->data[6], &adc_raw, sizeof(uint16_t)); | ||
|
|
||
| bool result = CAN1_MessageTransmitFifo(1, txBuffer); | ||
| if (!result) { | ||
| printf("ERROR: CAN1_MessageTransmitFifo failed!\r\n"); | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
|
|
||
| static void set_pwm_outputs(const uint8_t *data, struct pwm_output *outputs, size_t count) { | ||
| const uint16_t *pulse_data = (const uint16_t *)data; | ||
| for (size_t i = 0; i < count; i++) { | ||
|
|
||
| uint16_t pulse_us = pulse_data[i]; | ||
|
|
||
| pulse_us = clamp(pulse_us, outputs[i].min_us, outputs[i].max_us); | ||
|
|
||
| uint32_t ticks = us_to_ticks(outputs[i].period_ticks, pulse_us, outputs[i].frame_us); | ||
|
|
||
| tcc_write(outputs[i].instance, outputs[i].channel, ticks); | ||
| } | ||
|
|
||
| // Pet the watchdog after applying updates | ||
| WDT_Clear(); | ||
| } | ||
|
|
||
| static void set_pwm_neutral(struct pwm_output *outputs, size_t count) { | ||
| for (size_t i = 0; i < count; i++) { | ||
| uint32_t ticks = us_to_ticks(outputs[i].period_ticks, outputs[i].neutral_us, outputs[i].frame_us); | ||
| tcc_write(outputs[i].instance, outputs[i].channel, ticks); | ||
|
|
||
| } | ||
| WDT_Clear(); | ||
| } | ||
|
|
||
| static inline uint16_t clamp(uint16_t value, uint16_t low, uint16_t high) { | ||
| if (value < low) { | ||
| return low; | ||
| } else if (value > high) { | ||
| return high; | ||
| } else { | ||
| return value; | ||
| } | ||
|
|
||
| } | ||
|
|
||
| static inline void tcc_write(uint8_t instance, uint8_t channel, uint32_t ticks) { | ||
| switch (instance) { | ||
| case 0: | ||
| TCC0_PWM24bitDutySet(channel, ticks); | ||
| break; | ||
|
|
||
| case 1: | ||
| TCC1_PWM24bitDutySet(channel, ticks); | ||
| break; | ||
|
|
||
| case 2: | ||
| TCC2_PWM16bitDutySet(channel, (uint16_t)ticks); | ||
| break; // Not used with current mapping | ||
|
|
||
| default: | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| static inline uint32_t us_to_ticks(uint32_t period_ticks, uint16_t pulse_us, uint32_t frame_us) { | ||
| return ((uint32_t)pulse_us * (period_ticks + 1U)) / frame_us; | ||
| } | ||
|
|
||
| static void can_receive_callback(uint8_t numberOfMessage, uintptr_t context) { | ||
| // Check CAN Status | ||
| can_status = CAN1_ErrorGet(); | ||
|
|
||
| // If no new error, handle CAN frame | ||
| if (((can_status & CAN_PSR_LEC_Msk) == CAN_ERROR_NONE) || | ||
| ((can_status & CAN_PSR_LEC_Msk) == CAN_ERROR_LEC_NC)) { | ||
|
|
||
| memset(rxFiFo0, 0x00, (numberOfMessage * CAN1_RX_FIFO0_ELEMENT_SIZE)); | ||
| if (CAN1_MessageReceiveFifo(CAN_RX_FIFO_0, numberOfMessage, (CAN_RX_BUFFER *)rxFiFo0) == true) { | ||
| can_message_received = true; | ||
| // Optionally print can frame | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static void can_transmit_callback(uintptr_t context) { | ||
| // Check CAN Status | ||
| can_status = CAN1_ErrorGet(); | ||
|
|
||
| if (((can_status & CAN_PSR_LEC_Msk) == CAN_ERROR_NONE) || | ||
| ((can_status & CAN_PSR_LEC_Msk) == CAN_ERROR_LEC_NC)) { | ||
| //printf("CAN TX successful\r\n"); | ||
| } | ||
| } | ||
|
|
||
| static void adc_dma_callback(DMAC_TRANSFER_EVENT returned_event, uintptr_t MyDmacContext) { | ||
| if (returned_event == DMAC_TRANSFER_EVENT_COMPLETE) { | ||
| adc_dma_done = true; | ||
| // Re-arm DMA for next conversion | ||
| DMAC_ChannelTransfer(DMAC_CHANNEL_0, (const void *)&ADC0_REGS->ADC_RESULT, (const void *)adc_result_array, sizeof(adc_result_array)); | ||
| } | ||
| else if (returned_event == DMAC_TRANSFER_EVENT_ERROR) { | ||
| printf("ERROR: DMAC Transfer Failed!\r\n"); | ||
| } | ||
| } | ||
|
|
||
| static void eic_pin_flt_thruster(uintptr_t context) { | ||
| uint8_t thruster_id = (uint8_t)context; | ||
|
|
||
| set_pwm_neutral(thrusters, 8); | ||
|
|
||
| // TODO: Send CAN fault message (I don't have the current available so send_thruster_fault() can't be used) | ||
| } | ||
|
|
||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.