Initial Commit

This commit is contained in:
CarlWachter
2025-03-25 15:20:28 +01:00
commit 81a16b2acc
50 changed files with 5351 additions and 0 deletions

94
App/Inc/shared.hpp Normal file
View File

@@ -0,0 +1,94 @@
#ifndef INC_SHARED_HPP_
#define INC_SHARED_HPP_
#include <cmsis_os2.h>
#include <states.hpp>
namespace rres
{
struct LoggingData
{
uint32_t hash;
uint32_t timestamp;
uint8_t state;
uint8_t sense_fire;
uint16_t sense_adc[6];
uint8_t fired;
};
enum Event
{
TICK_10HZ = 1 << 0,
TOCK_10HZ = 1 << 1,
START_LOGGING = 1 << 2,
DUMP_FLASH = 1 << 3,
CLEAR_FLASH = 1 << 4,
FLASH_EVENT = DUMP_FLASH | CLEAR_FLASH
};
void init();
/**
* @brief Wait for any of the provided flags to be set.
*
* @note Example usage: waitForAny(GYRO | TICK_20HZ); to either wait for the 20Hz tick or new gyro data.
*
* @param event An integer with every bit representing a specific event.
* @param timeout An optional timeout for additional safety.
* @return uint32_t Returns the flags that were set.
*/
uint32_t waitForAny(uint32_t event, uint32_t timeout = osWaitForever);
/**
* @brief Wait for all of the provided flags to be set.
*
* @note Example usage: waitForAny(GYRO | TICK_20HZ); to wait for both the 20Hz tick as well as new gyro data.
*
* @param event An integer with every bit representing a specific event.
* @param timeout An optional timeout for additional safety.
* @return uint32_t Returns the flags that were set.
*/
uint32_t waitForAll(uint32_t event, uint32_t timeout = osWaitForever);
LoggingData getData();
/**
* @brief Set the sensed fire bits.
*
* @param sense_fire The sensed fire bits.
*/
void setSenseFire(uint8_t sense_fire);
/**
* @brief Set Capacitor Voltages.
*
* @param sense_adc The sensed ADC values.
*/
void setSenseADC(uint16_t sense_adc[6]);
/**
* @brief Set fired event.
*
* @param fired The fired event.
*/
void setFired(uint8_t fired);
/**
* @brief Start logging data to the flash memory.
*/
void startLogging();
/**
* @brief Dump the flash memory to the console.
*/
void dumpFlash();
/**
* @brief Clear the flash memory.
*/
void clearFlash();
} // namespace grsm
#endif /* INC_SHARED_HPP_ */

126
App/Inc/sta/config.hpp Normal file
View File

