2020-09-19 02:49:20 -07:00
|
|
|
#include "ch.h"
|
|
|
|
#include "hal.h"
|
|
|
|
|
2020-09-19 16:51:02 -07:00
|
|
|
#include "can.h"
|
2020-12-10 18:32:41 -08:00
|
|
|
#include "fault.h"
|
2020-10-30 01:53:54 -07:00
|
|
|
#include "heater_control.h"
|
2020-10-31 16:59:35 -07:00
|
|
|
#include "pump_control.h"
|
2020-10-27 16:33:32 -07:00
|
|
|
#include "pump_dac.h"
|
2020-10-29 02:55:55 -07:00
|
|
|
#include "sampling.h"
|
2020-12-10 23:48:47 -08:00
|
|
|
#include "uart.h"
|
2021-11-07 22:52:13 -08:00
|
|
|
#include "io_pins.h"
|
2022-07-03 12:11:12 -07:00
|
|
|
#include "auxout.h"
|
2023-05-29 15:16:28 -07:00
|
|
|
#include "max3185x.h"
|
2022-09-19 16:31:30 -07:00
|
|
|
#include "port.h"
|
2023-02-27 15:27:25 -08:00
|
|
|
#include "tunerstudio.h"
|
2023-05-03 13:18:05 -07:00
|
|
|
#include "indication.h"
|
2022-07-20 16:36:23 -07:00
|
|
|
|
|
|
|
#include "wideband_config.h"
|
2020-09-19 15:44:10 -07:00
|
|
|
|
2023-01-05 16:56:28 -08:00
|
|
|
#include <cstring>
|
|
|
|
|
2022-01-01 21:10:55 -08:00
|
|
|
using namespace wbo;
|
2020-10-26 17:25:05 -07:00
|
|
|
|
2020-09-19 02:49:20 -07:00
|
|
|
/*
|
|
|
|
* Application entry point.
|
|
|
|
*/
|
2020-09-19 21:39:29 -07:00
|
|
|
int main() {
|
2020-09-19 16:51:02 -07:00
|
|
|
halInit();
|
|
|
|
chSysInit();
|
2020-09-19 02:49:20 -07:00
|
|
|
|
2022-09-19 16:31:30 -07:00
|
|
|
// Load configuration
|
|
|
|
InitConfiguration();
|
|
|
|
|
2020-10-31 16:59:35 -07:00
|
|
|
// Fire up all of our threads
|
2020-10-29 02:55:55 -07:00
|
|
|
StartSampling();
|
2020-10-27 16:33:32 -07:00
|
|
|
InitPumpDac();
|
2020-10-31 16:59:35 -07:00
|
|
|
StartHeaterControl();
|
|
|
|
StartPumpControl();
|
2022-07-03 12:11:12 -07:00
|
|
|
InitAuxDac();
|
|
|
|
|
2023-12-03 15:57:18 -08:00
|
|
|
#if TS_ENABLED
|
2023-02-27 15:27:25 -08:00
|
|
|
startTunerStudioConnectivity();
|
2023-11-22 18:26:40 -08:00
|
|
|
#endif
|
2023-02-27 15:27:25 -08:00
|
|
|
|
2020-10-31 16:59:35 -07:00
|
|
|
InitCan();
|
2022-04-04 14:18:08 -07:00
|
|
|
InitUart();
|
2023-05-03 13:18:05 -07:00
|
|
|
InitIndication();
|
2020-09-19 21:39:29 -07:00
|
|
|
|
2022-07-20 16:36:23 -07:00
|
|
|
#if (EGT_CHANNELS > 0)
|
|
|
|
StartEgt();
|
|
|
|
#endif
|
|
|
|
|
2020-12-10 18:08:06 -08:00
|
|
|
while(true)
|
|
|
|
{
|
2023-05-03 13:18:05 -07:00
|
|
|
#ifdef ADVANCED_INDICATION
|
|
|
|
/* NOP nap */
|
|
|
|
chThdSleepMilliseconds(1000);
|
|
|
|
#else
|
2022-08-29 17:19:30 -07:00
|
|
|
/* TODO: show error for all AFR channels */
|
|
|
|
/* TODO: show EGT errors */
|
|
|
|
auto fault = GetCurrentFault(0);
|
2020-12-10 21:58:59 -08:00
|
|
|
|
|
|
|
if (fault == Fault::None)
|
2020-12-10 21:46:41 -08:00
|
|
|
{
|
|
|
|
// blue is off
|
2021-12-27 20:45:55 -08:00
|
|
|
palClearPad(LED_BLUE_PORT, LED_BLUE_PIN);
|
2020-12-10 21:46:41 -08:00
|
|
|
|
|
|
|
// Green is blinking
|
2021-12-27 20:45:55 -08:00
|
|
|
palTogglePad(LED_GREEN_PORT, LED_GREEN_PIN);
|
2020-12-10 21:46:41 -08:00
|
|
|
|
2020-12-19 16:06:35 -08:00
|
|
|
// Slow blink if closed loop, fast if not
|
2023-06-23 14:38:17 -07:00
|
|
|
chThdSleepMilliseconds(GetHeaterController(0).IsRunningClosedLoop() ? 700 : 50);
|
2020-12-10 21:46:41 -08:00
|
|
|
}
|
2020-12-10 21:58:59 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// green is off
|
2021-12-27 20:45:55 -08:00
|
|
|
palClearPad(LED_GREEN_PORT, LED_GREEN_PIN);
|
2020-12-10 21:46:41 -08:00
|
|
|
|
2020-12-10 21:58:59 -08:00
|
|
|
// Blink out the error code
|
|
|
|
for (int i = 0; i < 2 * static_cast<int>(fault); i++)
|
|
|
|
{
|
|
|
|
// Blue is blinking
|
2021-12-27 20:45:55 -08:00
|
|
|
palTogglePad(LED_BLUE_PORT, LED_BLUE_PIN);
|
2020-12-10 21:58:09 -08:00
|
|
|
|
2020-12-10 21:58:59 -08:00
|
|
|
// fast blink
|
|
|
|
chThdSleepMilliseconds(300);
|
|
|
|
}
|
2020-12-10 21:58:09 -08:00
|
|
|
|
2020-12-10 21:58:59 -08:00
|
|
|
chThdSleepMilliseconds(2000);
|
2020-12-10 18:32:41 -08:00
|
|
|
}
|
2023-05-03 13:18:05 -07:00
|
|
|
#endif
|
2020-09-19 16:51:02 -07:00
|
|
|
}
|
2020-09-19 02:49:20 -07:00
|
|
|
}
|
2023-01-05 16:56:28 -08:00
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
Reset = 1,
|
|
|
|
NMI = 2,
|
|
|
|
HardFault = 3,
|
|
|
|
MemManage = 4,
|
|
|
|
BusFault = 5,
|
|
|
|
UsageFault = 6,
|
|
|
|
} FaultType;
|
|
|
|
|
|
|
|
#define bkpt() __asm volatile("BKPT #0\n")
|
|
|
|
|
|
|
|
extern "C" void HardFault_Handler_C(void* sp) {
|
|
|
|
//Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
|
|
|
|
//Get thread context. Contains main registers including PC and LR
|
|
|
|
struct port_extctx ctx;
|
|
|
|
memcpy(&ctx, sp, sizeof(struct port_extctx));
|
|
|
|
|
|
|
|
//Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
|
|
|
|
FaultType faultType = (FaultType)__get_IPSR();
|
|
|
|
(void)faultType;
|
2023-01-16 03:49:00 -08:00
|
|
|
#if (__CORTEX_M > 0)
|
2023-01-05 16:56:28 -08:00
|
|
|
//For HardFault/BusFault this is the address that was accessed causing the error
|
|
|
|
uint32_t faultAddress = SCB->BFAR;
|
|
|
|
|
|
|
|
//Flags about hardfault / busfault
|
|
|
|
//See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
|
|
|
|
bool isFaultPrecise = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 1) ? true : false);
|
|
|
|
bool isFaultImprecise = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 2) ? true : false);
|
|
|
|
bool isFaultOnUnstacking = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 3) ? true : false);
|
|
|
|
bool isFaultOnStacking = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 4) ? true : false);
|
|
|
|
bool isFaultAddressValid = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 7) ? true : false);
|
2023-02-15 10:25:28 -08:00
|
|
|
(void)faultAddress;
|
2023-01-05 16:56:28 -08:00
|
|
|
(void)isFaultPrecise;
|
|
|
|
(void)isFaultImprecise;
|
|
|
|
(void)isFaultOnUnstacking;
|
|
|
|
(void)isFaultOnStacking;
|
|
|
|
(void)isFaultAddressValid;
|
2023-01-16 03:49:00 -08:00
|
|
|
#endif
|
2023-01-05 16:56:28 -08:00
|
|
|
|
|
|
|
//Cause debugger to stop. Ignored if no debugger is attached
|
|
|
|
bkpt();
|
|
|
|
NVIC_SystemReset();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void UsageFault_Handler_C(void* sp) {
|
|
|
|
//Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
|
|
|
|
//Get thread context. Contains main registers including PC and LR
|
|
|
|
struct port_extctx ctx;
|
|
|
|
memcpy(&ctx, sp, sizeof(struct port_extctx));
|
|
|
|
|
|
|
|
//Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
|
|
|
|
FaultType faultType = (FaultType)__get_IPSR();
|
|
|
|
(void)faultType;
|
2023-01-16 03:49:00 -08:00
|
|
|
#if (__CORTEX_M > 0)
|
2023-01-05 16:56:28 -08:00
|
|
|
//Flags about hardfault / busfault
|
|
|
|
//See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
|
|
|
|
bool isUndefinedInstructionFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 0) ? true : false);
|
|
|
|
bool isEPSRUsageFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 1) ? true : false);
|
|
|
|
bool isInvalidPCFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 2) ? true : false);
|
|
|
|
bool isNoCoprocessorFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 3) ? true : false);
|
|
|
|
bool isUnalignedAccessFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 8) ? true : false);
|
|
|
|
bool isDivideByZeroFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 9) ? true : false);
|
|
|
|
(void)isUndefinedInstructionFault;
|
|
|
|
(void)isEPSRUsageFault;
|
|
|
|
(void)isInvalidPCFault;
|
|
|
|
(void)isNoCoprocessorFault;
|
|
|
|
(void)isUnalignedAccessFault;
|
|
|
|
(void)isDivideByZeroFault;
|
2023-01-16 03:49:00 -08:00
|
|
|
#endif
|
2023-01-05 16:56:28 -08:00
|
|
|
|
|
|
|
bkpt();
|
|
|
|
NVIC_SystemReset();
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void MemManage_Handler_C(void* sp) {
|
|
|
|
//Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
|
|
|
|
//Get thread context. Contains main registers including PC and LR
|
|
|
|
struct port_extctx ctx;
|
|
|
|
memcpy(&ctx, sp, sizeof(struct port_extctx));
|
|
|
|
|
|
|
|
//Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
|
|
|
|
FaultType faultType = (FaultType)__get_IPSR();
|
|
|
|
(void)faultType;
|
2023-01-16 03:49:00 -08:00
|
|
|
#if (__CORTEX_M > 0)
|
2023-01-05 16:56:28 -08:00
|
|
|
//For HardFault/BusFault this is the address that was accessed causing the error
|
|
|
|
uint32_t faultAddress = SCB->MMFAR;
|
2023-02-17 11:43:21 -08:00
|
|
|
(void)faultAddress;
|
2023-01-05 16:56:28 -08:00
|
|
|
|
|
|
|
//Flags about hardfault / busfault
|
|
|
|
//See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
|
|
|
|
bool isInstructionAccessViolation = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 0) ? true : false);
|
|
|
|
bool isDataAccessViolation = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 1) ? true : false);
|
|
|
|
bool isExceptionUnstackingFault = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 3) ? true : false);
|
|
|
|
bool isExceptionStackingFault = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 4) ? true : false);
|
|
|
|
bool isFaultAddressValid = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 7) ? true : false);
|
|
|
|
(void)isInstructionAccessViolation;
|
|
|
|
(void)isDataAccessViolation;
|
|
|
|
(void)isExceptionUnstackingFault;
|
|
|
|
(void)isExceptionStackingFault;
|
|
|
|
(void)isFaultAddressValid;
|
2023-01-16 03:49:00 -08:00
|
|
|
#endif
|
2023-01-05 16:56:28 -08:00
|
|
|
|
|
|
|
bkpt();
|
|
|
|
NVIC_SystemReset();
|
|
|
|
}
|