@@ -0,0 +1,126 @@
/*
* Configuration file for STA-Core.
*
* Created on: Aug 30, 2023
* Author: Dario
*/
#ifndef INC_STA_CONFIG_HPP_
#define INC_STA_CONFIG_HPP_
#define STA_STM32_ASEAG
#include <sta/devices/stm32/mcu/STM32F407xx.hpp>
// Doesn't really do too much right now. Has to be added for successful compilation.
#define STA_PRINTF_USE_STDLIB
#define STA_MCU_LITTLE_ENDIAN
#define STA_PLATFORM_STM32
// Enable debug serial output and assertions.
//#define STA_ASSERT_FORCE
#define STA_DEBUGGING_ENABLED
// Activate the timer for microsecond delays.
// #define STA_STM32_DELAY_ENABLE
// #define STA_STM32_DELAY_US_TIM htim1
// Settings for the rtos-utils
#define STA_RTOS_SYSTEM_EVENTS_ENABLE
// #define STA_RTOS_SYSTEM_WATCHDOG_ENABLE
#define STA_TACOS_CAN_BUS_ENABLED
#define STA_CAN_BUS_ENABLE
// Uses the default configuration for TACOS.
#include <sta/tacos/configs/default.hpp>
#include <states.hpp>
#include <can_ids.hpp>
#include <modules.hpp>
// Pin Definitions:
// Arming pins
// Hatch arming
#define ARMING_GROUPA GPIOE
#define ARMING_PIN_A GPIO_PIN_15
#define ARMING_GROUPB GPIOG
#define ARMING_PIN_B GPIO_PIN_0
// Main arming
#define ARMING_GROUPC GPIOA
#define ARMING_PIN_C GPIO_PIN_6
#define ARMING_GROUPD GPIOE
#define ARMING_PIN_D GPIO_PIN_0
// Main dereefing
#define ARMING_GROUPE GPIOB
#define ARMING_PIN_E GPIO_PIN_6
#define ARMING_GROUPF GPIOG
#define ARMING_PIN_F GPIO_PIN_11
// Shorting pins
// Hatch shorting
#define SHORTING_GROUPA GPIOE
#define SHORTING_PIN_A GPIO_PIN_13
#define SHORTING_GROUPB GPIOC
#define SHORTING_PIN_B GPIO_PIN_5
// Main shorting
#define SHORTING_GROUPC GPIOA
#define SHORTING_PIN_C GPIO_PIN_4
#define SHORTING_GROUPD GPIOB
#define SHORTING_PIN_D GPIO_PIN_8
// Main dereefing
#define SHORTING_GROUPE GPIOB
#define SHORTING_PIN_E GPIO_PIN_4
#define SHORTING_GROUPF GPIOG
#define SHORTING_PIN_F GPIO_PIN_9
// Fire pins
// Hatch fire
#define FIRE_DEREEFING_GROUP1 GPIOB
#define FIRE_DEREEFING_PIN_1 GPIO_PIN_10
#define FIRE_DEREEFING_GROUP2 GPIOE
#define FIRE_DEREEFING_PIN_2 GPIO_PIN_7
// Main fire
#define FIRE_MAIN_GROUP1 GPIOA
#define FIRE_MAIN_PIN_1 GPIO_PIN_7
#define FIRE_MAIN_GROUP2 GPIOE
#define FIRE_MAIN_PIN_2 GPIO_PIN_1
// Main dereefing
#define FIRE_HATCH_GROUP1 GPIOB
#define FIRE_HATCH_PIN_1 GPIO_PIN_7
#define FIRE_HATCH_GROUP2 GPIOG
#define FIRE_HATCH_PIN_2 GPIO_PIN_12
// Sense fire pins
#define SENSE_FIRE_GROUP1 GPIOE
#define SENSE_FIRE_PIN_1 GPIO_PIN_14
#define SENSE_FIRE_GROUP2 GPIOF
#define SENSE_FIRE_PIN_2 GPIO_PIN_15
#define SENSE_FIRE_GROUP3 GPIOA
#define SENSE_FIRE_PIN_3 GPIO_PIN_5
#define SENSE_FIRE_GROUP4 GPIOB
#define SENSE_FIRE_PIN_4 GPIO_PIN_9
#define SENSE_FIRE_GROUP5 GPIOB
#define SENSE_FIRE_PIN_5 GPIO_PIN_5
#define SENSE_FIRE_GROUP6 GPIOG
#define SENSE_FIRE_PIN_6 GPIO_PIN_10
#endif /* INC_STA_CONFIG_HPP_ */

26
App/Inc/tasks/arming.hpp Normal file
View File

@@ -0,0 +1,26 @@
/*
* arming.hpp
*
* Created on: Jun 17, 2024
* Author: carlos
*/
#ifndef INC_TASKS_ARMING_HPP_
#define INC_TASKS_ARMING_HPP_
#include <sta/tacos.hpp>
namespace tasks
{
class ArmingTask : public sta::tacos::TacosThread
{
public:
ArmingTask();
void init() override;
void func() override;
};
} // namespace tasks
#endif /* INC_TASKS_ARMING_HPP_ */

27
App/Inc/tasks/fire.hpp Normal file
View File

@@ -0,0 +1,27 @@
/*
* fire.hpp
*
* Created on: Jun 17, 2024
* Author: carlos
*/
#ifndef INC_TASKS_FIRE_HPP_
#define INC_TASKS_FIRE_HPP_
#include <sta/tacos.hpp>
#include <sta/devices/stm32/can.hpp>
namespace tasks
{
class FireTask : public sta::tacos::TacosThread
{
public:
FireTask();
void init() override;
void func() override;
};
} // namespace tasks
#endif /* INC_TASKS_FIRE_HPP_ */

37
App/Inc/tasks/sense.hpp Normal file
View File

@@ -0,0 +1,37 @@
/*
* sense.hpp
*
* Created on: Jun 17, 2024
* Author: carlos
*/
#ifndef INC_TASKS_SENSE_HPP_
#define INC_TASKS_SENSE_HPP_
#include <sta/tacos.hpp>
#include <sta/devices/stm32/adc.hpp>
#include <sta/devices/stm32/bus/spi.hpp>
namespace tasks
{
class SenseTask : public sta::tacos::TacosThread
{
public:
SenseTask(ADC_HandleTypeDef *handle);
void init() override;
void func() override;
private:
sta::STM32ADC adc_;
uint16_t dmaBuffer_[6];
size_t bufferSize_ = 6;
uint16_t result_[6];
CanSysMsg msg_;
uint16_t result_counter_ = 0;
};
} // namespace tasks
#endif /* INC_TASKS_SENSE_HPP_ */

164
App/Src/shared.cpp Normal file
View File

@@ -0,0 +1,164 @@
/*
* shared.cpp
*
* Created on: Jun 17, 2024
* Author: Dario
*/
#include <shared.hpp>
#include <sta/tacos.hpp>
#include <sta/rtos/mutex.hpp>
#include <sta/rtos/event.hpp>
#include <sta/rtos/timer.hpp>
#include <sta/rtos/sharedmem.hpp>
#include <sta/time.hpp>
namespace rres
{
sta::RtosEvent *signal;
sta::RtosSharedMem<LoggingData> *memory;
sta::RtosTimer *sync_10Hz;
bool _10Hz_tick = true;
void init()
{
signal = new sta::RtosEvent();
memory = new sta::RtosSharedMem<LoggingData>(100);
sync_10Hz = new sta::RtosTimer([](void *)
{
if (_10Hz_tick)
{
signal->set(TICK_10HZ);
}
else
{
signal->set(TOCK_10HZ);
}
_10Hz_tick = !_10Hz_tick; }, NULL, true);
sync_10Hz->start(50);
}
uint32_t waitForAny(uint32_t dataTypes, uint32_t timeout /* = osWaitForever */)
{
uint32_t flags = signal->wait(dataTypes, timeout);
signal->clear(dataTypes);
return flags;
}
uint32_t waitForAll(uint32_t dataTypes, uint32_t timeout /* = osWaitForever */)
{
uint32_t received = 0x00;
uint32_t startTime = sta::timeMs();
do
{
// Wait for the remaining flags and set the remaining time as the timeout.
received |= waitForAny(dataTypes & ~received, timeout - (sta::timeMs() - startTime));
} while (received != dataTypes && sta::timeMs() - startTime < timeout);
signal->clear(received);
return received;
}
void setSenseFire(uint8_t sense_fire)
{
LoggingData data = memory->read();
data.sense_fire = sense_fire;
memory->write(data);
}
void setSenseADC(uint16_t sense_adc[6])
{
LoggingData data = memory->read();
for (int i = 0; i < 6; i++)
{
data.sense_adc[i] = sense_adc[i];
}
memory->write(data);
}
void setFired(uint8_t fired)
{
LoggingData data = memory->read();
data.fired = fired;
memory->write(data);
}
LoggingData getData()
{
return memory->read();
}
void startLogging()
{
signal->set(START_LOGGING);
}
void dumpFlash()
{
signal->set(DUMP_FLASH);
}
void clearFlash()
{
signal->set(CLEAR_FLASH);
}
} // namespace rres
#ifdef STA_TACOS_CAN_BUS_ENABLED
namespace sta
{
namespace tacos
{
bool handleSysMessage(CanMsgHeader &header, uint8_t *payload)
{
// STA_DEBUG_PRINTF("> CAN ID recved: %d", header.sid);
switch (header.sid)
{
// State transition message
case STA_TACOS_CAN_BUS_SYS_MSG_ID:
// First byte of payload is the origin state, second byte is the destination state
tacos::forceState(payload[0], payload[1], 0, true);
// Send confirmation message
CanSysMsg msg;
msg.header.payloadLength = 2;
msg.header.sid = MODULE_STATE_CONFIRM_CAN_ID;
msg.header.eid = 0;
msg.header.format = 0;
msg.payload[0] = MODULE_RRES;
msg.payload[1] = payload[1];
tacos::queueCanBusMsg(msg, 0);
return true;
case MODULE_SW_RESET_CAN_ID:
if (payload[0] == MODULE_RRES)
{
HAL_NVIC_SystemReset();
}
return true; // Least useless return statement ever
// Flash Operations
case FLASH_OPERATIONS_CAN_ID:
if (payload[0] == 0x01)
rres::clearFlash();
else if (payload[0] == 0x02)
rres::dumpFlash();
return true;
default:
return false;
}
}
}
}
#endif // STA_TACOS_CAN_BUS_ENABLED

42
App/Src/startup.cpp Normal file
View File

@@ -0,0 +1,42 @@
/*
* printable.cpp
*
* Created on: Aug 30, 2023
* Author: Dario
*/
#include <sta/debug/debug.hpp>
#include <shared.hpp>
#include <tasks/sense.hpp>
#include <tasks/arming.hpp>
#include <tasks/fire.hpp>
#include <sta/rtos/debug/heap_stats.hpp>
#include <sta/devices/stm32/bus/spi.hpp>
#include <states.hpp>
#include <sta/tacos.hpp>
#include <memory>
#include <spi.h>
#include <adc.h>
namespace sta
{
namespace tacos
{
void onStatemachineInit()
{
rres::init();
sta::tacos::addThread<tasks::SenseTask>(ALL_STATES, &hadc1);
sta::tacos::addThread<tasks::ArmingTask>({stahr::ARMED});
sta::tacos::addThread<tasks::FireTask>({stahr::DROGUE, stahr::MAIN, stahr::DISREEFING});
tacos::forceState(tacos::getState(), stahr::READY_ON_PAD);
STA_DEBUG_PRINTF("The answer to everything is %d", 42);
// STA_DEBUG_HEAP_STATS();
}
} // namespace tacos
} // namespace sta

65
App/Src/tasks/arming.cpp Normal file
View File

@@ -0,0 +1,65 @@
/*
* arming.cpp
*
* Created on: Jun 17, 2024
* Author: carlos
*/
#include <tasks/arming.hpp>
#include <sta/debug/debug.hpp>
#include "can.h"
#include <sta/tacos.hpp>
#include <cmsis_os2.h>
namespace tasks
{
ArmingTask::ArmingTask() : TacosThread("ARMING", osPriorityHigh)
{
}
void ArmingTask::init()
{
// Stop shorting the igniters (NC so they are always shorted until high signal is sent)
HAL_GPIO_WritePin(SHORTING_GROUPA, SHORTING_PIN_A, GPIO_PIN_SET);
HAL_GPIO_WritePin(SHORTING_GROUPB, SHORTING_PIN_B, GPIO_PIN_SET);
HAL_GPIO_WritePin(SHORTING_GROUPC, SHORTING_PIN_C, GPIO_PIN_SET);
HAL_GPIO_WritePin(SHORTING_GROUPD, SHORTING_PIN_D, GPIO_PIN_SET);
HAL_GPIO_WritePin(SHORTING_GROUPE, SHORTING_PIN_E, GPIO_PIN_SET);
HAL_GPIO_WritePin(SHORTING_GROUPF, SHORTING_PIN_F, GPIO_PIN_SET);
this->sleep(500); // 500ms delay
// Arming the igniters
HAL_GPIO_WritePin(ARMING_GROUPA, ARMING_PIN_A, GPIO_PIN_SET);
HAL_GPIO_WritePin(ARMING_GROUPB, ARMING_PIN_B, GPIO_PIN_SET);
HAL_GPIO_WritePin(ARMING_GROUPC, ARMING_PIN_C, GPIO_PIN_SET);
HAL_GPIO_WritePin(ARMING_GROUPD, ARMING_PIN_D, GPIO_PIN_SET);
HAL_GPIO_WritePin(ARMING_GROUPE, ARMING_PIN_E, GPIO_PIN_SET);
HAL_GPIO_WritePin(ARMING_GROUPF, ARMING_PIN_F, GPIO_PIN_SET);
#ifdef STA_TACOS_CAN_BUS_ENABLED
CanSysMsg msg;
msg.payload[0] = 1; // Send 1 to indicate that the igniters are armed
msg.header.payloadLength = 1;
msg.header.sid = ARMING_CAN_ID;
msg.header.eid = 0;
msg.header.format = 0;
sta::tacos::queueCanBusMsg(msg, 0);
#endif // STA_TACOS_CAN_BUS_ENABLED
// Terminate the thread until next state
#ifdef STA_TACOS_WATCHDOG_ENABLED
this->watchdogIgnore();
#endif // STA_TACOS_WATCHDOG_ENABLED
}
void ArmingTask::func()
{
sleep(osWaitForever);
}
} // namespace tasks

131
App/Src/tasks/fire.cpp Normal file
View File

@@ -0,0 +1,131 @@
/*
* fire.cpp
*
* Created on: Jun 17, 2024
* Author: carlos
*/
#include <tasks/fire.hpp>
#include <sta/debug/debug.hpp>
#include "can.h"
#include <sta/tacos.hpp>
#include <sta/config.hpp>
#include <shared.hpp>
#include <cmsis_os2.h>
namespace tasks
{
FireTask::FireTask() : TacosThread("IGNITOR_FIRE", osPriorityHigh)
{
}
void FireTask::init()
{
rres::setFired(0);
}
void FireTask::func()
{
// Firing the igniters
CanSysMsg msg;
msg.header.sid = FIRE_CAN_ID;
msg.header.eid = 0;
msg.header.format = 0;
msg.header.payloadLength = 1;
if (sta::tacos::getState() == stahr::DROGUE)
{
// Fire
HAL_GPIO_WritePin(FIRE_HATCH_GROUP1, FIRE_HATCH_PIN_1, GPIO_PIN_SET);
HAL_GPIO_WritePin(FIRE_HATCH_GROUP2, FIRE_HATCH_PIN_2, GPIO_PIN_SET);
// Send out fire information
msg.payload[0] = 1; // Event 1 = HATCH fired / drogue deployed
sta::tacos::queueCanBusMsg(msg, 0);
rres::setFired(1);
// Only leave on for a second to avoid shorting via the igniter
this->sleep(1000); // 1 second
HAL_GPIO_WritePin(FIRE_HATCH_GROUP1, FIRE_HATCH_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(FIRE_HATCH_GROUP2, FIRE_HATCH_PIN_2, GPIO_PIN_RESET);
this->sleep(50); // Delay before disarming igniters
// Disarm the igniters
HAL_GPIO_WritePin(ARMING_GROUPE, ARMING_PIN_E, GPIO_PIN_RESET);
HAL_GPIO_WritePin(ARMING_GROUPF, ARMING_PIN_F , GPIO_PIN_RESET);
// Short ignitors
HAL_GPIO_WritePin(SHORTING_GROUPE, SHORTING_PIN_E, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SHORTING_GROUPF, SHORTING_PIN_F, GPIO_PIN_RESET);
}
else if (sta::tacos::getState() == stahr::MAIN)
{
HAL_GPIO_WritePin(FIRE_MAIN_GROUP1, FIRE_MAIN_PIN_1, GPIO_PIN_SET);
HAL_GPIO_WritePin(FIRE_MAIN_GROUP2, FIRE_MAIN_PIN_2, GPIO_PIN_SET);
// Send out fire information
msg.payload[0] = 2; // Event 2 = MAIN Parachute
sta::tacos::queueCanBusMsg(msg, 0);
rres::setFired(2);
// Only leave on for a second to avoid shorting via the igniter
this->sleep(1000); // 1 second
HAL_GPIO_WritePin(FIRE_MAIN_GROUP1, FIRE_MAIN_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(FIRE_MAIN_GROUP2, FIRE_MAIN_PIN_2, GPIO_PIN_RESET);
this->sleep(50); // Delay before disarming igniters
// Disarm the igniters
HAL_GPIO_WritePin(ARMING_GROUPC, ARMING_PIN_C, GPIO_PIN_RESET);
HAL_GPIO_WritePin(ARMING_GROUPD, ARMING_PIN_D, GPIO_PIN_RESET);
// Short ignitors
HAL_GPIO_WritePin(SHORTING_GROUPC, SHORTING_PIN_C, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SHORTING_GROUPD, SHORTING_PIN_D, GPIO_PIN_RESET);
}
else if (sta::tacos::getState() == stahr::DISREEFING)
{
HAL_GPIO_WritePin(FIRE_DEREEFING_GROUP1, FIRE_DEREEFING_PIN_1, GPIO_PIN_SET);
HAL_GPIO_WritePin(FIRE_DEREEFING_GROUP2, FIRE_DEREEFING_PIN_2, GPIO_PIN_SET);
// Send out fire information
msg.payload[0] = 3; // Event 3 = Drogue Parachute
sta::tacos::queueCanBusMsg(msg, 0);
rres::setFired(3);
// Only leave on for a second to avoid shorting via the igniter
this->sleep(1000); // 1 second
HAL_GPIO_WritePin(FIRE_DEREEFING_GROUP1, FIRE_DEREEFING_PIN_1, GPIO_PIN_RESET);
HAL_GPIO_WritePin(FIRE_DEREEFING_GROUP2, FIRE_DEREEFING_PIN_2, GPIO_PIN_RESET);
this->sleep(50); // Delay before disarming igniters
// Disarm the igniters
HAL_GPIO_WritePin(ARMING_GROUPA, ARMING_PIN_A, GPIO_PIN_RESET);
HAL_GPIO_WritePin(ARMING_GROUPB, ARMING_PIN_B, GPIO_PIN_RESET);
// Short ignitors
HAL_GPIO_WritePin(SHORTING_GROUPA, SHORTING_PIN_A, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SHORTING_GROUPB, SHORTING_PIN_B, GPIO_PIN_RESET);
}
// Terminate the thread until next state
#ifdef STA_TACOS_WATCHDOG_ENABLED
this->watchdogIgnore();
#endif // STA_TACOS_WATCHDOG_ENABLED
this->requestTermination();
}
} // namespace tasks

153
App/Src/tasks/sense.cpp Normal file
View File

@@ -0,0 +1,153 @@
/*
* sense.cpp
*
* Created on: Jun 17, 2024
* Author: carlos
*/
#include <tasks/sense.hpp>
#include <sta/tacos.hpp>
#include <sta/rtos/signal.hpp>
#include <sta/devices/stm32/delay.hpp>
#include <shared.hpp>
#include <tim.h>
#include <adc.h>
namespace tasks
{
/**
* @brief Signal for the ADC conversion complete interrupt to communicate with the ADCTask.
*/
sta::RtosSignal *adcCompleteSignal = nullptr;
SenseTask::SenseTask(ADC_HandleTypeDef *handle)
: sta::tacos::TacosThread{"Sense", osPriorityNormal},
adc_{handle}, result_counter_{0}
{
}
void SenseTask::init()
{
adcCompleteSignal = new sta::RtosSignal(1);
// Init msg_
msg_.header.payloadLength = 8;
msg_.header.eid = 0;
msg_.header.format = 0;
// Start ADC timer
HAL_TIM_Base_Start(&htim3);
adc_.startDMA((uint32_t *)dmaBuffer_, bufferSize_);
}
void SenseTask::func()
{
STA_ASSERT(adcCompleteSignal != nullptr);
// Wait for the conversion to be completed.
adcCompleteSignal->wait();
// Determine wether to send the data or not
uint16_t state = sta::tacos::getState();
bool logging = !(state == stahr::CALIBRATING || state == stahr::READY_ON_PAD);
bool send = result_counter_++ % 4 == 0;
// Sending the first 4 ADC values (limited by the CAN message size of 8 bytes)
for (size_t i = 0; i < 4; ++i)
{
// Send the MSB first.
msg_.payload[2 * i] = (uint8_t)(dmaBuffer_[i] >> 8);
// ... LSB second
msg_.payload[2 * i + 1] = (uint8_t)dmaBuffer_[i];
}
// Save the first 4 ADC values for logging
for (size_t i = 0; i < 4; i++)
{
result_[i] = msg_.payload[2 * i] << 8 | msg_.payload[2 * i + 1];
STA_DEBUG_PRINTF("> ADC[%d]: %d", i, result_[i]);
}
if (send)
{
// Send it out while on the pad. Otherwise we only log the data.
msg_.header.payloadLength = 8;
msg_.header.sid = SENSE_CAN_ID;
sta::tacos::queueCanBusMsg(msg_, 0);
}
// Send the last 2 ADC values (limited by the CAN message size of 8 bytes)
for (size_t i = 4; i < bufferSize_; ++i)
{
// Send the MSB first.
msg_.payload[2 * (i - 4)] = (uint8_t)(dmaBuffer_[i] >> 8);
// ... LSB second
msg_.payload[2 * (i - 4) + 1] = (uint8_t)dmaBuffer_[i];
}
// Save the last 2 ADC values for logging
for (size_t i = 4; i < 6; i++)
{
result_[i] = msg_.payload[2 * (i - 4)] << 8 | msg_.payload[2 * (i - 4) + 1];
STA_DEBUG_PRINTF("> ADC[%d]: %d", i, result_[i]);
}
// Get the sense pins on the fire output
uint8_t sense_fire = 0;
uint8_t sense_fire_1 = HAL_GPIO_ReadPin(SENSE_FIRE_GROUP1, SENSE_FIRE_PIN_1);
uint8_t sense_fire_2 = HAL_GPIO_ReadPin(SENSE_FIRE_GROUP2, SENSE_FIRE_PIN_2);
uint8_t sense_fire_3 = HAL_GPIO_ReadPin(SENSE_FIRE_GROUP3, SENSE_FIRE_PIN_3);
uint8_t sense_fire_4 = HAL_GPIO_ReadPin(SENSE_FIRE_GROUP4, SENSE_FIRE_PIN_4);
uint8_t sense_fire_5 = HAL_GPIO_ReadPin(SENSE_FIRE_GROUP5, SENSE_FIRE_PIN_5);
uint8_t sense_fire_6 = HAL_GPIO_ReadPin(SENSE_FIRE_GROUP6, SENSE_FIRE_PIN_6);
sense_fire = sense_fire_1 | (sense_fire_2 << 1) | (sense_fire_3 << 2) | (sense_fire_4 << 3) | (sense_fire_5 << 4) | (sense_fire_6 << 5);
STA_DEBUG_PRINTF("> Sense Fired pins: %d", sense_fire);
if (send)
{
msg_.payload[4] = sense_fire; // Send the sense pins on the fire output
// Send second half of the ADC values, via another CAN ID (+1)
msg_.header.sid = SENSE_CAN_ID_2;
msg_.header.payloadLength = 5;
// Send it out while on the pad. Otherwise we only log the data.
sta::tacos::queueCanBusMsg(msg_, 0);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_10);
}
else
{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_9);
}
if (logging)
{
// Log the ADC values and the sense pins on the fire output
rres::setSenseFire(sense_fire);
rres::setSenseADC(result_);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_8);
}
adc_.startDMA((uint32_t *)dmaBuffer_, bufferSize_);
}
} // namespace tasks
// Callback for HAL ADC
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if (tasks::adcCompleteSignal != nullptr && hadc == &hadc1)
{
tasks::adcCompleteSignal->notify();
}
}