From 54b4fa4e668f120cc242c337f27cf2d0182ca66c Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Fri, 5 Aug 2022 15:32:21 +0000 Subject: [PATCH 001/141] added basics of multi-bus support to CAN driver --- Drivers/Inc/CANbus.h | 27 ++++++------- Drivers/Src/CANbus.c | 91 +++++++++++++++++++++++++++----------------- 2 files changed, 70 insertions(+), 48 deletions(-) diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index 33b20bf39..7542d0b24 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -4,7 +4,8 @@ #define CAN_H__ #include "BSP_CAN.h" - +#define CARCAN CAN_1 //convenience aliases for the CANBuses +#define MOTORCAN CAN_3 typedef enum { MC_BUS = 0x242, VELOCITY = 0x243, @@ -32,7 +33,7 @@ typedef union { typedef struct { uint8_t idx : 8; uint8_t bytes : 8; - CANData_t data; + CANData_t data; //TODO: This could probably be replaced with a uint64_t } CANPayload_t; /** @@ -46,31 +47,31 @@ typedef struct { typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; /** - * @brief Initializes the CAN system - * @param None + * @brief Initializes the CAN system for a given bus + * @param bus The bus to initialize. You can either use CAN_1, CAN_3, or the convenience macros CARCAN and MOTORCAN * @return None */ -void CANbus_Init(void); +void CANbus_Init(CAN_t bus); /** * @brief Transmits data onto the CANbus. * @param id : CAN id of the message * @param payload : the data that will be sent. * @param blocking: Whether or not the Send should be blocking or not + * @param bus: Which bus to transmit on * @return ERROR if data wasn't sent, otherwise it was sent. */ -ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload,CAN_blocking_t blocking); +ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload,CAN_blocking_t blocking, CAN_t bus); /** - * @brief Checks if the CAN ID matches with Motor disable ID - * @param canline (not implemented, default is CAN1) can line to read from - * @param id CAN msg ID - * @param buffer pointer to buffer in which to store the can msg - * @param blocking whether or not this Read should be a blocking read or a nonblocking read - * @return 1 if ID matches and 0 if it doesn't + * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers + * @param ID pointer to where to store the CAN id of the recieved msg + * @param pointer to buffer array to store message. MUST BE 8 BYTES OR LARGER + * @param blocking whether or not this read should be blocking + * @returns ERROR if read failed, SUCCESS otherwise */ -ErrorStatus CANbus_Read(uint32_t *id, uint8_t* buffer, CAN_blocking_t blocking); +ErrorStatus CANbus_Read(uint32_t *id, uint8_t* buffer, CAN_blocking_t blocking, CAN_t bus); #endif diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index efc61d175..1e17d68b7 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -3,55 +3,80 @@ #include "os.h" #include "Tasks.h" -static OS_SEM CANMail_Sem4; // sem4 to count how many sending hardware mailboxes we have left (start at 3) -static OS_SEM CANBus_RecieveSem4; // sem4 to count how many msgs in our recieving queue -static OS_MUTEX CANbus_TxMutex; // mutex to lock tx line -static OS_MUTEX CANbus_RxMutex; // mutex to lock Rx line +static OS_SEM CANMail_Sem4[NUM_CAN]; // sem4 to count how many sending hardware mailboxes we have left (start at 3) +static OS_SEM CANBus_RecieveSem4[NUM_CAN]; // sem4 to count how many msgs in our recieving queue +static OS_MUTEX CANbus_TxMutex[NUM_CAN]; // mutex to lock tx line +static OS_MUTEX CANbus_RxMutex[NUM_CAN]; // mutex to lock Rx line /** * @brief this function will be passed down to the BSP layer to trigger on RX events. Increments the recieve semaphore to signal message in hardware mailbox. Do not access directly. + * @param bus The CAN bus to operate on */ -void CANbus_RxHandler() +void CANbus_RxHandler(CAN_t bus) { OS_ERR err; - OSSemPost(&CANBus_RecieveSem4, OS_OPT_POST_1, &err); // increment our queue counter + OSSemPost(&(CANBus_RecieveSem4[bus]), OS_OPT_POST_1, &err); // increment our queue counter assertOSError(OS_CANDRIVER_LOC,err); } /** * @brief this function will be passed down to the BSP layer to trigger on TXend. Releases hold of the mailbox semaphore (Increments it to show mailbox available). Do not access directly. + * @param bus The CAN bus to operate on */ -void CANbus_TxHandler() +void CANbus_TxHandler(CAN_t bus) { OS_ERR err; - OSSemPost(&CANMail_Sem4, OS_OPT_POST_1, &err); + OSSemPost(&(CANMail_Sem4[bus]), OS_OPT_POST_1, &err); assertOSError(OS_CANDRIVER_LOC,err); } +//wrapper functions for the interrupt customized for each bus +void CANbus_TxHandler_1(){ + CANbus_TxHandler(CAN_1); +} + +void CANbus_TxHandler_3(){ + CANbus_TxHandler(CAN_3); +} + +void CANbus_RxHandler_1(){ + CANbus_RxHandler(CAN_1); +} +void CANbus_RxHandler_3(){ + CANbus_RxHandler(CAN_3); +} + /** * @brief Initializes the CAN system * @param None * @return None */ -void CANbus_Init(void) +void CANbus_Init(CAN_t bus) { // initialize CAN mailbox semaphore to 3 for the 3 CAN mailboxes that we have // initialize tx OS_ERR err; - - OSMutexCreate(&CANbus_TxMutex, "CAN TX Lock", &err); + + + + OSMutexCreate(&(CANbus_TxMutex[bus]), (bus == CAN_1 ? "CAN TX Lock 1":"CAN TX Lock 3"), &err); assertOSError(OS_CANDRIVER_LOC,err); - OSMutexCreate(&CANbus_RxMutex, "CAN RX Lock", &err); + OSMutexCreate(&(CANbus_RxMutex[bus]), (bus == CAN_1 ? "CAN RX Lock 1":"CAN RX Lock 3"), &err); assertOSError(OS_CANDRIVER_LOC,err); - OSSemCreate(&CANMail_Sem4, "CAN Mailbox Semaphore", 3, &err); // there's 3 hardware mailboxes on the board, so 3 software mailboxes + OSSemCreate(&(CANMail_Sem4[bus]), (bus == CAN_1 ? "CAN Mailbox Semaphore 1":"CAN Mailbox Semaphore 3"), 3, &err); // there's 3 hardware mailboxes on the board, so 3 software mailboxes assertOSError(OS_CANDRIVER_LOC,err); - OSSemCreate(&CANBus_RecieveSem4, "CAN Recieved Msg queue", 0, &err); // create a mailbox counter to hold the messages in as they come in + OSSemCreate(&(CANBus_RecieveSem4[bus]), (bus == CAN_1 ? "CAN Recieved Msg Queue Ctr 1":"CAN Recieved Msg Queue Ctr 3"), 0, &err); // create a mailbox counter to hold the messages in as they come in assertOSError(OS_CANDRIVER_LOC,err); - BSP_CAN_Init(CAN_1, &CANbus_RxHandler, &CANbus_TxHandler); + if(bus==CAN_1){ + BSP_CAN_Init(bus,&CANbus_RxHandler_1,&CANbus_TxHandler_1); + } else if (bus==CAN_3){ + BSP_CAN_Init(bus,&CANbus_RxHandler_3,&CANbus_TxHandler_3); + } + } /** @@ -61,7 +86,7 @@ void CANbus_Init(void) * @param blocking: Whether or not this should be a blocking call * @return 0 if data wasn't sent, otherwise it was sent. */ -ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blocking) +ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blocking, CAN_t bus) { CPU_TS timestamp; OS_ERR err; @@ -69,7 +94,7 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin if (blocking == CAN_BLOCKING) { OSSemPend( - &CANMail_Sem4, + &(CANMail_Sem4[bus]), 0, OS_OPT_PEND_BLOCKING, ×tamp, @@ -79,7 +104,7 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin else { OSSemPend( - &CANMail_Sem4, + &(CANMail_Sem4[bus]), 0, OS_OPT_PEND_NON_BLOCKING, ×tamp, @@ -100,7 +125,7 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin uint8_t txdata[8]; uint8_t datalen = 0; - switch (id) + switch (id) //TODO: Inspect this Switch case, see if we can offload to the caller { // Handle 64bit precision case (no idx) case MC_BUS: @@ -112,9 +137,6 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin case TEMPERATURE: case ODOMETER_AMPHOURS: datalen = 8; - //TODO: I don't think we need this reversal thing, this was done looking at a logic analyzer trace showing the data frame was reversed - //We should test reception of data using BPS supplemental ASAP, and if that shows that it's wrong we need to revert this block to the memcpy - //that got removed memcpy(txdata, &payload.data.d, sizeof(txdata)); break; case ARRAY_CONTACTOR_STATE_CHANGE: @@ -127,7 +149,7 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin } OSMutexPend( // ensure that tx line is available - &CANbus_TxMutex, + &(CANbus_TxMutex[bus]), 0, OS_OPT_PEND_BLOCKING, ×tamp, @@ -135,10 +157,10 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin assertOSError(OS_CANDRIVER_LOC,err); // couldn't lock tx line // tx line locked - ErrorStatus retval = BSP_CAN_Write(CAN_1, id, txdata, datalen); + ErrorStatus retval = BSP_CAN_Write(bus, id, txdata, datalen); OSMutexPost( // unlock the TX line - &CANbus_TxMutex, + &(CANbus_TxMutex[bus]), OS_OPT_POST_NONE, &err); assertOSError(OS_CANDRIVER_LOC,err); @@ -146,15 +168,14 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin } /** - * @brief Checks if the CAN ID matches with expected ID and then copies message to given buffer array - * @param CAN line bus (variable buses not implemented, this function currently works with CAN1) + * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers * @param ID pointer to where to store the CAN id of the recieved msg - * @param pointer to buffer array to store message + * @param pointer to buffer array to store message. MUST BE 8 BYTES OR LARGER * @param blocking whether or not this read should be blocking - * @return 1 if ID matches and 0 if it doesn't + * @returns ERROR if read failed, SUCCESS otherwise */ -ErrorStatus CANbus_Read(uint32_t *id, uint8_t *buffer, CAN_blocking_t blocking) +ErrorStatus CANbus_Read(uint32_t *id, uint8_t *buffer, CAN_blocking_t blocking, CAN_t bus) { CPU_TS timestamp; OS_ERR err; @@ -162,7 +183,7 @@ ErrorStatus CANbus_Read(uint32_t *id, uint8_t *buffer, CAN_blocking_t blocking) if (blocking == CAN_BLOCKING) { OSSemPend( // check if the queue actually has anything - &CANBus_RecieveSem4, + &(CANBus_RecieveSem4[bus]), 0, OS_OPT_PEND_BLOCKING, ×tamp, @@ -172,7 +193,7 @@ ErrorStatus CANbus_Read(uint32_t *id, uint8_t *buffer, CAN_blocking_t blocking) else { OSSemPend( - &CANBus_RecieveSem4, + &(CANBus_RecieveSem4[bus]), 0, OS_OPT_PEND_NON_BLOCKING, ×tamp, @@ -189,7 +210,7 @@ ErrorStatus CANbus_Read(uint32_t *id, uint8_t *buffer, CAN_blocking_t blocking) } OSMutexPend( // ensure that RX line is available - &CANbus_RxMutex, + &(CANbus_RxMutex[bus]), 0, OS_OPT_PEND_BLOCKING, ×tamp, @@ -197,10 +218,10 @@ ErrorStatus CANbus_Read(uint32_t *id, uint8_t *buffer, CAN_blocking_t blocking) assertOSError(OS_CANDRIVER_LOC,err); // Actually get the message - ErrorStatus status = BSP_CAN_Read(CAN_1, id, buffer); + ErrorStatus status = BSP_CAN_Read(bus, id, buffer); OSMutexPost( // unlock RX line - &CANbus_RxMutex, + &(CANbus_RxMutex[bus]), OS_OPT_POST_1, &err); assertOSError(OS_CANDRIVER_LOC,err); From 03694588c20a50c39cab91b1d5e60789dcacb097 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 6 Aug 2022 05:15:54 +0000 Subject: [PATCH 002/141] New CAN data structure More flexible CAN Send structure --- Drivers/Inc/CANbus.h | 26 +++++++++++++++++--------- Drivers/Src/CANbus.c | 42 +++++++++++++++--------------------------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index 7542d0b24..7a53a84d0 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -24,10 +24,10 @@ typedef enum { typedef union { - uint8_t b; - uint16_t h; - uint32_t w; - uint64_t d; + uint8_t b; //byte + uint16_t h; //halfword + uint32_t w; //word + uint64_t d; //double } CANData_t; typedef struct { @@ -44,6 +44,16 @@ typedef struct { CANId_t id; }CANMSG_t; + +typedef struct { + CANId_t ID; //ID of message + uint8_t idx; //FOR TRANSMIT ONLY: if message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. Recieve will not touch this + bool idxEn; //FOR TRANSMIT ONLY: whether to use idx or not. Recieve will not touch this. + uint8_t size; //size of this particular message IN BYTES. On writes, this should not Exceed 8 bytes for non-idx messages, and should not exceed 7 for idx messages. + uint8_t data[8]; //data of the message +} CANDATA_t; + + typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; /** @@ -54,15 +64,14 @@ typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; void CANbus_Init(CAN_t bus); /** - * @brief Transmits data onto the CANbus. + * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. If more is needed, * @param id : CAN id of the message * @param payload : the data that will be sent. * @param blocking: Whether or not the Send should be blocking or not * @param bus: Which bus to transmit on * @return ERROR if data wasn't sent, otherwise it was sent. */ -ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload,CAN_blocking_t blocking, CAN_t bus); - +ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus); /** * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers @@ -71,7 +80,6 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload,CAN_blocking_t blocking * @param blocking whether or not this read should be blocking * @returns ERROR if read failed, SUCCESS otherwise */ -ErrorStatus CANbus_Read(uint32_t *id, uint8_t* buffer, CAN_blocking_t blocking, CAN_t bus); - +ErrorStatus CANbus_Read(CANDATA_t* data, CAN_blocking_t blocking, CAN_t bus); #endif diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 1e17d68b7..299262124 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -80,13 +80,13 @@ void CANbus_Init(CAN_t bus) } /** - * @brief Transmits data onto the CANbus + * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. If more is necessary, please use IDX * @param id : CAN id of the message * @param payload : the data that will be sent. * @param blocking: Whether or not this should be a blocking call * @return 0 if data wasn't sent, otherwise it was sent. */ -ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blocking, CAN_t bus) +ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) { CPU_TS timestamp; OS_ERR err; @@ -124,28 +124,11 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin uint8_t txdata[8]; uint8_t datalen = 0; - - switch (id) //TODO: Inspect this Switch case, see if we can offload to the caller - { - // Handle 64bit precision case (no idx) - case MC_BUS: - case VELOCITY: - case MC_PHASE_CURRENT: - case VOLTAGE_VEC: - case CURRENT_VEC: - case BACKEMF: - case TEMPERATURE: - case ODOMETER_AMPHOURS: - datalen = 8; - memcpy(txdata, &payload.data.d, sizeof(txdata)); - break; - case ARRAY_CONTACTOR_STATE_CHANGE: - datalen = 1; - txdata[0] = (payload.data.b); - break; - default: - //This should never occur - return ERROR; + if(CanData.idxEn){ //first byte of txData should be the idx value + memcpy(txdata,CanData.idx,sizeof(CanData.idx)); + memcpy(&(txdata[1]),CanData.data,CanData.size); + } else { //non-idx case + memcpy(txdata,CanData.data,CanData.size); } OSMutexPend( // ensure that tx line is available @@ -157,7 +140,12 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin assertOSError(OS_CANDRIVER_LOC,err); // couldn't lock tx line // tx line locked - ErrorStatus retval = BSP_CAN_Write(bus, id, txdata, datalen); + ErrorStatus retval = BSP_CAN_Write( + bus, //bus to transmit onto + CanData.ID, //ID from Data struct + txdata, //data we memcpy'd earlier + (CanData.idxEn ? CanData.size+1 : CanData.size) //if IDX then add one to the msg size, else the msg size + ); OSMutexPost( // unlock the TX line &(CANbus_TxMutex[bus]), @@ -175,7 +163,7 @@ ErrorStatus CANbus_Send(CANId_t id, CANPayload_t payload, CAN_blocking_t blockin * @returns ERROR if read failed, SUCCESS otherwise */ -ErrorStatus CANbus_Read(uint32_t *id, uint8_t *buffer, CAN_blocking_t blocking, CAN_t bus) +ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t bus) { CPU_TS timestamp; OS_ERR err; @@ -218,7 +206,7 @@ ErrorStatus CANbus_Read(uint32_t *id, uint8_t *buffer, CAN_blocking_t blocking, assertOSError(OS_CANDRIVER_LOC,err); // Actually get the message - ErrorStatus status = BSP_CAN_Read(bus, id, buffer); + ErrorStatus status = BSP_CAN_Read(bus, &(MsgContainer->ID), &(MsgContainer->data)); OSMutexPost( // unlock RX line &(CANbus_RxMutex[bus]), From 89b6b7620d7aca7f91cb817f2f5d1d09dc940163 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 6 Aug 2022 23:26:17 +0000 Subject: [PATCH 003/141] - Compat fixes for applications with new driver data type and function signatures - Compile fixes for driver - Deprecated data types removed --- Apps/Inc/CAN_Queue.h | 4 ++-- Apps/Src/CAN_Queue.c | 6 +++--- Apps/Src/ReadCarCAN.c | 39 ++++++++++++++++++++++----------------- Apps/Src/ReadTritium.c | 11 +++++------ Apps/Src/SendCarCAN.c | 4 ++-- Apps/Src/main.c | 2 +- Drivers/Inc/CANbus.h | 27 ++++++--------------------- Drivers/Src/CANbus.c | 22 ++++++++++++++++------ 8 files changed, 57 insertions(+), 58 deletions(-) diff --git a/Apps/Inc/CAN_Queue.h b/Apps/Inc/CAN_Queue.h index 73b2b4180..e6925a0f7 100644 --- a/Apps/Inc/CAN_Queue.h +++ b/Apps/Inc/CAN_Queue.h @@ -10,8 +10,8 @@ void CAN_Queue_Init(void); -ErrorStatus CAN_Queue_Post(CANMSG_t message); +ErrorStatus CAN_Queue_Post(CANDATA_t message); -ErrorStatus CAN_Queue_Pend(CANMSG_t *message); +ErrorStatus CAN_Queue_Pend(CANDATA_t *message); #endif diff --git a/Apps/Src/CAN_Queue.c b/Apps/Src/CAN_Queue.c index f59900689..70be11dc7 100644 --- a/Apps/Src/CAN_Queue.c +++ b/Apps/Src/CAN_Queue.c @@ -9,7 +9,7 @@ #include "Tasks.h" // fifo -#define FIFO_TYPE CANMSG_t +#define FIFO_TYPE CANDATA_t #define FIFO_SIZE 256 #define FIFO_NAME CAN_fifo #include "fifo.h" @@ -35,7 +35,7 @@ void CAN_Queue_Init(void) { assertOSError(OS_SEND_CAN_LOC, err); } -ErrorStatus CAN_Queue_Post(CANMSG_t message) { +ErrorStatus CAN_Queue_Post(CANDATA_t message) { OS_ERR err; CPU_TS ticks; OSMutexPend(&canFifo_Mutex, 0, OS_OPT_POST_NONE, &ticks, &err); @@ -52,7 +52,7 @@ ErrorStatus CAN_Queue_Post(CANMSG_t message) { return success ? SUCCESS : ERROR; } -ErrorStatus CAN_Queue_Pend(CANMSG_t *message) { +ErrorStatus CAN_Queue_Pend(CANDATA_t *message) { OS_ERR err; CPU_TS ticks; diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 912ca1a91..57df93223 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -37,11 +37,13 @@ static inline void chargingDisable(void) { Contactors_Set(ARRAY_PRECHARGE, OFF); // let array know we killed contactors - CANMSG_t msg; - msg.id = ARRAY_CONTACTOR_STATE_CHANGE; - msg.payload.bytes = 1; - msg.payload.data.b = false; - CAN_Queue_Post(msg); + CANDATA_t message; + message.ID = ARRAY_CONTACTOR_STATE_CHANGE; + message.idxEn = false; + message.idx = 0; + message.size = 1; + message.data = false; + CAN_Queue_Post(message); // turn off the array contactor light Lights_Set(A_CNCTR, OFF); @@ -104,8 +106,9 @@ static inline void chargingEnable(void) { void Task_ReadCarCAN(void *p_arg) { OS_ERR err; - uint8_t buffer[8]; // buffer for CAN message - uint32_t canId; + + //data struct for CAN message + CANDATA_t dataBuf; CPU_TS ts; OSMutexCreate(&arrayRestartMutex, "array restart mutex", &err); @@ -134,12 +137,12 @@ void Task_ReadCarCAN(void *p_arg) while (1) { //Get any message that BPS Sent us - ErrorStatus status = CANbus_Read(&canId, buffer, CAN_BLOCKING); + ErrorStatus status = CANbus_Read(&dataBuf,CAN_BLOCKING,CARCAN); if(status != SUCCESS) { continue; } - switch(canId){ //we got a message + switch(dataBuf.ID){ //we got a message case CHARGE_ENABLE: { OSMutexPend(&msg_rcv_mutex, 0, @@ -155,7 +158,7 @@ void Task_ReadCarCAN(void *p_arg) &err); assertOSError(OS_READ_CAN_LOC,err); - if(buffer[0] == 0){ // If the buffer doesn't contain 1 for enable, turn off RegenEnable and turn array off + if((&dataBuf.data)[0] == 0){ // If the buffer doesn't contain 1 for enable, turn off RegenEnable and turn array off chargingDisable(); } else { //We got a message of enable with a nonzero value, turn on Regen, If we are already in precharge / array is on, do nothing. @@ -165,11 +168,11 @@ void Task_ReadCarCAN(void *p_arg) break; } case SUPPLEMENTAL_VOLTAGE: { - SupplementalVoltage = *(uint16_t *) &buffer; + SupplementalVoltage = *(uint16_t *) &(dataBuf.data); break; } case STATE_OF_CHARGE:{ - StateOfCharge = *(uint32_t*) &buffer; //get the 32 bit message and store it + StateOfCharge = *(uint32_t*) &(dataBuf.data); //get the 32 bit message and store it break; } default: @@ -247,11 +250,13 @@ static void ArrayRestart(void *p_arg){ //Display_SetLight(A_CNCTR, ON); // let array know the contactor is on - CANMSG_t msg; - msg.id = ARRAY_CONTACTOR_STATE_CHANGE; - msg.payload.bytes = 1; - msg.payload.data.b = true; - CAN_Queue_Post(msg); + CANDATA_t databuf; + databuf.ID = ARRAY_CONTACTOR_STATE_CHANGE; + databuf.size = 1; + databuf.data = true; + databuf.idxEn = false; + databuf.idx = 0; + CAN_Queue_Post(databuf); OSMutexPend(&arrayRestartMutex, 0, diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 6cd24a4fa..48e590c35 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -10,8 +10,7 @@ void Task_ReadTritium(void *p_arg) OS_ERR err; - CANMSG_t msg; - + CANDATA_t dataBuf; while (1) { CANbuff buf; @@ -19,12 +18,12 @@ void Task_ReadTritium(void *p_arg) if (status == SUCCESS) { - - msg.id = buf.id; - msg.payload.data.d = ((uint64_t)buf.firstNum << 32) | ((uint64_t)buf.secondNum); + dataBuf.data = ((uint64_t)buf.firstNum << 32) | ((uint64_t)buf.secondNum); + dataBuf.ID = buf.id; + dataBuf.idxEn = false; __unused - ErrorStatus error = CAN_Queue_Post(msg); + ErrorStatus error = CAN_Queue_Post(dataBuf); // TODO: handle error } diff --git a/Apps/Src/SendCarCAN.c b/Apps/Src/SendCarCAN.c index 8eae60661..5c4431b8e 100644 --- a/Apps/Src/SendCarCAN.c +++ b/Apps/Src/SendCarCAN.c @@ -10,11 +10,11 @@ */ void Task_SendCarCAN(void *p_arg){ - CANMSG_t msg; + CANDATA_t msg; while (1) { CAN_Queue_Pend(&msg); - CANbus_Send(msg.id,msg.payload,CAN_BLOCKING); //send message + CANbus_Send(msg,CAN_BLOCKING,CARCAN); //send message } } diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 28079360d..ec87005f3 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -71,7 +71,7 @@ void Task_Init(void *p_arg){ MotorController_Init(1.0f); // Let motor controller use 100% of bus current OSTimeDlyHMSM(0,0,10,0,OS_OPT_TIME_HMSM_STRICT,&err); BSP_UART_Init(UART_2); - CANbus_Init(); + CANbus_Init(CARCAN); Contactors_Init(); Display_Init(); Minions_Init(); diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index 7a53a84d0..f1056c55d 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -19,38 +19,22 @@ typedef enum { CAR_STATE = 0x580, CHARGE_ENABLE = 0x10C, SUPPLEMENTAL_VOLTAGE = 0x10B, - STATE_OF_CHARGE = 0x106 + STATE_OF_CHARGE = 0x106, + DO_NOT_USE_FORCE_ENUM_SIZE = 0xFFFFFFFF //force the enum values to be 32 bits wide. This value should not be used. This is here because the BSP layer expects a 32 bit ptr for ID's } CANId_t; -typedef union { - uint8_t b; //byte - uint16_t h; //halfword - uint32_t w; //word - uint64_t d; //double -} CANData_t; -typedef struct { - uint8_t idx : 8; - uint8_t bytes : 8; - CANData_t data; //TODO: This could probably be replaced with a uint64_t -} CANPayload_t; /** - * Data type for message queue + * Standard CAN packet */ -typedef struct { - CANPayload_t payload; - CANId_t id; -}CANMSG_t; - - typedef struct { CANId_t ID; //ID of message uint8_t idx; //FOR TRANSMIT ONLY: if message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. Recieve will not touch this bool idxEn; //FOR TRANSMIT ONLY: whether to use idx or not. Recieve will not touch this. uint8_t size; //size of this particular message IN BYTES. On writes, this should not Exceed 8 bytes for non-idx messages, and should not exceed 7 for idx messages. - uint8_t data[8]; //data of the message + uint64_t data; //data of the message } CANDATA_t; @@ -74,7 +58,8 @@ void CANbus_Init(CAN_t bus); ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus); /** - * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers + * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers. + * DOES NOT POPULATE IDXen or IDX. You have to manually inspect the first byte and the ID * @param ID pointer to where to store the CAN id of the recieved msg * @param pointer to buffer array to store message. MUST BE 8 BYTES OR LARGER * @param blocking whether or not this read should be blocking diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 299262124..e20fe5c76 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -90,6 +90,17 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) { CPU_TS timestamp; OS_ERR err; + + //message error checks + if(CanData.idxEn & (CanData.size>7)){ //idx message can only handle up to 7 bytes + return ERROR; + } else if (CanData.size>8){ //non-idx message can only handle up to 8 bytes + return ERROR; + } else if (CanData.size <= 0){ //no 0 size messages allowed + return ERROR; + } + + // make sure that Can mailbox is available if (blocking == CAN_BLOCKING) { @@ -123,12 +134,11 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) } uint8_t txdata[8]; - uint8_t datalen = 0; if(CanData.idxEn){ //first byte of txData should be the idx value - memcpy(txdata,CanData.idx,sizeof(CanData.idx)); - memcpy(&(txdata[1]),CanData.data,CanData.size); + memcpy(txdata,&CanData.idx,sizeof(CanData.idx)); + memcpy(&(txdata[1]),&CanData.data,CanData.size); } else { //non-idx case - memcpy(txdata,CanData.data,CanData.size); + memcpy(txdata,&CanData.data,CanData.size); } OSMutexPend( // ensure that tx line is available @@ -156,7 +166,7 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) } /** - * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers + * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers. **DOES NOT POPULATE IDXen or IDX. You have to manually inspect the first byte and the ID** * @param ID pointer to where to store the CAN id of the recieved msg * @param pointer to buffer array to store message. MUST BE 8 BYTES OR LARGER * @param blocking whether or not this read should be blocking @@ -206,7 +216,7 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t assertOSError(OS_CANDRIVER_LOC,err); // Actually get the message - ErrorStatus status = BSP_CAN_Read(bus, &(MsgContainer->ID), &(MsgContainer->data)); + ErrorStatus status = BSP_CAN_Read(bus, (uint32_t*)(&(MsgContainer->ID)), (uint8_t*)(&(MsgContainer->data))); OSMutexPost( // unlock RX line &(CANbus_RxMutex[bus]), From 48a8e2f6dd4e1c0d6d29a400a270773ea1a5cae2 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sun, 7 Aug 2022 19:52:55 +0000 Subject: [PATCH 004/141] - Compat layer for legacy MC driver - Minor bug fixes - Notice of deprecation for legacy MC driver --- Drivers/Inc/CANbus.h | 6 ++ Drivers/Inc/MotorController.h | 14 ++- Drivers/Src/CANbus.c | 14 ++- Drivers/Src/MotorController.c | 161 ++++++++-------------------------- 4 files changed, 64 insertions(+), 131 deletions(-) diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index f1056c55d..84825643f 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -6,6 +6,7 @@ #include "BSP_CAN.h" #define CARCAN CAN_1 //convenience aliases for the CANBuses #define MOTORCAN CAN_3 +#define MAX_CAN_LEN 8 typedef enum { MC_BUS = 0x242, VELOCITY = 0x243, @@ -20,6 +21,11 @@ typedef enum { CHARGE_ENABLE = 0x10C, SUPPLEMENTAL_VOLTAGE = 0x10B, STATE_OF_CHARGE = 0x106, + MOTOR_DRIVE = 0x221, + MOTOR_POWER = 0x222, + MOTOR_RESET = 0x223, + MOTOR_STATUS = 0x241, + MOTOR_VELOCITY = 0x243, DO_NOT_USE_FORCE_ENUM_SIZE = 0xFFFFFFFF //force the enum values to be 32 bits wide. This value should not be used. This is here because the BSP layer expects a 32 bit ptr for ID's } CANId_t; diff --git a/Drivers/Inc/MotorController.h b/Drivers/Inc/MotorController.h index ea51c0a01..6e37d454d 100644 --- a/Drivers/Inc/MotorController.h +++ b/Drivers/Inc/MotorController.h @@ -1,4 +1,9 @@ /* Copyright (c) 2020 UT Longhorn Racing Solar */ +/** + * NOTE: THIS DRIVER IS ACTIVELY BEING DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED, + * YOU SHOULD MIGRATE TO USING THE MULTI-BUS CAN DRIVER + */ + #ifndef __MOTORCONTROLLER_H #define __MOTORCONTROLLER_H @@ -38,11 +43,13 @@ typedef enum{ /** * @brief Returns the current error status of the tritium controller + * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED */ tritium_error_code_t MotorController_getTritiumError(void); /** * @brief Initializes the motor controller + * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED * @param busCurrentFractionalSetPoint fraction of the bus current to allow the motor to draw * @return None */ @@ -50,6 +57,7 @@ void MotorController_Init(float busCurrentFractionalSetPoint); /** * @brief Sends MOTOR DRIVE command on CAN3 + * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED * @param newVelocity desired motor velocity setpoint in rpm * @param motorCurrent desired motor current setpoint as a fraction of max current setting * @return None @@ -58,6 +66,7 @@ void MotorController_Drive(float newVelocity, float motorCurrent); /** * @brief Reads most recent command from CAN3 bus + * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED * @param message the buffer in which the info for the CAN message will be stored * @return SUCCESS if a message is read */ @@ -65,6 +74,7 @@ ErrorStatus MotorController_Read(CANbuff *message); /** * @brief Reads velocity + * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED * @return Velocity */ float MotorController_ReadVelocity(void); @@ -72,7 +82,7 @@ float MotorController_ReadVelocity(void); /** * @brief Reads RPM of motor - * + * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED * @return RPM */ float MotorController_ReadRPM(void); @@ -80,7 +90,7 @@ float MotorController_ReadRPM(void); /** * @brief Restarts the motor controller. THIS FUNCTION IS FOR FAULT STATE USE ONLY. - * + * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED * @param busCurrentFractionalSetPoint */ void MotorController_Restart(void); diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index e20fe5c76..8f1607ce0 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -122,9 +122,10 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) &err); // don't crash if we are just using this in non-blocking mode and don't block - if (err != OS_ERR_PEND_WOULD_BLOCK) { - assertOSError(OS_CANDRIVER_LOC,err); + if(err == OS_ERR_PEND_WOULD_BLOCK){ + err = OS_ERR_NONE; } + assertOSError(OS_CANDRIVER_LOC,err); } @@ -162,6 +163,10 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) OS_OPT_POST_NONE, &err); assertOSError(OS_CANDRIVER_LOC,err); + if(retval == ERROR){ + CANbus_TxHandler(bus); //release the mailbox by posting back to the counter semaphore + } + return retval; } @@ -198,9 +203,10 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t &err); // don't crash if we are just using this in non-blocking mode and don't block - if (err != OS_ERR_PEND_WOULD_BLOCK) { - assertOSError(OS_CANDRIVER_LOC,err); + if(err == OS_ERR_PEND_WOULD_BLOCK){ + err = OS_ERR_NONE; } + assertOSError(OS_CANDRIVER_LOC,err); } if (err != OS_ERR_NONE) { diff --git a/Drivers/Src/MotorController.c b/Drivers/Src/MotorController.c index 5a01f4c05..6bc5ec929 100644 --- a/Drivers/Src/MotorController.c +++ b/Drivers/Src/MotorController.c @@ -1,17 +1,13 @@ #include "MotorController.h" #include "os.h" #include "Tasks.h" -#include "Minions.h" + #include "Display.h" +#include "CANbus.h" #include "Contactors.h" -#define MOTOR_DRIVE 0x221 -#define MOTOR_POWER 0x222 -#define MOTOR_RESET 0x223 -#define MOTOR_STATUS 0x241 -#define MOTOR_VELOCITY 0x243 -#define MAX_CAN_LEN 8 + //status msg masks #define MASK_LOW_VOLTAGE_LOCKOUT_ERR (1<<22) //Low voltage rail lockout happened @@ -24,8 +20,6 @@ #define BYTES_TO_UINT32(bytes) ((bytes[])) -static OS_SEM MotorController_MailSem4; -static OS_SEM MotorController_ReceiveSem4; static bool restartFinished = true; static float CurrentVelocity = 0; static float CurrentRPM = 0; @@ -44,7 +38,7 @@ static bool is_initialized = false; static void _assertTritiumError(tritium_error_code_t motor_err) { - if(restartFinished){ // && Contactors_Get(MOTOR_CONTACTOR) + if(restartFinished){ OS_ERR err; if(motor_err != T_NONE){ FaultBitmap |= FAULT_TRITIUM; @@ -64,52 +58,18 @@ static void _assertTritiumError(tritium_error_code_t motor_err) #define assertTritiumError(motor_err) _assertTritiumError(motor_err); #endif -/** - * @brief Releases hold of the mailbox semaphore. - * @note Do not call directly. - */ -static void MotorController_Release(void) -{ - OS_ERR err; - OSSemPost(&MotorController_MailSem4, - OS_OPT_POST_1, - &err); - assertOSError(0, err); -} -/** - * @brief Increments the receive semaphore. - * @note Do not call directly. - */ -static void MotorController_CountIncoming(void) -{ - OS_ERR err; - - OSSemPost(&MotorController_ReceiveSem4, - OS_OPT_POST_1, - &err); - assertOSError(0, err); -} - -static void MotorController_InitCommand(){ //transmits the init command with id 0x222 - OS_ERR err; - CPU_TS ts; - uint8_t data[8] = {0}; - memcpy( - data + 4, // Tritium expects the setpoint in the Most significant 32 bits, so we offset - &busCurrent, - sizeof(busCurrent)); - OSSemPend(&MotorController_MailSem4, - 0, - OS_OPT_PEND_BLOCKING, - &ts, - &err); - assertOSError(0, err); - ErrorStatus initCommand = BSP_CAN_Write(CAN_3, MOTOR_POWER, data, MAX_CAN_LEN); +static void MotorController_InitCommand(){ //transmits the init command with id 0x222 + CANDATA_t initData; + *(((uint32_t*)&initData.data)+1) = busCurrent; //put the buscurrent into the Most significant 32 bits of initData data + initData.ID = MOTOR_POWER; + initData.idx = 0; + initData.idxEn = false; + initData.size = MAX_CAN_LEN; + ErrorStatus initCommand = CANbus_Send(initData,CAN_BLOCKING,MOTORCAN); if (initCommand == ERROR) { - MotorController_Release(); Motor_FaultBitmap = T_INIT_FAIL; assertTritiumError(Motor_FaultBitmap); } @@ -125,25 +85,6 @@ void MotorController_Init(float busCurrentFractionalSetPoint) if (is_initialized) return; is_initialized = true; // Ensure that we only execute the function once - OS_ERR err; - OSSemCreate(&MotorController_MailSem4, - "Motor Controller Mailbox Semaphore", - 3, // Number of mailboxes - &err); - assertOSError(0, err); - - OSSemCreate(&MotorController_ReceiveSem4, - "Motor Controller Receive Semaphore", - 0, // Number of mailboxes - &err); - assertOSError(0, err); - - OSMutexCreate(&restartFinished_Mutex, - "Motor Controller Restart Mutex", - &err); - assertOSError(0, err); - - BSP_CAN_Init(CAN_3, MotorController_CountIncoming, MotorController_Release); busCurrent = busCurrentFractionalSetPoint; MotorController_InitCommand(); } @@ -151,30 +92,25 @@ void MotorController_Init(float busCurrentFractionalSetPoint) /** * @brief Restarts the motor controller. * - * @param busCurrentFractionalSetPoint */ void MotorController_Restart(void){ CPU_TS ts; OS_ERR err; OSMutexPend(&restartFinished_Mutex, 0, OS_OPT_POST_NONE, &ts, &err); assertOSError(0, err); - uint8_t data[8] = {0}; restartFinished = false; - OSSemPend(&MotorController_MailSem4, - 0, - OS_OPT_PEND_BLOCKING, - &ts, - &err); - assertOSError(0, err); - ErrorStatus initCommand = BSP_CAN_Write(CAN_3, MOTOR_RESET, data, MAX_CAN_LEN); //send reset command + CANDATA_t restartCommand; + restartCommand.data = 0; + restartCommand.ID = MOTOR_RESET; + restartCommand.idx = 0; + restartCommand.idxEn = false; + restartCommand.size = MAX_CAN_LEN; + ErrorStatus initCommand = CANbus_Send(restartCommand,CAN_BLOCKING,MOTORCAN); if (initCommand == ERROR) { restartFinished = true; - MotorController_Release(); - OSMutexPost(&restartFinished_Mutex, OS_OPT_POST_NONE, &err); assertOSError(0, err); - Motor_FaultBitmap = T_INIT_FAIL; assertTritiumError(Motor_FaultBitmap); return; @@ -192,24 +128,14 @@ void MotorController_Restart(void){ */ void MotorController_Drive(float newVelocity, float motorCurrent) { - CPU_TS ts; - OS_ERR err; - - uint8_t data[8]; - memcpy(data, &newVelocity, sizeof(newVelocity)); - memcpy(data + sizeof(newVelocity), &motorCurrent, sizeof(motorCurrent)); - - OSSemPend(&MotorController_MailSem4, - 0, - OS_OPT_PEND_BLOCKING, - &ts, - &err); - assertOSError(0, err); - ErrorStatus result = BSP_CAN_Write(CAN_3, MOTOR_DRIVE, data, MAX_CAN_LEN); - if (result == ERROR) - { - MotorController_Release(); - } + CANDATA_t driveCommand; + *((uint32_t*)&driveCommand.data) = newVelocity; //copy velocity into LS 32 bits + *(((uint32_t*)&driveCommand.data)+1) = motorCurrent; //copy current into MS 32 bits + driveCommand.ID = MOTOR_DRIVE; + driveCommand.idx = 0; + driveCommand.idxEn = false; + driveCommand.size = MAX_CAN_LEN; + CANbus_Send(driveCommand,CAN_NON_BLOCKING,MOTORCAN); } /** @@ -222,42 +148,24 @@ void MotorController_Drive(float newVelocity, float motorCurrent) ErrorStatus MotorController_Read(CANbuff *message) { - uint32_t id; - uint8_t data[8] = {0}; uint32_t firstSum = 0; uint32_t secondSum = 0; CPU_TS ts; OS_ERR err; - // Check to see if a mailbox is available: BLOCKING - OSSemPend( - &MotorController_ReceiveSem4, - 0, - OS_OPT_PEND_BLOCKING, - &ts, - &err); - assertOSError(0, err); - ErrorStatus status = BSP_CAN_Read(CAN_3, &id, data); + CANDATA_t motormsg; + ErrorStatus status = CANbus_Read(&motormsg,CAN_NON_BLOCKING,MOTORCAN); if (status == SUCCESS) { - message->id = id; - //get first number (bits 0-31) - for(int j = (MAX_CAN_LEN/2)-1 ; j >= 0; j--){ - firstSum <<= 8; - firstSum += data[j]; - } - - //get second number (bits 32-63) - for(int k = MAX_CAN_LEN - 1; k >= (MAX_CAN_LEN/2); k--){ - secondSum <<= 8; - secondSum += data[k]; - } + firstSum = *(uint32_t*)&(motormsg.data); //first 32 bits + secondSum = *(((uint32_t*)&(motormsg.data))+1); //second 32 bits + message->id = motormsg.ID; message->firstNum = firstSum; message->secondNum = secondSum; - switch (id) { + switch (motormsg.ID) { // If we're reading the output from the Motor Status command (0x241) then // Check the status bits we care about and set flags accordingly case MOTOR_STATUS: { @@ -305,6 +213,9 @@ ErrorStatus MotorController_Read(CANbuff *message) CurrentRPM = *(float*) &firstSum; break; } + default: { + break; + } // if(MASK_OVER_SPEED_ERR & firstSum){ // Motor_FaultBitmap |= T_OVER_SPEED_ERR; From a71434266a4c39287f75a7a02da659dd1a529194 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 13 Aug 2022 15:38:41 +0000 Subject: [PATCH 005/141] reconfigured enum and implemented lookup table --- Drivers/Inc/CANbus.h | 99 ++++++++++++++++++++++++++++++++------------ Drivers/Src/CANbus.c | 20 +++++---- 2 files changed, 84 insertions(+), 35 deletions(-) diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index 84825643f..b9dce11f3 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -7,40 +7,87 @@ #define CARCAN CAN_1 //convenience aliases for the CANBuses #define MOTORCAN CAN_3 #define MAX_CAN_LEN 8 -typedef enum { - MC_BUS = 0x242, - VELOCITY = 0x243, - MC_PHASE_CURRENT = 0x244, - VOLTAGE_VEC = 0x245, - CURRENT_VEC = 0x246, - BACKEMF = 0x247, - TEMPERATURE = 0x24B, - ODOMETER_AMPHOURS = 0x24E, - ARRAY_CONTACTOR_STATE_CHANGE = 0x24F, - CAR_STATE = 0x580, - CHARGE_ENABLE = 0x10C, - SUPPLEMENTAL_VOLTAGE = 0x10B, - STATE_OF_CHARGE = 0x106, - MOTOR_DRIVE = 0x221, - MOTOR_POWER = 0x222, - MOTOR_RESET = 0x223, - MOTOR_STATUS = 0x241, - MOTOR_VELOCITY = 0x243, - DO_NOT_USE_FORCE_ENUM_SIZE = 0xFFFFFFFF //force the enum values to be 32 bits wide. This value should not be used. This is here because the BSP layer expects a 32 bit ptr for ID's -} CANId_t; +/** + * @brief Struct to use in CAN MSG LUT + * @param idxEn Whether or not this message is part of a sequence of messages. + * @param size Size of message's data + * @param ID The actual CAN ID of this message + */ +typedef struct { + bool idxEn; + uint8_t size; + uint32_t ID; +} CANLUT_T; + +/** + * @brief Lookup table to simplify user-defined packet structs. Contains fields that are always the same for every message of a given ID. + * Indexed by CANId_t values. + * FOR DRIVER USE ONLY. + */ +static CANLUT_T CANLUT[NUM_CAN_IDS] = { + {false, MAX_CAN_LEN, 0x10C}, + {false, MAX_CAN_LEN, 0x106}, + {false, MAX_CAN_LEN, 0x10B}, + {false, MAX_CAN_LEN, 0x580}, + {false, MAX_CAN_LEN, 0x242}, + {false, MAX_CAN_LEN, 0x243}, + {false, MAX_CAN_LEN, 0x244}, + {false, MAX_CAN_LEN, 0x245}, + {false, MAX_CAN_LEN, 0x246}, + {false, MAX_CAN_LEN, 0x247}, + {false, MAX_CAN_LEN, 0x248}, + {false, MAX_CAN_LEN, 0x24E}, + {false, MAX_CAN_LEN, 0x24F}, + {false, MAX_CAN_LEN, 0x221}, + {false, MAX_CAN_LEN, 0x222}, + {false, MAX_CAN_LEN, 0x223}, + {false, MAX_CAN_LEN, 0x241}, + {false, MAX_CAN_LEN, 0x243}, +}; + +/** + * @brief This enum is used to signify the ID of the message you want to send. + * It is used internally to index our lookup table (above) and get message-specific fields. + * If changing the order of this enum, make sure to mirror that change in the lookup table, or + * else the driver will not work properly. + */ +typedef enum { + CHARGE_ENABLE = 0, + STATE_OF_CHARGE, + SUPPLEMENTAL_VOLTAGE, + CAR_STATE, + MC_BUS, + VELOCITY, + MC_PHASE_CURRENT, + VOLTAGE_VEC, + CURRENT_VEC, + BACKEMF, + TEMPERATURE, + ODOMETER_AMPHOURS, + ARRAY_CONTACTOR_STATE_CHANGE, + MOTOR_DRIVE, + MOTOR_POWER, + MOTOR_RESET, + MOTOR_STATUS, + MOTOR_VELOCITY, + NUM_CAN_IDS +} CANId_t; /** * Standard CAN packet + * @param ID CANId_t value indicating which message we are trying to send + * @param idx FOR TRANSMIT ONLY: + * if message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. + * This is not designed to exceed the 8bit unsigned max value. + * @param data data of the message */ typedef struct { - CANId_t ID; //ID of message - uint8_t idx; //FOR TRANSMIT ONLY: if message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. Recieve will not touch this - bool idxEn; //FOR TRANSMIT ONLY: whether to use idx or not. Recieve will not touch this. - uint8_t size; //size of this particular message IN BYTES. On writes, this should not Exceed 8 bytes for non-idx messages, and should not exceed 7 for idx messages. - uint64_t data; //data of the message + CANId_t ID; + uint8_t idx; + uint8_t data[8]; } CANDATA_t; diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 8f1607ce0..c727441a1 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -91,12 +91,14 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) CPU_TS timestamp; OS_ERR err; + CANLUT_T msginfo = CANLUT[CanData.ID]; //lookup msg information in table + //message error checks - if(CanData.idxEn & (CanData.size>7)){ //idx message can only handle up to 7 bytes + if(msginfo.idxEn & (msginfo.size>7)){ //idx message can only handle up to 7 bytes return ERROR; - } else if (CanData.size>8){ //non-idx message can only handle up to 8 bytes + } else if (msginfo.size>8){ //non-idx message can only handle up to 8 bytes return ERROR; - } else if (CanData.size <= 0){ //no 0 size messages allowed + } else if (msginfo.size <= 0){ //no 0 size messages allowed return ERROR; } @@ -123,7 +125,7 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) // don't crash if we are just using this in non-blocking mode and don't block if(err == OS_ERR_PEND_WOULD_BLOCK){ - err = OS_ERR_NONE; + return ERROR; } assertOSError(OS_CANDRIVER_LOC,err); } @@ -135,11 +137,11 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) } uint8_t txdata[8]; - if(CanData.idxEn){ //first byte of txData should be the idx value + if(msginfo.idxEn){ //first byte of txData should be the idx value memcpy(txdata,&CanData.idx,sizeof(CanData.idx)); - memcpy(&(txdata[1]),&CanData.data,CanData.size); + memcpy(&(txdata[sizeof(CanData.idx)]),&CanData.data,msginfo.size); } else { //non-idx case - memcpy(txdata,&CanData.data,CanData.size); + memcpy(txdata,&CanData.data,msginfo.size); } OSMutexPend( // ensure that tx line is available @@ -155,7 +157,7 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) bus, //bus to transmit onto CanData.ID, //ID from Data struct txdata, //data we memcpy'd earlier - (CanData.idxEn ? CanData.size+1 : CanData.size) //if IDX then add one to the msg size, else the msg size + (msginfo.idxEn ? msginfo.size+sizeof(CanData.idx) : msginfo.size) //if IDX then add one to the msg size, else the msg size ); OSMutexPost( // unlock the TX line @@ -204,7 +206,7 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t // don't crash if we are just using this in non-blocking mode and don't block if(err == OS_ERR_PEND_WOULD_BLOCK){ - err = OS_ERR_NONE; + return ERROR; } assertOSError(OS_CANDRIVER_LOC,err); } From 87c5f28d8220a33c1ad18472ac65eb3e1a77da8f Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 13 Aug 2022 16:20:09 +0000 Subject: [PATCH 006/141] implemented LUT and build fixes --- Apps/Src/ReadCarCAN.c | 8 ++--- Apps/Src/ReadTritium.c | 8 ++--- Drivers/Inc/CANbus.h | 61 +++++++++++++++++++---------------- Drivers/Src/CANbus.c | 6 +++- Drivers/Src/MotorController.c | 12 ++----- 5 files changed, 47 insertions(+), 48 deletions(-) diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 57df93223..18f2579c0 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -39,10 +39,8 @@ static inline void chargingDisable(void) { // let array know we killed contactors CANDATA_t message; message.ID = ARRAY_CONTACTOR_STATE_CHANGE; - message.idxEn = false; message.idx = 0; - message.size = 1; - message.data = false; + message.data[0] = false; CAN_Queue_Post(message); // turn off the array contactor light @@ -252,9 +250,7 @@ static void ArrayRestart(void *p_arg){ // let array know the contactor is on CANDATA_t databuf; databuf.ID = ARRAY_CONTACTOR_STATE_CHANGE; - databuf.size = 1; - databuf.data = true; - databuf.idxEn = false; + databuf.data[0] = true; databuf.idx = 0; CAN_Queue_Post(databuf); diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 48e590c35..f898822d3 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -18,12 +18,12 @@ void Task_ReadTritium(void *p_arg) if (status == SUCCESS) { - dataBuf.data = ((uint64_t)buf.firstNum << 32) | ((uint64_t)buf.secondNum); + dataBuf.data[0] = buf.secondNum; + dataBuf.data[4] = buf.firstNum; dataBuf.ID = buf.id; - dataBuf.idxEn = false; - __unused - ErrorStatus error = CAN_Queue_Post(dataBuf); + __attribute__((unused)) + ErrorStatus error = CAN_Queue_Post(dataBuf); // TODO: handle error } diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index b9dce11f3..374395926 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -6,8 +6,12 @@ #include "BSP_CAN.h" #define CARCAN CAN_1 //convenience aliases for the CANBuses #define MOTORCAN CAN_3 -#define MAX_CAN_LEN 8 +//macros to define canmsg length in LUT +#define BYTE 1 +#define HALFWORD 2 +#define WORD 4 +#define DOUBLE 8 /** * @brief Struct to use in CAN MSG LUT @@ -20,33 +24,6 @@ typedef struct { uint8_t size; uint32_t ID; } CANLUT_T; - -/** - * @brief Lookup table to simplify user-defined packet structs. Contains fields that are always the same for every message of a given ID. - * Indexed by CANId_t values. - * FOR DRIVER USE ONLY. - */ -static CANLUT_T CANLUT[NUM_CAN_IDS] = { - {false, MAX_CAN_LEN, 0x10C}, - {false, MAX_CAN_LEN, 0x106}, - {false, MAX_CAN_LEN, 0x10B}, - {false, MAX_CAN_LEN, 0x580}, - {false, MAX_CAN_LEN, 0x242}, - {false, MAX_CAN_LEN, 0x243}, - {false, MAX_CAN_LEN, 0x244}, - {false, MAX_CAN_LEN, 0x245}, - {false, MAX_CAN_LEN, 0x246}, - {false, MAX_CAN_LEN, 0x247}, - {false, MAX_CAN_LEN, 0x248}, - {false, MAX_CAN_LEN, 0x24E}, - {false, MAX_CAN_LEN, 0x24F}, - {false, MAX_CAN_LEN, 0x221}, - {false, MAX_CAN_LEN, 0x222}, - {false, MAX_CAN_LEN, 0x223}, - {false, MAX_CAN_LEN, 0x241}, - {false, MAX_CAN_LEN, 0x243}, -}; - /** * @brief This enum is used to signify the ID of the message you want to send. * It is used internally to index our lookup table (above) and get message-specific fields. @@ -76,6 +53,34 @@ typedef enum { } CANId_t; +/** + * @brief Lookup table to simplify user-defined packet structs. Contains fields that are always the same for every message of a given ID. + * Indexed by CANId_t values. + * FOR DRIVER USE ONLY. + */ +CANLUT_T CANLUT[NUM_CAN_IDS] = { + {false, DOUBLE, 0x10C}, + {false, DOUBLE, 0x106}, + {false, DOUBLE, 0x10B}, + {false, DOUBLE, 0x580}, + {false, DOUBLE, 0x242}, + {false, DOUBLE, 0x243}, + {false, DOUBLE, 0x244}, + {false, DOUBLE, 0x245}, + {false, DOUBLE, 0x246}, + {false, DOUBLE, 0x247}, + {false, DOUBLE, 0x248}, + {false, DOUBLE, 0x24E}, + {false, BYTE , 0x24F}, + {false, DOUBLE, 0x221}, + {false, DOUBLE, 0x222}, + {false, DOUBLE, 0x223}, + {false, DOUBLE, 0x241}, + {false, DOUBLE, 0x243}, +}; + + + /** * Standard CAN packet * @param ID CANId_t value indicating which message we are trying to send diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index c727441a1..7d4a7bfad 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -224,7 +224,11 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t assertOSError(OS_CANDRIVER_LOC,err); // Actually get the message - ErrorStatus status = BSP_CAN_Read(bus, (uint32_t*)(&(MsgContainer->ID)), (uint8_t*)(&(MsgContainer->data))); + uint32_t id; + uint64_t dat; + ErrorStatus status = BSP_CAN_Read(bus, &id, (uint8_t*)&dat); + MsgContainer->ID = id; + MsgContainer->data[0] = dat; OSMutexPost( // unlock RX line &(CANbus_RxMutex[bus]), diff --git a/Drivers/Src/MotorController.c b/Drivers/Src/MotorController.c index 6bc5ec929..d5e85ca48 100644 --- a/Drivers/Src/MotorController.c +++ b/Drivers/Src/MotorController.c @@ -60,13 +60,11 @@ static void _assertTritiumError(tritium_error_code_t motor_err) -static void MotorController_InitCommand(){ //transmits the init command with id 0x222 +static void MotorController_InitCommand(){ //transmits the init command CANDATA_t initData; - *(((uint32_t*)&initData.data)+1) = busCurrent; //put the buscurrent into the Most significant 32 bits of initData data + initData.data[4] = busCurrent; //put 32bit busCurrent value in most significant 32 bits initData.ID = MOTOR_POWER; initData.idx = 0; - initData.idxEn = false; - initData.size = MAX_CAN_LEN; ErrorStatus initCommand = CANbus_Send(initData,CAN_BLOCKING,MOTORCAN); if (initCommand == ERROR) { @@ -101,11 +99,9 @@ void MotorController_Restart(void){ restartFinished = false; CANDATA_t restartCommand; - restartCommand.data = 0; + restartCommand.data[0] = 0; restartCommand.ID = MOTOR_RESET; restartCommand.idx = 0; - restartCommand.idxEn = false; - restartCommand.size = MAX_CAN_LEN; ErrorStatus initCommand = CANbus_Send(restartCommand,CAN_BLOCKING,MOTORCAN); if (initCommand == ERROR) { restartFinished = true; @@ -133,8 +129,6 @@ void MotorController_Drive(float newVelocity, float motorCurrent) *(((uint32_t*)&driveCommand.data)+1) = motorCurrent; //copy current into MS 32 bits driveCommand.ID = MOTOR_DRIVE; driveCommand.idx = 0; - driveCommand.idxEn = false; - driveCommand.size = MAX_CAN_LEN; CANbus_Send(driveCommand,CAN_NON_BLOCKING,MOTORCAN); } From b35df362cce90eb8376d9cc030a03a5e165b8115 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 17 Sep 2022 22:40:00 +0000 Subject: [PATCH 007/141] - Moved LUT into the C file to fix linker issue - Moved LUT struct def into the C file - fixed doc comments --- Drivers/Inc/CANbus.h | 79 +++++++++----------------------------------- Drivers/Src/CANbus.c | 63 +++++++++++++++++++++++++++++++---- 2 files changed, 73 insertions(+), 69 deletions(-) diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index 374395926..d0e8787aa 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -7,28 +7,11 @@ #define CARCAN CAN_1 //convenience aliases for the CANBuses #define MOTORCAN CAN_3 -//macros to define canmsg length in LUT -#define BYTE 1 -#define HALFWORD 2 -#define WORD 4 -#define DOUBLE 8 - -/** - * @brief Struct to use in CAN MSG LUT - * @param idxEn Whether or not this message is part of a sequence of messages. - * @param size Size of message's data - * @param ID The actual CAN ID of this message - */ -typedef struct { - bool idxEn; - uint8_t size; - uint32_t ID; -} CANLUT_T; /** * @brief This enum is used to signify the ID of the message you want to send. - * It is used internally to index our lookup table (above) and get message-specific fields. + * It is used internally to index our lookup table (CANbus.C) and get message-specific fields. * If changing the order of this enum, make sure to mirror that change in the lookup table, or - * else the driver will not work properly. + * else the driver will not work properly. This also applies if you are adding additional CAN messages. */ typedef enum { CHARGE_ENABLE = 0, @@ -52,42 +35,12 @@ typedef enum { NUM_CAN_IDS } CANId_t; - -/** - * @brief Lookup table to simplify user-defined packet structs. Contains fields that are always the same for every message of a given ID. - * Indexed by CANId_t values. - * FOR DRIVER USE ONLY. - */ -CANLUT_T CANLUT[NUM_CAN_IDS] = { - {false, DOUBLE, 0x10C}, - {false, DOUBLE, 0x106}, - {false, DOUBLE, 0x10B}, - {false, DOUBLE, 0x580}, - {false, DOUBLE, 0x242}, - {false, DOUBLE, 0x243}, - {false, DOUBLE, 0x244}, - {false, DOUBLE, 0x245}, - {false, DOUBLE, 0x246}, - {false, DOUBLE, 0x247}, - {false, DOUBLE, 0x248}, - {false, DOUBLE, 0x24E}, - {false, BYTE , 0x24F}, - {false, DOUBLE, 0x221}, - {false, DOUBLE, 0x222}, - {false, DOUBLE, 0x223}, - {false, DOUBLE, 0x241}, - {false, DOUBLE, 0x243}, -}; - - - /** * Standard CAN packet - * @param ID CANId_t value indicating which message we are trying to send - * @param idx FOR TRANSMIT ONLY: - * if message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. - * This is not designed to exceed the 8bit unsigned max value. - * @param data data of the message + * @param ID CANId_t value indicating which message we are trying to send + * @param idx If message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. + * This is not designed to exceed the 8bit unsigned max value. + * @param data data of the message */ typedef struct { CANId_t ID; @@ -95,7 +48,9 @@ typedef struct { uint8_t data[8]; } CANDATA_t; - +/** + * Standard identifier for whether or not a CAN transaction is blocking or not + */ typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; /** @@ -107,20 +62,18 @@ void CANbus_Init(CAN_t bus); /** * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. If more is needed, - * @param id : CAN id of the message - * @param payload : the data that will be sent. - * @param blocking: Whether or not the Send should be blocking or not - * @param bus: Which bus to transmit on + * @param CanData The data to be transmitted + * @param blocking Whether or not this transmission should be a blocking send. + * @param bus The bus to transmit on. This should be either CARCAN or MOTORCAN. * @return ERROR if data wasn't sent, otherwise it was sent. */ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus); /** - * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers. - * DOES NOT POPULATE IDXen or IDX. You have to manually inspect the first byte and the ID - * @param ID pointer to where to store the CAN id of the recieved msg - * @param pointer to buffer array to store message. MUST BE 8 BYTES OR LARGER - * @param blocking whether or not this read should be blocking + * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers. + * @param data pointer to where to store the CAN id of the recieved msg + * @param blocking Whether or not this read should be a blocking read + * @param bus The bus to use. This should either be CARCAN or MOTORCAN. * @returns ERROR if read failed, SUCCESS otherwise */ ErrorStatus CANbus_Read(CANDATA_t* data, CAN_blocking_t blocking, CAN_t bus); diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 7d4a7bfad..6a9e53524 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -8,9 +8,55 @@ static OS_SEM CANBus_RecieveSem4[NUM_CAN]; // sem4 to count how many msgs in our static OS_MUTEX CANbus_TxMutex[NUM_CAN]; // mutex to lock tx line static OS_MUTEX CANbus_RxMutex[NUM_CAN]; // mutex to lock Rx line + +/** + * @brief Struct to use in CAN MSG LUT + * @param idxEn Whether or not this message is part of a sequence of messages. + * @param size Size of message's data + * @param ID The actual CAN ID of this message + */ +typedef struct { + bool idxEn; + uint8_t size; + uint32_t ID; +} CANLUT_T; + + +//macros to define canmsg length in LUT +#define BYTE 1 +#define HALFWORD 2 +#define WORD 4 +#define DOUBLE 8 + +/** + * @brief Lookup table to simplify user-defined packet structs. Contains fields that are always the same for every message of a given ID. + * Indexed by CANId_t values. + * FOR DRIVER USE ONLY. + */ +CANLUT_T CANLUT[NUM_CAN_IDS] = { + {false, DOUBLE, 0x10C}, + {false, DOUBLE, 0x106}, + {false, DOUBLE, 0x10B}, + {false, DOUBLE, 0x580}, + {false, DOUBLE, 0x242}, + {false, DOUBLE, 0x243}, + {false, DOUBLE, 0x244}, + {false, DOUBLE, 0x245}, + {false, DOUBLE, 0x246}, + {false, DOUBLE, 0x247}, + {false, DOUBLE, 0x248}, + {false, DOUBLE, 0x24E}, + {false, BYTE , 0x24F}, + {false, DOUBLE, 0x221}, + {false, DOUBLE, 0x222}, + {false, DOUBLE, 0x223}, + {false, DOUBLE, 0x241}, + {false, DOUBLE, 0x243}, +}; + /** * @brief this function will be passed down to the BSP layer to trigger on RX events. Increments the recieve semaphore to signal message in hardware mailbox. Do not access directly. - * @param bus The CAN bus to operate on + * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. */ void CANbus_RxHandler(CAN_t bus) { @@ -21,7 +67,7 @@ void CANbus_RxHandler(CAN_t bus) /** * @brief this function will be passed down to the BSP layer to trigger on TXend. Releases hold of the mailbox semaphore (Increments it to show mailbox available). Do not access directly. - * @param bus The CAN bus to operate on + * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. */ void CANbus_TxHandler(CAN_t bus) { @@ -35,13 +81,13 @@ void CANbus_TxHandler_1(){ CANbus_TxHandler(CAN_1); } -void CANbus_TxHandler_3(){ - CANbus_TxHandler(CAN_3); -} void CANbus_RxHandler_1(){ CANbus_RxHandler(CAN_1); } +void CANbus_TxHandler_3(){ + CANbus_TxHandler(CAN_3); +} void CANbus_RxHandler_3(){ CANbus_RxHandler(CAN_3); } @@ -93,7 +139,7 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) CANLUT_T msginfo = CANLUT[CanData.ID]; //lookup msg information in table - //message error checks + //lookup table error checks if(msginfo.idxEn & (msginfo.size>7)){ //idx message can only handle up to 7 bytes return ERROR; } else if (msginfo.size>8){ //non-idx message can only handle up to 8 bytes @@ -235,5 +281,10 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t OS_OPT_POST_1, &err); assertOSError(OS_CANDRIVER_LOC,err); + + //search LUT for idmatch to populate idx and trim data + for(uint8_t i = 0; i Date: Sun, 18 Sep 2022 17:41:01 +0000 Subject: [PATCH 008/141] - changed file organization - still need to make readfunc populate the idx field --- Drivers/Inc/CANbus.h | 28 +++++++++++++++++++++++--- Drivers/Src/CANLUT.c | 35 +++++++++++++++++++++++++++++++++ Drivers/Src/CANbus.c | 47 +------------------------------------------- 3 files changed, 61 insertions(+), 49 deletions(-) create mode 100644 Drivers/Src/CANLUT.c diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index d0e8787aa..00c0bdcec 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -8,10 +8,15 @@ #define MOTORCAN CAN_3 /** - * @brief This enum is used to signify the ID of the message you want to send. - * It is used internally to index our lookup table (CANbus.C) and get message-specific fields. + * This enum is used to signify the ID of the message you want to send. + * It is used internally to index our lookup table (CANLUT.C) and get message-specific fields. + * For user purposes, it selects the message to send. + * * If changing the order of this enum, make sure to mirror that change in the lookup table, or - * else the driver will not work properly. This also applies if you are adding additional CAN messages. + * else the driver will not work properly. + * + * If adding new types of CAN messages, add the identifier above NUM_CAN_IDs, and then go to CANLUT.c to add an entry for + * the new message in the lookup */ typedef enum { CHARGE_ENABLE = 0, @@ -35,6 +40,23 @@ typedef enum { NUM_CAN_IDS } CANId_t; +/** + * @brief Struct to use in CAN MSG LUT + * @param idxEn Whether or not this message is part of a sequence of messages. + * @param size Size of message's data + * @param ID The actual CAN ID of this message + */ +typedef struct { + bool idxEn; + uint8_t size; + uint32_t ID; +} CANLUT_T; + +/** + * The lookup table containing the entries for all of our CAN messages. Located in CANLUT.c + */ +extern CANLUT_T CANLUT[NUM_CAN_IDS]; + /** * Standard CAN packet * @param ID CANId_t value indicating which message we are trying to send diff --git a/Drivers/Src/CANLUT.c b/Drivers/Src/CANLUT.c new file mode 100644 index 000000000..b27814ede --- /dev/null +++ b/Drivers/Src/CANLUT.c @@ -0,0 +1,35 @@ + +#include "CANbus.h" + +#define BYTE 1 +#define HALFWORD 2 +#define WORD 4 +#define DOUBLE 8 +#define NOIDX false +#define IDX true + + +/** + * @brief Lookup table to simplify user-defined packet structs. Contains fields that are always the same for every message of a given ID. + * Indexed by CANId_t values. Any changes or additions must be made in parallel with changes made to the CANID_t enum in CANbus.h + */ +CANLUT_T CANLUT[NUM_CAN_IDS] = { + {NOIDX, DOUBLE, 0x10C}, /** CHARGE_ENABLE **/ + {NOIDX, DOUBLE, 0x106}, /** STATE_OF_CHARGE **/ + {NOIDX, DOUBLE, 0x10B}, /** SUPPLEMENTAL_VOLTAGE **/ + {NOIDX, DOUBLE, 0x580}, /** CAR_STATE **/ + {NOIDX, DOUBLE, 0x242}, /** MC_BUS **/ + {NOIDX, DOUBLE, 0x243}, /** VELOCITY **/ + {NOIDX, DOUBLE, 0x244}, /** MC_PHASE_CURRENT **/ + {NOIDX, DOUBLE, 0x245}, /** VOLTAGE_VEC **/ + {NOIDX, DOUBLE, 0x246}, /** CURRENT_VEC **/ + {NOIDX, DOUBLE, 0x247}, /** BACKEMF **/ + {NOIDX, DOUBLE, 0x248}, /** TEMPERATURE **/ + {NOIDX, DOUBLE, 0x24E}, /** ODOMETER_AMPHOURS **/ + {NOIDX, BYTE , 0x24F}, /** ARRAY_CONTACTOR_STATE_CHANGE **/ + {NOIDX, DOUBLE, 0x221}, /** MOTOR_DRIVE **/ + {NOIDX, DOUBLE, 0x222}, /** MOTOR_POWER **/ + {NOIDX, DOUBLE, 0x223}, /** MOTOR_RESET **/ + {NOIDX, DOUBLE, 0x241}, /** MOTOR_STATUS **/ + {NOIDX, DOUBLE, 0x243}, /** MOTOR_VELOCITY **/ +}; diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 6a9e53524..13750b2c5 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -9,51 +9,6 @@ static OS_MUTEX CANbus_TxMutex[NUM_CAN]; // mutex to lock tx line static OS_MUTEX CANbus_RxMutex[NUM_CAN]; // mutex to lock Rx line -/** - * @brief Struct to use in CAN MSG LUT - * @param idxEn Whether or not this message is part of a sequence of messages. - * @param size Size of message's data - * @param ID The actual CAN ID of this message - */ -typedef struct { - bool idxEn; - uint8_t size; - uint32_t ID; -} CANLUT_T; - - -//macros to define canmsg length in LUT -#define BYTE 1 -#define HALFWORD 2 -#define WORD 4 -#define DOUBLE 8 - -/** - * @brief Lookup table to simplify user-defined packet structs. Contains fields that are always the same for every message of a given ID. - * Indexed by CANId_t values. - * FOR DRIVER USE ONLY. - */ -CANLUT_T CANLUT[NUM_CAN_IDS] = { - {false, DOUBLE, 0x10C}, - {false, DOUBLE, 0x106}, - {false, DOUBLE, 0x10B}, - {false, DOUBLE, 0x580}, - {false, DOUBLE, 0x242}, - {false, DOUBLE, 0x243}, - {false, DOUBLE, 0x244}, - {false, DOUBLE, 0x245}, - {false, DOUBLE, 0x246}, - {false, DOUBLE, 0x247}, - {false, DOUBLE, 0x248}, - {false, DOUBLE, 0x24E}, - {false, BYTE , 0x24F}, - {false, DOUBLE, 0x221}, - {false, DOUBLE, 0x222}, - {false, DOUBLE, 0x223}, - {false, DOUBLE, 0x241}, - {false, DOUBLE, 0x243}, -}; - /** * @brief this function will be passed down to the BSP layer to trigger on RX events. Increments the recieve semaphore to signal message in hardware mailbox. Do not access directly. * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. @@ -139,7 +94,7 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) CANLUT_T msginfo = CANLUT[CanData.ID]; //lookup msg information in table - //lookup table error checks + // lookup table def error checks if(msginfo.idxEn & (msginfo.size>7)){ //idx message can only handle up to 7 bytes return ERROR; } else if (msginfo.size>8){ //non-idx message can only handle up to 8 bytes From 478cbf540ddc2e1de8d20aae726b2b083ec38c26 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 24 Sep 2022 15:52:21 +0000 Subject: [PATCH 009/141] changed lookup table to be a sparse array, changed enum to fit --- Drivers/Inc/CANbus.h | 41 ++++++++++++++++++++--------------------- Drivers/Src/CANLUT.c | 36 ++++++++++++++++++------------------ Drivers/Src/CANbus.c | 7 +++++-- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index 00c0bdcec..60fbbc48e 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -15,28 +15,28 @@ * If changing the order of this enum, make sure to mirror that change in the lookup table, or * else the driver will not work properly. * - * If adding new types of CAN messages, add the identifier above NUM_CAN_IDs, and then go to CANLUT.c to add an entry for - * the new message in the lookup + * If adding new types of CAN messages, add the identifier wherever it fits in + * (the enum is sorted in ascending order on purpus), and then add an entry to the lookup table. */ typedef enum { - CHARGE_ENABLE = 0, - STATE_OF_CHARGE, - SUPPLEMENTAL_VOLTAGE, - CAR_STATE, - MC_BUS, - VELOCITY, - MC_PHASE_CURRENT, - VOLTAGE_VEC, - CURRENT_VEC, - BACKEMF, - TEMPERATURE, - ODOMETER_AMPHOURS, - ARRAY_CONTACTOR_STATE_CHANGE, - MOTOR_DRIVE, - MOTOR_POWER, - MOTOR_RESET, - MOTOR_STATUS, - MOTOR_VELOCITY, + CHARGE_ENABLE = 0x10C, + STATE_OF_CHARGE = 0x106, + SUPPLEMENTAL_VOLTAGE = 0x10B, + // CAR_STATE = 0x580, + MOTOR_DRIVE = 0x221, + MOTOR_POWER = 0x222, + MOTOR_RESET = 0x223, + MOTOR_STATUS = 0x241, + MOTOR_VELOCITY = 0x243, + MC_BUS = 0x242, + VELOCITY = 0x243, + MC_PHASE_CURRENT = 0x244, + VOLTAGE_VEC = 0x245, + CURRENT_VEC = 0x246, + BACKEMF = 0x247, + TEMPERATURE = 0x248, + ODOMETER_AMPHOURS = 0x24E, + ARRAY_CONTACTOR_STATE_CHANGE = 0x24F, NUM_CAN_IDS } CANId_t; @@ -49,7 +49,6 @@ typedef enum { typedef struct { bool idxEn; uint8_t size; - uint32_t ID; } CANLUT_T; /** diff --git a/Drivers/Src/CANLUT.c b/Drivers/Src/CANLUT.c index b27814ede..dec719cf4 100644 --- a/Drivers/Src/CANLUT.c +++ b/Drivers/Src/CANLUT.c @@ -14,22 +14,22 @@ * Indexed by CANId_t values. Any changes or additions must be made in parallel with changes made to the CANID_t enum in CANbus.h */ CANLUT_T CANLUT[NUM_CAN_IDS] = { - {NOIDX, DOUBLE, 0x10C}, /** CHARGE_ENABLE **/ - {NOIDX, DOUBLE, 0x106}, /** STATE_OF_CHARGE **/ - {NOIDX, DOUBLE, 0x10B}, /** SUPPLEMENTAL_VOLTAGE **/ - {NOIDX, DOUBLE, 0x580}, /** CAR_STATE **/ - {NOIDX, DOUBLE, 0x242}, /** MC_BUS **/ - {NOIDX, DOUBLE, 0x243}, /** VELOCITY **/ - {NOIDX, DOUBLE, 0x244}, /** MC_PHASE_CURRENT **/ - {NOIDX, DOUBLE, 0x245}, /** VOLTAGE_VEC **/ - {NOIDX, DOUBLE, 0x246}, /** CURRENT_VEC **/ - {NOIDX, DOUBLE, 0x247}, /** BACKEMF **/ - {NOIDX, DOUBLE, 0x248}, /** TEMPERATURE **/ - {NOIDX, DOUBLE, 0x24E}, /** ODOMETER_AMPHOURS **/ - {NOIDX, BYTE , 0x24F}, /** ARRAY_CONTACTOR_STATE_CHANGE **/ - {NOIDX, DOUBLE, 0x221}, /** MOTOR_DRIVE **/ - {NOIDX, DOUBLE, 0x222}, /** MOTOR_POWER **/ - {NOIDX, DOUBLE, 0x223}, /** MOTOR_RESET **/ - {NOIDX, DOUBLE, 0x241}, /** MOTOR_STATUS **/ - {NOIDX, DOUBLE, 0x243}, /** MOTOR_VELOCITY **/ + [CHARGE_ENABLE] = {NOIDX, DOUBLE}, /** CHARGE_ENABLE **/ + [STATE_OF_CHARGE] = {NOIDX, DOUBLE}, /** STATE_OF_CHARGE **/ + [SUPPLEMENTAL_VOLTAGE] = {NOIDX, DOUBLE}, /** SUPPLEMENTAL_VOLTAGE **/ + // [CAR_STATE] = {NOIDX, DOUBLE, 0x580}, /** CAR_STATE **/ + [MC_BUS] = {NOIDX, DOUBLE}, /** MC_BUS **/ + [VELOCITY] = {NOIDX, DOUBLE}, /** VELOCITY **/ + [MC_PHASE_CURRENT] = {NOIDX, DOUBLE}, /** MC_PHASE_CURRENT **/ + [VOLTAGE_VEC] = {NOIDX, DOUBLE}, /** VOLTAGE_VEC **/ + [CURRENT_VEC] = {NOIDX, DOUBLE}, /** CURRENT_VEC **/ + [BACKEMF] = {NOIDX, DOUBLE}, /** BACKEMF **/ + [TEMPERATURE] = {NOIDX, DOUBLE}, /** TEMPERATURE **/ + [ODOMETER_AMPHOURS] = {NOIDX, DOUBLE}, /** ODOMETER_AMPHOURS **/ + [ARRAY_CONTACTOR_STATE_CHANGE] = {NOIDX, BYTE }, /** ARRAY_CONTACTOR_STATE_CHANGE **/ + [MOTOR_DRIVE] = {NOIDX, DOUBLE}, /** MOTOR_DRIVE **/ + [MOTOR_POWER] = {NOIDX, DOUBLE}, /** MOTOR_POWER **/ + [MOTOR_RESET] = {NOIDX, DOUBLE}, /** MOTOR_RESET **/ + [MOTOR_STATUS] = {NOIDX, DOUBLE}, /** MOTOR_STATUS **/ + [MOTOR_VELOCITY] = {NOIDX, DOUBLE}, /** MOTOR_VELOCITY **/ }; diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 13750b2c5..eaa475bd7 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -238,8 +238,11 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t assertOSError(OS_CANDRIVER_LOC,err); //search LUT for idmatch to populate idx and trim data - for(uint8_t i = 0; idata[0]; + CANLUT_T entry = CANLUT[lookupid]; + if(entry.idxEn==true){ + } + return status; } From 214490cf7060578da59d5afb90d884e2b1a3a8a5 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 24 Sep 2022 21:17:02 +0000 Subject: [PATCH 010/141] implemented read functionality --- Drivers/Src/CANbus.c | 51 ++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index eaa475bd7..b4deda07e 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -36,7 +36,6 @@ void CANbus_TxHandler_1(){ CANbus_TxHandler(CAN_1); } - void CANbus_RxHandler_1(){ CANbus_RxHandler(CAN_1); } @@ -48,9 +47,8 @@ void CANbus_RxHandler_3(){ } /** - * @brief Initializes the CAN system - * @param None - * @return None + * @brief Initializes the CAN system for a given bus. Must be called independently for each bus. + * @param bus */ void CANbus_Init(CAN_t bus) { @@ -58,8 +56,6 @@ void CANbus_Init(CAN_t bus) // initialize tx OS_ERR err; - - OSMutexCreate(&(CANbus_TxMutex[bus]), (bus == CAN_1 ? "CAN TX Lock 1":"CAN TX Lock 3"), &err); assertOSError(OS_CANDRIVER_LOC,err); @@ -81,11 +77,11 @@ void CANbus_Init(CAN_t bus) } /** - * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. If more is necessary, please use IDX + * @brief Transmits data onto the specified CANbus. Transmits up to 8 bytes at a time. If more is necessary, please use an IDX message. * @param id : CAN id of the message * @param payload : the data that will be sent. - * @param blocking: Whether or not this should be a blocking call - * @return 0 if data wasn't sent, otherwise it was sent. + * @param blocking: Whether or not this should be a blocking call + * @return ERROR if data wasn't sent, SUCCESS if it was sent. */ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) { @@ -103,7 +99,6 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) return ERROR; } - // make sure that Can mailbox is available if (blocking == CAN_BLOCKING) { @@ -113,7 +108,6 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) OS_OPT_PEND_BLOCKING, ×tamp, &err); - assertOSError(OS_CANDRIVER_LOC,err); } else { @@ -128,15 +122,15 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) if(err == OS_ERR_PEND_WOULD_BLOCK){ return ERROR; } - assertOSError(OS_CANDRIVER_LOC,err); } - - if (err != OS_ERR_NONE) { + assertOSError(OS_CANDRIVER_LOC,err); return ERROR; } + + uint8_t txdata[8]; if(msginfo.idxEn){ //first byte of txData should be the idx value memcpy(txdata,&CanData.idx,sizeof(CanData.idx)); @@ -175,10 +169,10 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) /** * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers. **DOES NOT POPULATE IDXen or IDX. You have to manually inspect the first byte and the ID** - * @param ID pointer to where to store the CAN id of the recieved msg - * @param pointer to buffer array to store message. MUST BE 8 BYTES OR LARGER - * @param blocking whether or not this read should be blocking - * @returns ERROR if read failed, SUCCESS otherwise + * @param MsgContainer Where to store the recieved message + * @param blocking Whether or not this read should be blocking + * @param bus Which bus to read a message from + * @returns ERROR if read failed, SUCCESS otherwise */ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t bus) @@ -194,7 +188,6 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t OS_OPT_PEND_BLOCKING, ×tamp, &err); - assertOSError(OS_CANDRIVER_LOC,err); } else { @@ -209,10 +202,10 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t if(err == OS_ERR_PEND_WOULD_BLOCK){ return ERROR; } - assertOSError(OS_CANDRIVER_LOC,err); } if (err != OS_ERR_NONE) { + assertOSError(OS_CANDRIVER_LOC,err); return ERROR; } @@ -226,10 +219,8 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t // Actually get the message uint32_t id; - uint64_t dat; - ErrorStatus status = BSP_CAN_Read(bus, &id, (uint8_t*)&dat); - MsgContainer->ID = id; - MsgContainer->data[0] = dat; + ErrorStatus status = BSP_CAN_Read(bus, &id, MsgContainer->data); + MsgContainer->ID = (CANId_t) id; OSMutexPost( // unlock RX line &(CANbus_RxMutex[bus]), @@ -237,12 +228,16 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t &err); assertOSError(OS_CANDRIVER_LOC,err); - //search LUT for idmatch to populate idx and trim data - CANId_t lookupid = (CANId_t) MsgContainer->data[0]; - CANLUT_T entry = CANLUT[lookupid]; + //search LUT for id to populate idx and trim data + CANLUT_T entry = CANLUT[MsgContainer->ID]; if(entry.idxEn==true){ + MsgContainer->idx = MsgContainer->data[0]; + memcpy( + MsgContainer->data, + &(MsgContainer->data[1]), + 7 + ); } - return status; } From a77f10de36b98529c81a8bd6d073010f5436a911 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Mon, 3 Oct 2022 03:13:54 +0000 Subject: [PATCH 011/141] more appropriate error checking in CANbus_Send --- Drivers/Src/CANbus.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index b4deda07e..55be137b5 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -88,16 +88,14 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) CPU_TS timestamp; OS_ERR err; + //error check the id + if(CanData.ID >= NUM_CAN_IDS){return ERROR;} + CANLUT_T msginfo = CANLUT[CanData.ID]; //lookup msg information in table + + //if they passed in an invalid id, it will be zero + if(msginfo.size == 0){return ERROR;} - // lookup table def error checks - if(msginfo.idxEn & (msginfo.size>7)){ //idx message can only handle up to 7 bytes - return ERROR; - } else if (msginfo.size>8){ //non-idx message can only handle up to 8 bytes - return ERROR; - } else if (msginfo.size <= 0){ //no 0 size messages allowed - return ERROR; - } // make sure that Can mailbox is available if (blocking == CAN_BLOCKING) From 1dd0a4c6fb1bce9fe316d4e574164ad6a616034f Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 8 Oct 2022 22:16:05 +0000 Subject: [PATCH 012/141] - fixed temperature CAN ID - fixed comments - fixed lookup table type --- Drivers/Inc/CANbus.h | 15 +++++++-------- Drivers/Src/CANLUT.c | 2 +- Drivers/Src/CANbus.c | 26 ++++++++++++++------------ 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index 60fbbc48e..0d6672c49 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -34,7 +34,7 @@ typedef enum { VOLTAGE_VEC = 0x245, CURRENT_VEC = 0x246, BACKEMF = 0x247, - TEMPERATURE = 0x248, + TEMPERATURE = 0x24B, ODOMETER_AMPHOURS = 0x24E, ARRAY_CONTACTOR_STATE_CHANGE = 0x24F, NUM_CAN_IDS @@ -43,18 +43,17 @@ typedef enum { /** * @brief Struct to use in CAN MSG LUT * @param idxEn Whether or not this message is part of a sequence of messages. - * @param size Size of message's data - * @param ID The actual CAN ID of this message + * @param size Size of message's data. Should be a maximum of eight (in decimal). */ typedef struct { - bool idxEn; - uint8_t size; + bool idxEn: 1; + unsigned int size: 7; } CANLUT_T; /** * The lookup table containing the entries for all of our CAN messages. Located in CANLUT.c */ -extern CANLUT_T CANLUT[NUM_CAN_IDS]; +extern const CANLUT_T CANLUT[NUM_CAN_IDS]; /** * Standard CAN packet @@ -76,10 +75,10 @@ typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; /** * @brief Initializes the CAN system for a given bus - * @param bus The bus to initialize. You can either use CAN_1, CAN_3, or the convenience macros CARCAN and MOTORCAN + * @param bus The bus to initialize. You can either use CAN_1, CAN_3, or the convenience macros CARCAN and MOTORCAN. CAN2 will not be supported. * @return None */ -void CANbus_Init(CAN_t bus); +ErrorStatus CANbus_Init(CAN_t bus); /** * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. If more is needed, diff --git a/Drivers/Src/CANLUT.c b/Drivers/Src/CANLUT.c index dec719cf4..a0a849962 100644 --- a/Drivers/Src/CANLUT.c +++ b/Drivers/Src/CANLUT.c @@ -13,7 +13,7 @@ * @brief Lookup table to simplify user-defined packet structs. Contains fields that are always the same for every message of a given ID. * Indexed by CANId_t values. Any changes or additions must be made in parallel with changes made to the CANID_t enum in CANbus.h */ -CANLUT_T CANLUT[NUM_CAN_IDS] = { +const CANLUT_T CANLUT[NUM_CAN_IDS] = { [CHARGE_ENABLE] = {NOIDX, DOUBLE}, /** CHARGE_ENABLE **/ [STATE_OF_CHARGE] = {NOIDX, DOUBLE}, /** STATE_OF_CHARGE **/ [SUPPLEMENTAL_VOLTAGE] = {NOIDX, DOUBLE}, /** SUPPLEMENTAL_VOLTAGE **/ diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 55be137b5..86d5faff8 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -10,7 +10,7 @@ static OS_MUTEX CANbus_RxMutex[NUM_CAN]; // mutex to lock Rx line /** - * @brief this function will be passed down to the BSP layer to trigger on RX events. Increments the recieve semaphore to signal message in hardware mailbox. Do not access directly. + * @brief this function will be passed down to the BSP layer to trigger on RX events. Increments the recieve semaphore to signal message in hardware mailbox. Do not access directly outside this driver. * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. */ void CANbus_RxHandler(CAN_t bus) @@ -21,7 +21,7 @@ void CANbus_RxHandler(CAN_t bus) } /** - * @brief this function will be passed down to the BSP layer to trigger on TXend. Releases hold of the mailbox semaphore (Increments it to show mailbox available). Do not access directly. + * @brief this function will be passed down to the BSP layer to trigger on TXend. Releases hold of the mailbox semaphore (Increments it to show mailbox available). Do not access directly outside this driver. * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. */ void CANbus_TxHandler(CAN_t bus) @@ -50,12 +50,20 @@ void CANbus_RxHandler_3(){ * @brief Initializes the CAN system for a given bus. Must be called independently for each bus. * @param bus */ -void CANbus_Init(CAN_t bus) +ErrorStatus CANbus_Init(CAN_t bus) { // initialize CAN mailbox semaphore to 3 for the 3 CAN mailboxes that we have // initialize tx OS_ERR err; + if(bus==CAN_1){ + BSP_CAN_Init(bus,&CANbus_RxHandler_1,&CANbus_TxHandler_1); + } else if (bus==CAN_3){ + BSP_CAN_Init(bus,&CANbus_RxHandler_3,&CANbus_TxHandler_3); + } else { + return ERROR; + } + OSMutexCreate(&(CANbus_TxMutex[bus]), (bus == CAN_1 ? "CAN TX Lock 1":"CAN TX Lock 3"), &err); assertOSError(OS_CANDRIVER_LOC,err); @@ -68,12 +76,7 @@ void CANbus_Init(CAN_t bus) OSSemCreate(&(CANBus_RecieveSem4[bus]), (bus == CAN_1 ? "CAN Recieved Msg Queue Ctr 1":"CAN Recieved Msg Queue Ctr 3"), 0, &err); // create a mailbox counter to hold the messages in as they come in assertOSError(OS_CANDRIVER_LOC,err); - if(bus==CAN_1){ - BSP_CAN_Init(bus,&CANbus_RxHandler_1,&CANbus_TxHandler_1); - } else if (bus==CAN_3){ - BSP_CAN_Init(bus,&CANbus_RxHandler_3,&CANbus_TxHandler_3); - } - + return SUCCESS; } /** @@ -93,8 +96,7 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) CANLUT_T msginfo = CANLUT[CanData.ID]; //lookup msg information in table - //if they passed in an invalid id, it will be zero - if(msginfo.size == 0){return ERROR;} + if(msginfo.size == 0){return ERROR;} //if they passed in an invalid id, it will be zero // make sure that Can mailbox is available @@ -131,7 +133,7 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) uint8_t txdata[8]; if(msginfo.idxEn){ //first byte of txData should be the idx value - memcpy(txdata,&CanData.idx,sizeof(CanData.idx)); + memcpy(txdata,&CanData.idx,1); memcpy(&(txdata[sizeof(CanData.idx)]),&CanData.data,msginfo.size); } else { //non-idx case memcpy(txdata,&CanData.data,msginfo.size); From abd795a34e22f7150e73d00e8de11744882e6416 Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 15 Oct 2022 10:48:47 -0500 Subject: [PATCH 013/141] Small fixes --- Apps/Src/ReadTritium.c | 3 +-- Apps/Src/main.c | 1 + Drivers/Inc/CANbus.h | 4 ++-- Drivers/Src/CANbus.c | 12 ++++++------ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index f898822d3..88c2ef087 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -22,8 +22,7 @@ void Task_ReadTritium(void *p_arg) dataBuf.data[4] = buf.firstNum; dataBuf.ID = buf.id; - __attribute__((unused)) - ErrorStatus error = CAN_Queue_Post(dataBuf); + (void) CAN_Queue_Post(dataBuf); // TODO: handle error } diff --git a/Apps/Src/main.c b/Apps/Src/main.c index ec87005f3..9f8ce16fa 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -72,6 +72,7 @@ void Task_Init(void *p_arg){ OSTimeDlyHMSM(0,0,10,0,OS_OPT_TIME_HMSM_STRICT,&err); BSP_UART_Init(UART_2); CANbus_Init(CARCAN); + CANbus_Init(MOTORCAN); Contactors_Init(); Display_Init(); Minions_Init(); diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index 0d6672c49..1acc1f429 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -16,7 +16,7 @@ * else the driver will not work properly. * * If adding new types of CAN messages, add the identifier wherever it fits in - * (the enum is sorted in ascending order on purpus), and then add an entry to the lookup table. + * (the enum is sorted in ascending order on purpose), and then add an entry to the lookup table. */ typedef enum { CHARGE_ENABLE = 0x10C, @@ -81,7 +81,7 @@ typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; ErrorStatus CANbus_Init(CAN_t bus); /** - * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. If more is needed, + * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. If more is necessary, please use an IDX message. * @param CanData The data to be transmitted * @param blocking Whether or not this transmission should be a blocking send. * @param bus The bus to transmit on. This should be either CARCAN or MOTORCAN. diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 86d5faff8..8f7fc1eed 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -133,10 +133,10 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) uint8_t txdata[8]; if(msginfo.idxEn){ //first byte of txData should be the idx value - memcpy(txdata,&CanData.idx,1); - memcpy(&(txdata[sizeof(CanData.idx)]),&CanData.data,msginfo.size); + memcpy(txdata, &CanData.idx, 1); + memcpy(&(txdata[sizeof(CanData.idx)]), &CanData.data, msginfo.size); } else { //non-idx case - memcpy(txdata,&CanData.data,msginfo.size); + memcpy(txdata, &CanData.data, msginfo.size); } OSMutexPend( // ensure that tx line is available @@ -224,7 +224,7 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t OSMutexPost( // unlock RX line &(CANbus_RxMutex[bus]), - OS_OPT_POST_1, + OS_OPT_POST_NONE, &err); assertOSError(OS_CANDRIVER_LOC,err); @@ -232,10 +232,10 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t CANLUT_T entry = CANLUT[MsgContainer->ID]; if(entry.idxEn==true){ MsgContainer->idx = MsgContainer->data[0]; - memcpy( + memmove( // Can't use memcpy, as memory regions overlap MsgContainer->data, &(MsgContainer->data[1]), - 7 + 7 // max size of data (8) - size of idx byte (1) ); } From 2a0999cfd00b1732b30efa6a9e9f74dfd7f39ca1 Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 15 Oct 2022 14:48:16 -0500 Subject: [PATCH 014/141] Started CANbus test file --- Tests/Test_CANbus.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 Tests/Test_CANbus.c diff --git a/Tests/Test_CANbus.c b/Tests/Test_CANbus.c new file mode 100644 index 000000000..1c55122c2 --- /dev/null +++ b/Tests/Test_CANbus.c @@ -0,0 +1,59 @@ +#include "common.h" +#include "os.h" +#include "CANbus.h" +#include + +static OS_TCB Task1TCB; +static CPU_STK Task1Stk[128]; + +void Task1(void *p_arg) { + OS_ERR err; + + CPU_Init(); + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + + CANDATA_t msg; + msg.ID = MOTOR_DRIVE; + msg.idx = 0; + float vel = 312.0f; + float current = 0.8f; + memcpy(&msg.data[0], &vel, sizeof vel); + memcpy(&msg.data[4], ¤t, sizeof current); + + CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + + msg.ID = ARRAY_CONTACTOR_STATE_CHANGE; + msg.idx = 0; + msg.data[0] = 1; + CANbus_Send(msg, CAN_NON_BLOCKING, CARCAN); + +} + + + +int main(void) { + OS_ERR err; + OSInit(&err); + if (CANbus_Init(CARCAN) == ERROR) return -1; + if (CANbus_Init(MOTORCAN) == ERROR) return -1; + + OSTaskCreate( + &Task1TCB, + "Task 1", + Task1, + NULL, + 4, + Task1Stk, + 64, + 128, + 0, + 0, + NULL, + OS_OPT_TASK_STK_CLR | OS_OPT_TASK_STK_CHK, + &err + ); + + OSStart(&err); + +} \ No newline at end of file From 05c0ce32086cb7d7c55e792a5d6010d87afd1766 Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 15 Oct 2022 17:29:50 -0500 Subject: [PATCH 015/141] Added some tests for repeated blocking and non-blocking CANbus_Send --- Tests/Test_CANbus.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/Tests/Test_CANbus.c b/Tests/Test_CANbus.c index 1c55122c2..1d1d03c9b 100644 --- a/Tests/Test_CANbus.c +++ b/Tests/Test_CANbus.c @@ -7,11 +7,18 @@ static OS_TCB Task1TCB; static CPU_STK Task1Stk[128]; void Task1(void *p_arg) { + (void) p_arg; OS_ERR err; CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + /** + * +-------------+ + * | CANbus_Send | + * +-------------+ + */ + CANDATA_t msg; msg.ID = MOTOR_DRIVE; msg.idx = 0; @@ -20,14 +27,45 @@ void Task1(void *p_arg) { memcpy(&msg.data[0], &vel, sizeof vel); memcpy(&msg.data[4], ¤t, sizeof current); - CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); + CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); msg.ID = ARRAY_CONTACTOR_STATE_CHANGE; msg.idx = 0; msg.data[0] = 1; - CANbus_Send(msg, CAN_NON_BLOCKING, CARCAN); + CANbus_Send(msg, CAN_BLOCKING, CARCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + + // Now test non-blocking CAN send + // The latter ones should return an error + msg.ID = MOTOR_DRIVE; + memcpy(&msg.data[0], &vel, sizeof vel); + memcpy(&msg.data[4], ¤t, sizeof current); + volatile ErrorStatus e; + e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); + e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); + e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); // Potentially an error? + e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); // Almost definitely an error, check in GDB + (void) e; + + OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_HMSM_STRICT, &err); + + // Now do the same test, but blocking this time + // All of the operations should succeed, so we should see four CAN messages + e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); + e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); + e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); + e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); + + + /** + * +-------------+ + * | CANbus_Read | + * +-------------+ + */ + // Might have to put CAN in loopback mode to test this? + } From 77464fc884c15a214944702b581712acf7d46f2e Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 22 Oct 2022 12:30:45 -0500 Subject: [PATCH 016/141] Some changes to test --- Tests/Test_CANbus.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Tests/Test_CANbus.c b/Tests/Test_CANbus.c index 1d1d03c9b..154fbb01f 100644 --- a/Tests/Test_CANbus.c +++ b/Tests/Test_CANbus.c @@ -20,6 +20,7 @@ void Task1(void *p_arg) { */ CANDATA_t msg; + CANDATA_t response; msg.ID = MOTOR_DRIVE; msg.idx = 0; float vel = 312.0f; @@ -28,12 +29,15 @@ void Task1(void *p_arg) { memcpy(&msg.data[4], ¤t, sizeof current); CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); + CANbus_Read(&response, CAN_BLOCKING, CARCAN); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + msg.ID = ARRAY_CONTACTOR_STATE_CHANGE; msg.idx = 0; msg.data[0] = 1; CANbus_Send(msg, CAN_BLOCKING, CARCAN); + CANbus_Read(&response, CAN_BLOCKING, MOTORCAN); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Now test non-blocking CAN send @@ -46,16 +50,24 @@ void Task1(void *p_arg) { e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); // Potentially an error? e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); // Almost definitely an error, check in GDB + + CANbus_Read(&response, CAN_BLOCKING, CARCAN); + CANbus_Read(&response, CAN_BLOCKING, CARCAN); + CANbus_Read(&response, CAN_BLOCKING, CARCAN); + CANbus_Read(&response, CAN_BLOCKING, CARCAN); (void) e; OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_HMSM_STRICT, &err); + /* // Now do the same test, but blocking this time // All of the operations should succeed, so we should see four CAN messages e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); + */ + /** @@ -66,6 +78,11 @@ void Task1(void *p_arg) { // Might have to put CAN in loopback mode to test this? + + + while (1) { + OSTimeDlyHMSM(1, 0, 0, 0, OS_OPT_TIME_HMSM_STRICT, &err); + } } From 1abaee5558a224a99cd17db997a0820e9523cca3 Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 22 Oct 2022 18:19:54 -0500 Subject: [PATCH 017/141] Put CAN1 and CAN3 in loopback mode for testing --- BSP/STM32F413/Src/BSP_CAN.c | 8 +++--- Tests/Test_CANbus.c | 53 ++++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/BSP/STM32F413/Src/BSP_CAN.c b/BSP/STM32F413/Src/BSP_CAN.c index d859ed8c9..2cc010b3c 100644 --- a/BSP/STM32F413/Src/BSP_CAN.c +++ b/BSP/STM32F413/Src/BSP_CAN.c @@ -89,8 +89,8 @@ void BSP_CAN1_Init() { CAN_InitStruct.CAN_AWUM = DISABLE; CAN_InitStruct.CAN_NART = DISABLE; CAN_InitStruct.CAN_RFLM = DISABLE; - CAN_InitStruct.CAN_TXFP = DISABLE; - CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; + CAN_InitStruct.CAN_TXFP = ENABLE; + CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack; // Change back to normal after testing! CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; /* CAN Baudrate = 125 KBps @@ -184,8 +184,8 @@ void BSP_CAN3_Init() CAN_InitStruct.CAN_AWUM = DISABLE; CAN_InitStruct.CAN_NART = DISABLE; CAN_InitStruct.CAN_RFLM = DISABLE; - CAN_InitStruct.CAN_TXFP = DISABLE; - CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; // TODO: change back to Normal after testing + CAN_InitStruct.CAN_TXFP = ENABLE; + CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack; // TODO: change back to Normal after testing CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; /* CAN Baudrate = 125 KBps diff --git a/Tests/Test_CANbus.c b/Tests/Test_CANbus.c index 154fbb01f..e96edc524 100644 --- a/Tests/Test_CANbus.c +++ b/Tests/Test_CANbus.c @@ -6,6 +6,12 @@ static OS_TCB Task1TCB; static CPU_STK Task1Stk[128]; +void createDummyMsg(CANDATA_t *msg, CANId_t id, uint64_t data) { + msg->ID = id; + msg->idx = 0; + memcpy(&msg->data, &data , sizeof data); +} + void Task1(void *p_arg) { (void) p_arg; OS_ERR err; @@ -29,7 +35,7 @@ void Task1(void *p_arg) { memcpy(&msg.data[4], ¤t, sizeof current); CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); - CANbus_Read(&response, CAN_BLOCKING, CARCAN); + CANbus_Read(&response, CAN_BLOCKING, MOTORCAN); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); @@ -37,37 +43,46 @@ void Task1(void *p_arg) { msg.idx = 0; msg.data[0] = 1; CANbus_Send(msg, CAN_BLOCKING, CARCAN); - CANbus_Read(&response, CAN_BLOCKING, MOTORCAN); + CANbus_Read(&response, CAN_BLOCKING, CARCAN); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Now test non-blocking CAN send // The latter ones should return an error - msg.ID = MOTOR_DRIVE; - memcpy(&msg.data[0], &vel, sizeof vel); - memcpy(&msg.data[4], ¤t, sizeof current); + CANDATA_t msg1, msg2, msg3, msg4; + createDummyMsg(&msg1, MOTOR_DRIVE, 1L); + createDummyMsg(&msg2, MOTOR_DRIVE, 2L); + createDummyMsg(&msg3, MOTOR_DRIVE, 3L); + createDummyMsg(&msg4, MOTOR_DRIVE, 4L); + volatile ErrorStatus e; - e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); - e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); - e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); // Potentially an error? - e = CANbus_Send(msg, CAN_NON_BLOCKING, MOTORCAN); // Almost definitely an error, check in GDB + e = CANbus_Send(msg1, CAN_NON_BLOCKING, MOTORCAN); + e = CANbus_Send(msg2, CAN_NON_BLOCKING, MOTORCAN); + e = CANbus_Send(msg3, CAN_NON_BLOCKING, MOTORCAN); // Potentially an error? + e = CANbus_Send(msg4, CAN_NON_BLOCKING, MOTORCAN); // Almost definitely an error, check in GDB + + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + + CANbus_Read(&msg1, CAN_NON_BLOCKING, MOTORCAN); + CANbus_Read(&msg2, CAN_NON_BLOCKING, MOTORCAN); + CANbus_Read(&msg3, CAN_NON_BLOCKING, MOTORCAN); + CANbus_Read(&msg4, CAN_NON_BLOCKING, MOTORCAN); - CANbus_Read(&response, CAN_BLOCKING, CARCAN); - CANbus_Read(&response, CAN_BLOCKING, CARCAN); - CANbus_Read(&response, CAN_BLOCKING, CARCAN); - CANbus_Read(&response, CAN_BLOCKING, CARCAN); (void) e; OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_HMSM_STRICT, &err); - /* + // Now do the same test, but blocking this time // All of the operations should succeed, so we should see four CAN messages - e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); - e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); - e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); - e = CANbus_Send(msg, CAN_BLOCKING, MOTORCAN); - */ + e = CANbus_Send(msg1, CAN_BLOCKING, MOTORCAN); + e = CANbus_Send(msg2, CAN_BLOCKING, MOTORCAN); + e = CANbus_Send(msg3, CAN_BLOCKING, MOTORCAN); + e = CANbus_Send(msg4, CAN_BLOCKING, MOTORCAN); + CANbus_Read(&msg1, CAN_BLOCKING, MOTORCAN); + CANbus_Read(&msg2, CAN_BLOCKING, MOTORCAN); + CANbus_Read(&msg3, CAN_BLOCKING, MOTORCAN); + CANbus_Read(&msg4, CAN_BLOCKING, MOTORCAN); /** From ab1fc370d9f460c658b809d984547996f07a2952 Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 29 Oct 2022 16:10:29 -0500 Subject: [PATCH 018/141] Connected CAN1 and CAN3 to test read/writes --- BSP/STM32F413/Src/BSP_CAN.c | 4 ++-- Tests/Test_CANbus.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/BSP/STM32F413/Src/BSP_CAN.c b/BSP/STM32F413/Src/BSP_CAN.c index 2cc010b3c..74fb5f565 100644 --- a/BSP/STM32F413/Src/BSP_CAN.c +++ b/BSP/STM32F413/Src/BSP_CAN.c @@ -90,7 +90,7 @@ void BSP_CAN1_Init() { CAN_InitStruct.CAN_NART = DISABLE; CAN_InitStruct.CAN_RFLM = DISABLE; CAN_InitStruct.CAN_TXFP = ENABLE; - CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack; // Change back to normal after testing! + CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; /* CAN Baudrate = 125 KBps @@ -185,7 +185,7 @@ void BSP_CAN3_Init() CAN_InitStruct.CAN_NART = DISABLE; CAN_InitStruct.CAN_RFLM = DISABLE; CAN_InitStruct.CAN_TXFP = ENABLE; - CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack; // TODO: change back to Normal after testing + CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; /* CAN Baudrate = 125 KBps diff --git a/Tests/Test_CANbus.c b/Tests/Test_CANbus.c index e96edc524..ed70451a8 100644 --- a/Tests/Test_CANbus.c +++ b/Tests/Test_CANbus.c @@ -25,6 +25,7 @@ void Task1(void *p_arg) { * +-------------+ */ + /* CANDATA_t msg; CANDATA_t response; msg.ID = MOTOR_DRIVE; @@ -84,6 +85,19 @@ void Task1(void *p_arg) { CANbus_Read(&msg3, CAN_BLOCKING, MOTORCAN); CANbus_Read(&msg4, CAN_BLOCKING, MOTORCAN); + */ + + CANDATA_t msg; + msg.ID = STATE_OF_CHARGE; + msg.idx = 0; + float a = 420.69f; + float b = 13.37f; + memcpy(&msg.data[0], &a, sizeof a); + memcpy(&msg.data[4], &b, sizeof b); + CANbus_Send(msg, CAN_BLOCKING, CARCAN); + CANbus_Read(&msg, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + /** * +-------------+ From 9f5d6dd00bdc46ac6cb2f1626d63bf01fc319463 Mon Sep 17 00:00:00 2001 From: Arnav Surjan Date: Sat, 29 Oct 2022 23:01:20 +0000 Subject: [PATCH 019/141] Objectives for ReadTritium Rewrite --- Apps/Src/ReadTritium.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 6cd24a4fa..65703cfec 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -5,6 +5,27 @@ #include "CANbus.h" #include +/* OBJECTIVES: +Objective 1: +- Receive motor status message from MotorController +- interpret error status + - if error + - assertOSError +- determine information important to telementry + - SendCarCAN +- determine information important for storage + - acquire mutex on Storage Array + - Store information in Storage Array (based on index) + - release mutex on Storage Array + +Objective 2: +- create function able to read data from Storage Array + - pend on Storage Array mutex + - acquire Storage Array mutex + - read information of array index + - release Storage Array mutex +*/ + void Task_ReadTritium(void *p_arg) { From 621ae685380508eeb6edfa2a58abfb6d2052a646 Mon Sep 17 00:00:00 2001 From: Arnav Surjan Date: Sat, 5 Nov 2022 19:01:39 +0000 Subject: [PATCH 020/141] 11/5 - AM --- Apps/Src/ReadTritium.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 65703cfec..109fd3c70 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -7,7 +7,7 @@ /* OBJECTIVES: Objective 1: -- Receive motor status message from MotorController +- Receive motor status message from MotorController (18.4.2) - interpret error status - if error - assertOSError @@ -32,10 +32,11 @@ void Task_ReadTritium(void *p_arg) OS_ERR err; CANMSG_t msg; - + while (1) { - CANbuff buf; + +/* CANbuff buf; ErrorStatus status = MotorController_Read(&buf); if (status == SUCCESS) @@ -49,6 +50,7 @@ void Task_ReadTritium(void *p_arg) // TODO: handle error } +*/ OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_HMSM_NON_STRICT, &err); assertOSError(OS_READ_TRITIUM_LOC, err); } From f9f20011a43cba8b502d7793d54dd2374ee94bd7 Mon Sep 17 00:00:00 2001 From: Arnav Surjan Date: Sat, 5 Nov 2022 22:08:22 +0000 Subject: [PATCH 021/141] 11/5 - PM --- Apps/Src/ReadTritium.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 109fd3c70..c03700304 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -32,10 +32,16 @@ void Task_ReadTritium(void *p_arg) OS_ERR err; CANMSG_t msg; + + CANId_t ID; + CANDATA_t data; + CAN_blocking_t blocking; + while (1) { - + ErrorStatus status = CANbus_Read(CANDATA_t* data, CAN_blocking_t blocking, CAN_t MOTORCAN); + /* CANbuff buf; ErrorStatus status = MotorController_Read(&buf); From 20116485ec116ad06df949f9c0eec0f4fd117743 Mon Sep 17 00:00:00 2001 From: Gage Miller Date: Sat, 12 Nov 2022 22:47:16 +0000 Subject: [PATCH 022/141] Implemented error handling --- Apps/Inc/ReadTritium.h | 24 +++++++++++++- Apps/Src/ReadTritium.c | 71 +++++++++++++++++++++++++++++++----------- 2 files changed, 76 insertions(+), 19 deletions(-) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index 12beea2a0..3e2995a49 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -7,6 +7,28 @@ #include "common.h" #include "Tasks.h" -#include "MotorController.h" +/** + * Motor Error States + * Read messages from motor in ReadTritium and trigger appropriate error messages as needed based on bits + * + */ +typedef enum{ + T_HARDWARE_OVER_CURRENT_ERR = (1<<0), + T_SOFTWARE_OVER_CURRENT_ERR = (1<<1), + T_DC_BUS_OVERVOLT_ERR = (1<<2), + T_HALL_SENSOR_ERR = (1<<3), + T_WATCHDOG_LAST_RESET_ERR = (1<<4), + T_CONFIG_READ_ERR = (1<<5), + T_UNDER_VOLTAGE_LOCKOUT_ERR = (1<<6), + T_DESAT_FAULT_ERR = (1<<7), + T_MOTOR_OVER_SPEED_ERR = (1<<8), + T_NONE = 0x00, +} tritium_error_code_t; +#define NUM_TRITIUM_ERRORS 9 //9 errors, and 1 entry for no error + +/** + * @brief Returns the current error status of the tritium controller + */ +tritium_error_code_t MotorController_getTritiumError(void); #endif \ No newline at end of file diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 7d12071fd..7e4822302 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -5,6 +5,40 @@ #include "CANbus.h" #include +//status limit flag masks +#define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor 6 + +uint16_t Motor_FaultBitmap = T_NONE; + + +/** + * @brief Return the static error field from this layer + * + */ +tritium_error_code_t MotorController_getTritiumError(void){ + //TODO: implement for loop to parse this + for(int i = 0; i < NUM_TRITIUM_ERRORS; ++i){ + if(Motor_FaultBitmap & (1< Date: Sat, 12 Nov 2022 23:17:43 +0000 Subject: [PATCH 023/141] Modified Minion_Read_Input to read inputs and outputs and renamed to Minion_Read_Pin --- Drivers/Inc/Minions.h | 2 +- Drivers/Src/Minions.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Drivers/Inc/Minions.h b/Drivers/Inc/Minions.h index bbe06bae5..cfd1ae154 100644 --- a/Drivers/Inc/Minions.h +++ b/Drivers/Inc/Minions.h @@ -49,7 +49,7 @@ void Minion_Init(void); * @return true * @return false *NOTE* If output pin is passed, will exit */ -bool Minion_Read_Input(MinionPin_t pin, Minion_Error_t* err); +bool Minion_Read_Pin(MinionPin_t pin, Minion_Error_t* err); /** * @brief Writes given status to a specified output pin. Locks writing to all output pins diff --git a/Drivers/Src/Minions.c b/Drivers/Src/Minions.c index 3544a5710..2ba82efa8 100644 --- a/Drivers/Src/Minions.c +++ b/Drivers/Src/Minions.c @@ -29,13 +29,12 @@ void Minion_Init(void){ } -bool Minion_Read_Input(MinionPin_t pin, Minion_Error_t* err){ - if((PINS_LOOKARR[pin].direction == OUTPUT)){ //trying to read from an output pin, can't do that. - *err = MINION_ERR_YOU_READ_OUTPUT_PIN; - return false; - } - - return (bool)BSP_GPIO_Read_Pin(PINS_LOOKARR[pin].port, PINS_LOOKARR[pin].pinMask); +bool Minion_Read_Pin(MinionPin_t pin, Minion_Error_t* err){ + if((PINS_LOOKARR[pin].direction == INPUT)){ + return (bool)BSP_GPIO_Read_Pin(PINS_LOOKARR[pin].port, PINS_LOOKARR[pin].pinMask); + }else{ + return (bool)BSP_GPIO_Get_State(PINS_LOOKARR[pin].port, PINS_LOOKARR[pin].pinMask); + } } From 7adf9ad40263562f9d2eb7b6fcfe073ee452d240 Mon Sep 17 00:00:00 2001 From: NathanielDelgado Date: Sat, 12 Nov 2022 23:25:34 +0000 Subject: [PATCH 024/141] Added test for testing the ignition contactor task --- Tests/Test_Ign_Cont.c | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Tests/Test_Ign_Cont.c diff --git a/Tests/Test_Ign_Cont.c b/Tests/Test_Ign_Cont.c new file mode 100644 index 000000000..a8de45965 --- /dev/null +++ b/Tests/Test_Ign_Cont.c @@ -0,0 +1,72 @@ +#include "os.h" +#include "Tasks.h" +#include "Minions.h" +#include +#include "config.h" +#include "common.h" +#include "Contactors.h" + +static OS_TCB Task1TCB; +static CPU_STK Task1Stk[DEFAULT_STACK_SIZE]; + +void Task1(void *arg) +{ + CPU_Init(); + + BSP_UART_Init(UART_2); + Minion_Init(); + Contactors_Init(); + + OS_ERR err; + + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U)OSCfg_TickRate_Hz); + + // Initialize IgnitionContactor + OSTaskCreate( + (OS_TCB*)&IgnCont_TCB, + (CPU_CHAR*)"IgnitionContactor", + (OS_TASK_PTR)Task_Contactor_Ignition, + (void*)NULL, + (OS_PRIO)TASK_IGN_CONT_PRIO, + (CPU_STK*)IgnCont_Stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, + (CPU_STK_SIZE)TASK_IGN_CONT_STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)0, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR*)&err + ); + assertOSError(OS_MAIN_LOC, err); + + while (1){ + printf("Array Contactor: %d, Motor Contactor: %d\n\r", Contactors_Get(ARRAY_CONTACTOR), Contactors_Get(MOTOR_CONTACTOR)); + + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + } +}; + +int main() +{ + OS_ERR err; + OSInit(&err); + + // create tester thread + OSTaskCreate( + (OS_TCB *)&Task1TCB, + (CPU_CHAR *)"Task 1", + (OS_TASK_PTR)Task1, + (void *)NULL, + (OS_PRIO)13, + (CPU_STK *)Task1Stk, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE / 10, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR *)&err); + assertOSError(OS_MAIN_LOC, err); + + OSStart(&err); +} \ No newline at end of file From 478e97d3fdab07e5a5a11aca101fcc89591d236c Mon Sep 17 00:00:00 2001 From: NathanielDelgado Date: Sat, 12 Nov 2022 23:26:01 +0000 Subject: [PATCH 025/141] Updated code due to the Minion Read function rewrite --- Apps/Src/IgnitionContactor.c | 4 ++-- Apps/Src/UpdateVelocity.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Apps/Src/IgnitionContactor.c b/Apps/Src/IgnitionContactor.c index 9563b8715..e92b3c61c 100644 --- a/Apps/Src/IgnitionContactor.c +++ b/Apps/Src/IgnitionContactor.c @@ -29,7 +29,7 @@ void Task_Contactor_Ignition(void* p_arg) { //UpdateSwitches(); // array on/off - if (Minion_Read_Input(IGN_1, &Merr)) { + if (Minion_Read_Pin(IGN_1, &Merr)) { Contactors_Enable(ARRAY_CONTACTOR); } else { Contactors_Disable(ARRAY_CONTACTOR); @@ -37,7 +37,7 @@ void Task_Contactor_Ignition(void* p_arg) { assertOSError(OS_MINIONS_LOC, err); //turn motor on/off - Contactors_Set(MOTOR_CONTACTOR, Minion_Read_Input(IGN_2, &Merr)); + Contactors_Set(MOTOR_CONTACTOR, Minion_Read_Pin(IGN_2, &Merr)); assertOSError(OS_MINIONS_LOC, err); assertOSError(OS_MINIONS_LOC, err); //Lights_Set(M_CNCTR,Switches_Read(IGN_2)); diff --git a/Apps/Src/UpdateVelocity.c b/Apps/Src/UpdateVelocity.c index 3916c3421..5101ed65a 100644 --- a/Apps/Src/UpdateVelocity.c +++ b/Apps/Src/UpdateVelocity.c @@ -56,7 +56,7 @@ void Task_UpdateVelocity(void *p_arg) { uint8_t accelPedalPercent = Pedals_Read(ACCELERATOR); uint8_t brakePedalPercent = Pedals_Read(BRAKE); - State RegenSwitchState = Minion_Read_Input(REGEN_SW, &mErr); + State RegenSwitchState = Minion_Read_Pin(REGEN_SW, &mErr); RegenState = ((RegenSwitchState == ON) && (RegenEnable == ON)); //AND driver regen enable and system regen enable together to decide whether we are in regen brake mode // Set the cruise state accordingly @@ -116,15 +116,15 @@ void Task_UpdateVelocity(void *p_arg) forwardPercent = ((accelPedalPercent - NEUTRAL_PEDALS_PERCENT) * 100) / (100 - NEUTRAL_PEDALS_PERCENT); } - if(Minion_Read_Input(FOR_SW, &mErr)){ + if(Minion_Read_Pin(FOR_SW, &mErr)){ desiredVelocity = (((cruiseState==ON)&&(forwardPercent == 0)) ? cruiseSpeed : MAX_VELOCITY); // if in cruise and not pushing accel pedal, use cruise speed, otherwise use max - } else if (Minion_Read_Input(REV_SW, &mErr)) { + } else if (Minion_Read_Pin(REV_SW, &mErr)) { desiredVelocity = -MAX_VELOCITY; //no cruising in reverse cruiseState = OFF; } - if((cruiseState == ON)&&(Minion_Read_Input(FOR_SW, &mErr))&&(forwardPercent==0)){ //we're in cruise mode and not accelerating so use total current to hit cruise velocity + if((cruiseState == ON)&&(Minion_Read_Pin(FOR_SW, &mErr))&&(forwardPercent==0)){ //we're in cruise mode and not accelerating so use total current to hit cruise velocity desiredMotorCurrent = (float) 0.5; } else { desiredMotorCurrent = convertPedaltoMotorPercent(forwardPercent); @@ -132,7 +132,7 @@ void Task_UpdateVelocity(void *p_arg) } - if ((Contactors_Get(MOTOR_CONTACTOR)) && ((Minion_Read_Input(FOR_SW, &mErr) || Minion_Read_Input(REV_SW, &mErr)))) { + if ((Contactors_Get(MOTOR_CONTACTOR)) && ((Minion_Read_Pin(FOR_SW, &mErr) || Minion_Read_Pin(REV_SW, &mErr)))) { MotorController_Drive(velocity_to_rpm(desiredVelocity), desiredMotorCurrent); } From c0a693b0b26676c56c5c09816628c6c4bff34926 Mon Sep 17 00:00:00 2001 From: NathanielDelgado Date: Sat, 12 Nov 2022 23:28:08 +0000 Subject: [PATCH 026/141] Removed unneed error --- Drivers/Inc/Minions.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Drivers/Inc/Minions.h b/Drivers/Inc/Minions.h index cfd1ae154..a06068efd 100644 --- a/Drivers/Inc/Minions.h +++ b/Drivers/Inc/Minions.h @@ -7,7 +7,6 @@ //errors bc ur bad typedef enum{ MINION_ERR_NONE = 0, - MINION_ERR_YOU_READ_OUTPUT_PIN, MINION_ERR_YOU_WROTE_TO_INPUT_PIN, } Minion_Error_t; From 53a3846a42bac6bb365bc418a8eeded089d5194a Mon Sep 17 00:00:00 2001 From: NathanielDelgado Date: Sat, 3 Dec 2022 15:00:01 +0000 Subject: [PATCH 027/141] Removed unneeded error and shortened error name --- Drivers/Inc/Minions.h | 4 +--- Drivers/Src/Minions.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Drivers/Inc/Minions.h b/Drivers/Inc/Minions.h index a06068efd..1e4d2d673 100644 --- a/Drivers/Inc/Minions.h +++ b/Drivers/Inc/Minions.h @@ -4,11 +4,9 @@ #include "BSP_GPIO.h" -//errors bc ur bad typedef enum{ MINION_ERR_NONE = 0, - MINION_ERR_YOU_WROTE_TO_INPUT_PIN, - + MINION_ERR_WROTE_INPUT, } Minion_Error_t; //used to index into lookup table diff --git a/Drivers/Src/Minions.c b/Drivers/Src/Minions.c index 2ba82efa8..c2221e86e 100644 --- a/Drivers/Src/Minions.c +++ b/Drivers/Src/Minions.c @@ -50,6 +50,6 @@ bool Minion_Write_Output(MinionPin_t pin, bool status, Minion_Error_t* mErr){ assertOSError(OS_MINIONS_LOC, err); return true; } - *mErr = MINION_ERR_YOU_WROTE_TO_INPUT_PIN; + *mErr = MINION_ERR_WROTE_INPUT; return false; } \ No newline at end of file From 37df8bdbe0b4f813cc8cf9b81a3951628aeb835d Mon Sep 17 00:00:00 2001 From: Arnav Surjan Date: Sat, 3 Dec 2022 19:31:44 +0000 Subject: [PATCH 028/141] Fixed tritium error handling. Added velocity read and getter capabilities. In process of adding fault handlling capabilities --- Apps/Src/FaultState.c | 13 +++++++------ Apps/Src/ReadTritium.c | 32 ++++++++++++++++++++++++++++---- Drivers/Inc/CANbus.h | 1 - Drivers/Src/CANLUT.c | 1 - 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 5049d584b..8211938b9 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -28,18 +28,14 @@ void EnterFaultState(void) { } else if(FaultBitmap & FAULT_TRITIUM){ //This gets tripped by the ReadTritium thread tritium_error_code_t TritiumError = MotorController_getTritiumError(); //get error code to segregate based on fault type - if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage - nonrecoverableFaultHandler(); - } - if(TritiumError & T_HARDWARE_OVER_CURRENT_ERR){ //Tritium signaled too much current nonrecoverableFaultHandler(); } - + if(TritiumError & T_SOFTWARE_OVER_CURRENT_ERR){ nonrecoverableFaultHandler(); } - + if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error // Note: separate tripcnt from T_INIT_FAIL static uint8_t hall_fault_cnt = 0; //trip counter @@ -51,6 +47,11 @@ void EnterFaultState(void) { return; } } + + if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage + nonrecoverableFaultHandler(); + } + if(TritiumError & T_INIT_FAIL){ // Note: separate tripcnt from T_HALL_SENSOR_ERR diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 7e4822302..a5a6b88e9 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -10,9 +10,11 @@ uint16_t Motor_FaultBitmap = T_NONE; +static uint32_t Motor_Velocity = 0; +static uint32_t Car_Velocity = 0; /** - * @brief Return the static error field from this layer + * @brief Returns highest priority tritium error code * */ tritium_error_code_t MotorController_getTritiumError(void){ @@ -22,6 +24,7 @@ tritium_error_code_t MotorController_getTritiumError(void){ return ((tritium_error_code_t)(1< Date: Sat, 3 Dec 2022 21:35:48 +0000 Subject: [PATCH 029/141] added if-statement to skip T_NONE errors --- Apps/Src/FaultState.c | 67 ++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 8211938b9..c8d4b846d 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -28,42 +28,45 @@ void EnterFaultState(void) { } else if(FaultBitmap & FAULT_TRITIUM){ //This gets tripped by the ReadTritium thread tritium_error_code_t TritiumError = MotorController_getTritiumError(); //get error code to segregate based on fault type - if(TritiumError & T_HARDWARE_OVER_CURRENT_ERR){ //Tritium signaled too much current - nonrecoverableFaultHandler(); - } - - if(TritiumError & T_SOFTWARE_OVER_CURRENT_ERR){ - nonrecoverableFaultHandler(); - } - - if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error - // Note: separate tripcnt from T_INIT_FAIL - static uint8_t hall_fault_cnt = 0; //trip counter - if(hall_fault_cnt>3){ //try to restart the motor a few times and then fail out + if(TritiumError != T_NONE){ + + if(TritiumError & T_HARDWARE_OVER_CURRENT_ERR){ //Tritium signaled too much current + nonrecoverableFaultHandler(); + } + + if(TritiumError & T_SOFTWARE_OVER_CURRENT_ERR){ nonrecoverableFaultHandler(); - } else { - hall_fault_cnt++; - MotorController_Restart(); //re-initialize motor - return; } - } - - if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage - nonrecoverableFaultHandler(); - } - - if(TritiumError & T_INIT_FAIL){ - // Note: separate tripcnt from T_HALL_SENSOR_ERR - static uint8_t init_fault_cnt = 0; - if(init_fault_cnt>5){ - nonrecoverableFaultHandler(); //we've failed to init the motor five times - } else { - init_fault_cnt++; - MotorController_Restart(); - return; + if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage + nonrecoverableFaultHandler(); } - } + + if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error + // Note: separate tripcnt from T_INIT_FAIL + static uint8_t hall_fault_cnt = 0; //trip counter + if(hall_fault_cnt>3){ //try to restart the motor a few times and then fail out + nonrecoverableFaultHandler(); + } else { + hall_fault_cnt++; + MotorController_Restart(); //re-initialize motor + return; + } + } + + + if(TritiumError & T_INIT_FAIL){ + // Note: separate tripcnt from T_HALL_SENSOR_ERR + static uint8_t init_fault_cnt = 0; + if(init_fault_cnt>5){ + nonrecoverableFaultHandler(); //we've failed to init the motor five times + } else { + init_fault_cnt++; + MotorController_Restart(); + return; + } + } + } return; /** From 001074a3fa7332c43bf9c712ddcb8215f8346582 Mon Sep 17 00:00:00 2001 From: Arnav Surjan Date: Sat, 3 Dec 2022 21:59:53 +0000 Subject: [PATCH 030/141] for gage --- Apps/Src/FaultState.c | 65 +++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index c8d4b846d..6e7dc0cc3 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -28,52 +28,45 @@ void EnterFaultState(void) { } else if(FaultBitmap & FAULT_TRITIUM){ //This gets tripped by the ReadTritium thread tritium_error_code_t TritiumError = MotorController_getTritiumError(); //get error code to segregate based on fault type - if(TritiumError != T_NONE){ - if(TritiumError & T_HARDWARE_OVER_CURRENT_ERR){ //Tritium signaled too much current - nonrecoverableFaultHandler(); - } - - if(TritiumError & T_SOFTWARE_OVER_CURRENT_ERR){ - nonrecoverableFaultHandler(); - } + if(TritiumError & T_HARDWARE_OVER_CURRENT_ERR){ //Tritium signaled too much current + nonrecoverableFaultHandler(); + } + + if(TritiumError & T_SOFTWARE_OVER_CURRENT_ERR){ + nonrecoverableFaultHandler(); + } - if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage + if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage + nonrecoverableFaultHandler(); + } + + if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error + // Note: separate tripcnt from T_INIT_FAIL + static uint8_t hall_fault_cnt = 0; //trip counter + if(hall_fault_cnt>3){ //try to restart the motor a few times and then fail out nonrecoverableFaultHandler(); + } else { + hall_fault_cnt++; + MotorController_Restart(); //re-initialize motor + return; } - - if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error - // Note: separate tripcnt from T_INIT_FAIL - static uint8_t hall_fault_cnt = 0; //trip counter - if(hall_fault_cnt>3){ //try to restart the motor a few times and then fail out - nonrecoverableFaultHandler(); - } else { - hall_fault_cnt++; - MotorController_Restart(); //re-initialize motor - return; - } - } - + } - if(TritiumError & T_INIT_FAIL){ - // Note: separate tripcnt from T_HALL_SENSOR_ERR - static uint8_t init_fault_cnt = 0; - if(init_fault_cnt>5){ - nonrecoverableFaultHandler(); //we've failed to init the motor five times - } else { - init_fault_cnt++; - MotorController_Restart(); - return; - } - } - } + if(TritiumError & T_CONFIG_READ_ERR){ //Config read error + nonrecoverableFaultHandler(); + } + return; /** * FAULTS NOT HANDLED : - * Low Voltage Lockout Error - Not really much we can do if we're not giving the controller enough voltage, + * Watchdog Last Reset Error - Not using any hardware watchdogs. + * + * Under Voltage Lockout Error - Not really much we can do if we're not giving the controller enough voltage, * and if we miss drive messages as a result, it will shut itself off. - * Temp error - Motor will throttle itself, and there's nothing we can do additional to cool it down + * + * Desaturation Fault Error - */ } else if(FaultBitmap & FAULT_READBPS){ //This has been put in with future development in mind, it is not currently tripped by anything. From 594e7ae03e3e07b6ca9342577dbd4b6492ec889a Mon Sep 17 00:00:00 2001 From: Arnav Surjan Date: Sat, 3 Dec 2022 22:14:25 +0000 Subject: [PATCH 031/141] Added fault state handling. --- Apps/Src/FaultState.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 6e7dc0cc3..4cfa96153 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -6,6 +6,10 @@ #include "MotorController.h" #include "Contactors.h" #include "Minions.h" +#include "ReadTritium.h" + +#define RESTART_THRESHOLD 3 + static bool fromThread = false; //whether fault was tripped from thread extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. @@ -44,7 +48,7 @@ void EnterFaultState(void) { if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error // Note: separate tripcnt from T_INIT_FAIL static uint8_t hall_fault_cnt = 0; //trip counter - if(hall_fault_cnt>3){ //try to restart the motor a few times and then fail out + if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out nonrecoverableFaultHandler(); } else { hall_fault_cnt++; @@ -57,6 +61,14 @@ void EnterFaultState(void) { nonrecoverableFaultHandler(); } + if(TritiumError & T_DESAT_FAULT_ERR){ //Desaturation fault error + nonrecoverableFaultHandler(); + } + + if(TritiumError & T_MOTOR_OVER_SPEED_ERR){ //Motor over speed error + nonrecoverableFaultHandler(); + } + return; /** @@ -65,8 +77,7 @@ void EnterFaultState(void) { * * Under Voltage Lockout Error - Not really much we can do if we're not giving the controller enough voltage, * and if we miss drive messages as a result, it will shut itself off. - * - * Desaturation Fault Error - + */ } else if(FaultBitmap & FAULT_READBPS){ //This has been put in with future development in mind, it is not currently tripped by anything. From 7a0bee902a057b24088d177ea646266eeaf1e3f4 Mon Sep 17 00:00:00 2001 From: Arnav Surjan Date: Sun, 4 Dec 2022 00:04:11 +0000 Subject: [PATCH 032/141] Deleted old motor controller file and header file, and mentions of header file. --- Apps/Src/FaultState.c | 5 +- Apps/Src/ReadTritium.c | 19 ++- Apps/Src/Tasks.c | 1 - Apps/Src/UpdateDisplay.c | 1 - Apps/Src/UpdateVelocity.c | 1 - Apps/Src/main.c | 2 - Docs/source/Apps/FaultState.rst | 2 +- Drivers/Inc/MotorController.h | 99 ------------ Drivers/Src/MotorController.c | 247 ----------------------------- Tests/Test_DisplayApps.c | 1 - Tests/Test_DisplayDriver.c | 1 - Tests/Test_IntegratedDriverTest.c | 1 - Tests/Test_MotorCANBoard.c | 1 - Tests/Test_MotorConErrMessages.c | 1 - Tests/Test_MotorController.c | 1 - Tests/Test_ReadCarCAN.c | 1 - Tests/Test_ReadTritium.c | 1 - Tests/Test_ReadandSendCarCAN.c | 1 - Tests/Test_UpdateVelocity.c | 1 - Tests/Test_UpdateVelocityNoSpoof.c | 1 - 20 files changed, 15 insertions(+), 373 deletions(-) delete mode 100644 Drivers/Inc/MotorController.h delete mode 100644 Drivers/Src/MotorController.c diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 4cfa96153..e93d41b8e 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -3,7 +3,6 @@ #include "Contactors.h" #include "os.h" #include "Tasks.h" -#include "MotorController.h" #include "Contactors.h" #include "Minions.h" #include "ReadTritium.h" @@ -52,7 +51,9 @@ void EnterFaultState(void) { nonrecoverableFaultHandler(); } else { hall_fault_cnt++; - MotorController_Restart(); //re-initialize motor + //MotorController_Restart(); //re-initialize motor + //DEVELOP RESTART SEQUENCE + return; } } diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index a5a6b88e9..d0f1a1d03 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -3,6 +3,7 @@ #include "ReadTritium.h" #include "CAN_Queue.h" #include "CANbus.h" +#include "UpdateDisplay.h" #include //status limit flag masks @@ -10,8 +11,8 @@ uint16_t Motor_FaultBitmap = T_NONE; +static uint32_t Motor_RPM = 0; static uint32_t Motor_Velocity = 0; -static uint32_t Car_Velocity = 0; /** * @brief Returns highest priority tritium error code @@ -80,11 +81,13 @@ void Task_ReadTritium(void *p_arg){ } case VELOCITY:{ - //Motor Velocity (in rpm) is in bytes 0-3 - Motor_Velocity = *((uint32_t*)(&dataBuf.data[0])); + //Motor RPM is in bytes 0-3 + Motor_RPM = *((uint32_t*)(&dataBuf.data[0])); //Car Velocity (in m/s) is in bytes 4-7 - Car_Velocity = *((uint32_t*)(&dataBuf.data[4])); + Motor_Velocity = *((uint32_t*)(&dataBuf.data[4])); + uint32_t Car_Velocity = Motor_Velocity; + Car_Velocity = ((Car_Velocity * 100) * 3600); //Converting from m/s to m/h, using fixed point factor of 100 Car_Velocity = ((Car_Velocity / 160934) / 10); //Converting from m/h to mph, dividing by 10 to account for displaying @@ -106,10 +109,10 @@ void Task_ReadTritium(void *p_arg){ } } -uint32_t MotorVelocity_Get(){ - return Motor_Velocity; +uint32_t Motor_RPM_Get(){ //getter function for motor RPM + return Motor_RPM; } -uint32_t CarVelocity_Get(){ - return Car_Velocity; +uint32_t Motor_Velocity_Get(){ //getter function for motor velocity + return Motor_Velocity; } \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index b12f97c3f..64398c712 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -7,7 +7,6 @@ #include "Contactors.h" #include "Display.h" #include "Minions.h" -#include "MotorController.h" #include "Pedals.h" /** diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 7d0f0d156..409b8e34c 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -13,7 +13,6 @@ */ #include "UpdateDisplay.h" #include "Minions.h" -#include "MotorController.h" #include /** diff --git a/Apps/Src/UpdateVelocity.c b/Apps/Src/UpdateVelocity.c index 3916c3421..55df4b54f 100644 --- a/Apps/Src/UpdateVelocity.c +++ b/Apps/Src/UpdateVelocity.c @@ -2,7 +2,6 @@ #include "Pedals.h" #include "Tasks.h" #include "Minions.h" -#include "MotorController.h" #include "Contactors.h" #include diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 22ed1adb3..49d2edc9d 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -8,7 +8,6 @@ #include "Contactors.h" #include "Display.h" #include "Minions.h" -#include "MotorController.h" #include "Pedals.h" #include "CAN_Queue.h" @@ -71,7 +70,6 @@ void Task_Init(void *p_arg){ // Initialize drivers Pedals_Init(); OSTimeDlyHMSM(0,0,5,0,OS_OPT_TIME_HMSM_STRICT,&err); - MotorController_Init(1.0f); // Let motor controller use 100% of bus current OSTimeDlyHMSM(0,0,10,0,OS_OPT_TIME_HMSM_STRICT,&err); BSP_UART_Init(UART_2); CANbus_Init(CARCAN); diff --git a/Docs/source/Apps/FaultState.rst b/Docs/source/Apps/FaultState.rst index db39158ca..9d8e71923 100644 --- a/Docs/source/Apps/FaultState.rst +++ b/Docs/source/Apps/FaultState.rst @@ -7,7 +7,7 @@ The fault state task was selected to be the highest priority task in the system ``FaultBitmap`` =============== -The fault bitmap keeps track of the type of error that was encountered. The types of errors represented include OS errors, motor controller errors, and display errors. Check ``Tasks.h`` for the full definition of the bitmap. Based on the value of this bitmap, the fault state task can select what action to take based on the fault type. Furthermore, tritium errors are supplemented by a another bitmap that contains more specific information about the fault. The motor controller driver maintains this bitmap, and fault state uses it to discriminate between recoverable, non-recoverable, and ignorable errors. Check ``MotorController.h`` for the full definition of this bitmap. +The fault bitmap keeps track of the type of error that was encountered. The types of errors represented include OS errors, motor controller errors, and display errors. Check ``Tasks.h`` for the full definition of the bitmap. Based on the value of this bitmap, the fault state task can select what action to take based on the fault type. Furthermore, tritium errors are supplemented by a another bitmap that contains more specific information about the fault. The motor controller driver maintains this bitmap, and fault state uses it to discriminate between recoverable, non-recoverable, and ignorable errors. Check ``ReadTritium.h`` for the full definition of this bitmap. Non-recoverable Faults diff --git a/Drivers/Inc/MotorController.h b/Drivers/Inc/MotorController.h deleted file mode 100644 index 6e37d454d..000000000 --- a/Drivers/Inc/MotorController.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright (c) 2020 UT Longhorn Racing Solar */ -/** - * NOTE: THIS DRIVER IS ACTIVELY BEING DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED, - * YOU SHOULD MIGRATE TO USING THE MULTI-BUS CAN DRIVER - */ - - -#ifndef __MOTORCONTROLLER_H -#define __MOTORCONTROLLER_H - -#include - -typedef struct -{ - uint32_t id; - union { - uint32_t firstNum; - uint8_t data1[4]; - }; - union { - uint32_t secondNum; - uint8_t data2[4]; - }; -} CANbuff; - -/** - * Motor Error States - * Read messages from motor in ReadTritium and trigger appropriate error messages as needed based on bits - * - */ -typedef enum{ - T_NONE = 0x00, - T_DC_BUS_OVERVOLT_ERR = 0x01, - T_HALL_SENSOR_ERR = 0x02, - T_HARDWARE_OVER_CURRENT_ERR = 0x04, - T_CC_VEL_ERR = 0x08, //unused + deprecated - T_OVER_SPEED_ERR = 0x10, //unused + deprecated - T_TEMP_ERR = 0x20, - T_INIT_FAIL = 0x40, - T_LOW_VOLTAGE_LOCKOUT_ERR = 0x80, - T_SOFTWARE_OVER_CURRENT_ERR = 0x100, -} tritium_error_code_t; - -/** - * @brief Returns the current error status of the tritium controller - * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED - */ -tritium_error_code_t MotorController_getTritiumError(void); - -/** - * @brief Initializes the motor controller - * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED - * @param busCurrentFractionalSetPoint fraction of the bus current to allow the motor to draw - * @return None - */ -void MotorController_Init(float busCurrentFractionalSetPoint); - -/** - * @brief Sends MOTOR DRIVE command on CAN3 - * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED - * @param newVelocity desired motor velocity setpoint in rpm - * @param motorCurrent desired motor current setpoint as a fraction of max current setting - * @return None - */ -void MotorController_Drive(float newVelocity, float motorCurrent); - -/** - * @brief Reads most recent command from CAN3 bus - * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED - * @param message the buffer in which the info for the CAN message will be stored - * @return SUCCESS if a message is read - */ -ErrorStatus MotorController_Read(CANbuff *message); - -/** - * @brief Reads velocity - * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED - * @return Velocity - */ -float MotorController_ReadVelocity(void); - - -/** - * @brief Reads RPM of motor - * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED - * @return RPM - */ -float MotorController_ReadRPM(void); - - -/** - * @brief Restarts the motor controller. THIS FUNCTION IS FOR FAULT STATE USE ONLY. - * @brief THIS FUNCTION IS DEPRECATED. LEGACY SUPPORT IS NOT GUARANTEED - * @param busCurrentFractionalSetPoint - */ -void MotorController_Restart(void); - - -#endif diff --git a/Drivers/Src/MotorController.c b/Drivers/Src/MotorController.c deleted file mode 100644 index d5e85ca48..000000000 --- a/Drivers/Src/MotorController.c +++ /dev/null @@ -1,247 +0,0 @@ -#include "MotorController.h" -#include "os.h" -#include "Tasks.h" - -#include "Display.h" -#include "CANbus.h" - -#include "Contactors.h" - - - -//status msg masks -#define MASK_LOW_VOLTAGE_LOCKOUT_ERR (1<<22) //Low voltage rail lockout happened -#define MASK_HALL_SENSOR_ERR (1<<19) //check for slip or hall sequence position error on 19 bit -#define MASK_DC_BUS_OVERVOLT_ERR (1<<18) //DC Bus overvoltage error -#define MASK_SOFTWARE_OVER_CURRENT_ERR (1<<17) //Software Over Current error; Tritium firmware detected an overcurrent -#define MASK_HARDWARE_OVER_CURRENT_ERR (1<<16) //Hardware Over current error; Tritium hardware detected an overcurrent -#define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor 6 - - -#define BYTES_TO_UINT32(bytes) ((bytes[])) - -static bool restartFinished = true; -static float CurrentVelocity = 0; -static float CurrentRPM = 0; -static float busCurrent = 0.0; -static OS_MUTEX restartFinished_Mutex; - -tritium_error_code_t Motor_FaultBitmap = T_NONE; - -static bool is_initialized = false; - -/** - * @brief Assert Error if Tritium sends error. When Fault Bitmap is set, - * and semaphore is posted, Fault state will run. - * @param motor_err Bitmap which has motor error codes - */ -static void _assertTritiumError(tritium_error_code_t motor_err) -{ - - if(restartFinished){ - OS_ERR err; - if(motor_err != T_NONE){ - FaultBitmap |= FAULT_TRITIUM; - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); - assertOSError(0, err); - } - } -} - -#if DEBUG == 1 -#define assertTritiumError(motor_err) \ - if (motor_err != T_NONE) { \ - printf("Error asserted at %s, line %d: %d\n\r", __FILE__, __LINE__, motor_err); \ - } \ - _assertTritiumError(motor_err); -#else -#define assertTritiumError(motor_err) _assertTritiumError(motor_err); -#endif - - - -static void MotorController_InitCommand(){ //transmits the init command - CANDATA_t initData; - initData.data[4] = busCurrent; //put 32bit busCurrent value in most significant 32 bits - initData.ID = MOTOR_POWER; - initData.idx = 0; - ErrorStatus initCommand = CANbus_Send(initData,CAN_BLOCKING,MOTORCAN); - if (initCommand == ERROR) - { - Motor_FaultBitmap = T_INIT_FAIL; - assertTritiumError(Motor_FaultBitmap); - } -} - -/** - * @brief Initializes the motor controller - * @param busCurrentFractionalSetPoint fraction of the bus current to allow the motor to draw - * @return None - */ -void MotorController_Init(float busCurrentFractionalSetPoint) -{ - if (is_initialized) - return; - is_initialized = true; // Ensure that we only execute the function once - busCurrent = busCurrentFractionalSetPoint; - MotorController_InitCommand(); -} - -/** - * @brief Restarts the motor controller. - * - */ -void MotorController_Restart(void){ - CPU_TS ts; - OS_ERR err; - OSMutexPend(&restartFinished_Mutex, 0, OS_OPT_POST_NONE, &ts, &err); - assertOSError(0, err); - restartFinished = false; - - CANDATA_t restartCommand; - restartCommand.data[0] = 0; - restartCommand.ID = MOTOR_RESET; - restartCommand.idx = 0; - ErrorStatus initCommand = CANbus_Send(restartCommand,CAN_BLOCKING,MOTORCAN); - if (initCommand == ERROR) { - restartFinished = true; - OSMutexPost(&restartFinished_Mutex, OS_OPT_POST_NONE, &err); - assertOSError(0, err); - Motor_FaultBitmap = T_INIT_FAIL; - assertTritiumError(Motor_FaultBitmap); - return; - } - - OSMutexPost(&restartFinished_Mutex, OS_OPT_POST_NONE, &err); - assertOSError(0, err); -} - -/** - * @brief Sends MOTOR DRIVE command on CAN3 - * @param newVelocity desired motor velocity setpoint in m/s - * @param motorCurrent desired motor current setpoint as a percentage of max current setting (0.0-1.0) - * @return None - */ -void MotorController_Drive(float newVelocity, float motorCurrent) -{ - CANDATA_t driveCommand; - *((uint32_t*)&driveCommand.data) = newVelocity; //copy velocity into LS 32 bits - *(((uint32_t*)&driveCommand.data)+1) = motorCurrent; //copy current into MS 32 bits - driveCommand.ID = MOTOR_DRIVE; - driveCommand.idx = 0; - CANbus_Send(driveCommand,CAN_NON_BLOCKING,MOTORCAN); -} - -/** - * @brief - * - * - * @param message the buffer in which the info for the CAN message will be stored - * @return SUCCESS if a message is read - */ -ErrorStatus MotorController_Read(CANbuff *message) -{ - - uint32_t firstSum = 0; - uint32_t secondSum = 0; - CPU_TS ts; - OS_ERR err; - - CANDATA_t motormsg; - ErrorStatus status = CANbus_Read(&motormsg,CAN_NON_BLOCKING,MOTORCAN); - - if (status == SUCCESS) - { - firstSum = *(uint32_t*)&(motormsg.data); //first 32 bits - secondSum = *(((uint32_t*)&(motormsg.data))+1); //second 32 bits - - message->id = motormsg.ID; - message->firstNum = firstSum; - message->secondNum = secondSum; - - switch (motormsg.ID) { - // If we're reading the output from the Motor Status command (0x241) then - // Check the status bits we care about and set flags accordingly - case MOTOR_STATUS: { - - OSMutexPend(&restartFinished_Mutex, 0, OS_OPT_POST_NONE, &ts, &err); - assertOSError(0, err); - if(restartFinished == false){ - MotorController_InitCommand(); - restartFinished = true; - } - OSMutexPost(&restartFinished_Mutex, OS_OPT_POST_NONE, &err); - assertOSError(0, err); - - if(MASK_DC_BUS_OVERVOLT_ERR & firstSum){ - Motor_FaultBitmap |= T_DC_BUS_OVERVOLT_ERR; - } - - if(MASK_HALL_SENSOR_ERR & firstSum){ - Motor_FaultBitmap |= T_HALL_SENSOR_ERR; - } - - if(MASK_HARDWARE_OVER_CURRENT_ERR & firstSum){ - Motor_FaultBitmap |= T_HARDWARE_OVER_CURRENT_ERR; - } - - if(MASK_SOFTWARE_OVER_CURRENT_ERR & firstSum){ - Motor_FaultBitmap |= T_SOFTWARE_OVER_CURRENT_ERR; - } - - if(MASK_LOW_VOLTAGE_LOCKOUT_ERR & firstSum){ - Motor_FaultBitmap |= T_LOW_VOLTAGE_LOCKOUT_ERR; - } - - if(MASK_MOTOR_TEMP_LIMIT & firstSum){ - Motor_FaultBitmap |= T_TEMP_ERR; - } - - - assertTritiumError(Motor_FaultBitmap); - - break; - } - case MOTOR_VELOCITY: { - CurrentVelocity = *(float *) &secondSum; - CurrentRPM = *(float*) &firstSum; - break; - } - default: { - break; - } - - // if(MASK_OVER_SPEED_ERR & firstSum){ - // Motor_FaultBitmap |= T_OVER_SPEED_ERR; - // } - - assertTritiumError(Motor_FaultBitmap); - - break; - } - - return SUCCESS; - } - return ERROR; -} - -/** - * @brief Mutex protected read from Velocity parameter - * @return velocity value obtained from MotorController_Read - */ -float MotorController_ReadVelocity(void) -{ - return CurrentVelocity; -} - -float MotorController_ReadRPM(void){ - return CurrentRPM; -} - -/** - * @brief Return the static error field from this layer - * - */ -tritium_error_code_t MotorController_getTritiumError(void){ - return Motor_FaultBitmap; -} \ No newline at end of file diff --git a/Tests/Test_DisplayApps.c b/Tests/Test_DisplayApps.c index e4c20e42f..41bb932cd 100644 --- a/Tests/Test_DisplayApps.c +++ b/Tests/Test_DisplayApps.c @@ -4,7 +4,6 @@ #include "Tasks.h" #include "Display.h" // #include "bsp.h" -// #include "MotorController.h" // #include "Contactors.h" #include "UpdateDisplay.h" #include "FaultState.h" diff --git a/Tests/Test_DisplayDriver.c b/Tests/Test_DisplayDriver.c index b688102fa..b6d337ca8 100644 --- a/Tests/Test_DisplayDriver.c +++ b/Tests/Test_DisplayDriver.c @@ -15,7 +15,6 @@ #include "Tasks.h" // #include "Display.h" // #include "bsp.h" -// #include "MotorController.h" // #include "Contactors.h" #include "Display.h" diff --git a/Tests/Test_IntegratedDriverTest.c b/Tests/Test_IntegratedDriverTest.c index 4f69c0131..23334cb19 100644 --- a/Tests/Test_IntegratedDriverTest.c +++ b/Tests/Test_IntegratedDriverTest.c @@ -3,7 +3,6 @@ #include "Pedals.h" #include "Display.h" -#include "MotorController.h" #include "CANbus.h" int main() { diff --git a/Tests/Test_MotorCANBoard.c b/Tests/Test_MotorCANBoard.c index 085ddb175..a94744616 100644 --- a/Tests/Test_MotorCANBoard.c +++ b/Tests/Test_MotorCANBoard.c @@ -4,7 +4,6 @@ #include "config.h" #include #include -#include "MotorController.h" #include "CarState.h" #include "UpdateVelocity.h" #include diff --git a/Tests/Test_MotorConErrMessages.c b/Tests/Test_MotorConErrMessages.c index 8a62532de..34c709f74 100644 --- a/Tests/Test_MotorConErrMessages.c +++ b/Tests/Test_MotorConErrMessages.c @@ -9,7 +9,6 @@ #include "common.h" #include "config.h" #include "CarState.h" -#include "MotorController.h" int main(){ diff --git a/Tests/Test_MotorController.c b/Tests/Test_MotorController.c index 9960569f6..83b935678 100644 --- a/Tests/Test_MotorController.c +++ b/Tests/Test_MotorController.c @@ -7,7 +7,6 @@ */ #include "common.h" #include "config.h" -#include "MotorController.h" #include "os.h" #include "Tasks.h" #include "CANbus.h" diff --git a/Tests/Test_ReadCarCAN.c b/Tests/Test_ReadCarCAN.c index ed7e871b6..883b44cda 100644 --- a/Tests/Test_ReadCarCAN.c +++ b/Tests/Test_ReadCarCAN.c @@ -1,7 +1,6 @@ #include "os.h" #include "common.h" #include "Tasks.h" -#include "MotorController.h" #include "CAN_Queue.h" #include "Contactors.h" #include "Minions.h" diff --git a/Tests/Test_ReadTritium.c b/Tests/Test_ReadTritium.c index 8458fe33b..c9df16f26 100644 --- a/Tests/Test_ReadTritium.c +++ b/Tests/Test_ReadTritium.c @@ -3,7 +3,6 @@ #include "os.h" #include "common.h" #include "Tasks.h" -#include "MotorController.h" void Task1(void *); diff --git a/Tests/Test_ReadandSendCarCAN.c b/Tests/Test_ReadandSendCarCAN.c index 6e9f12460..f4c8ef296 100644 --- a/Tests/Test_ReadandSendCarCAN.c +++ b/Tests/Test_ReadandSendCarCAN.c @@ -1,7 +1,6 @@ #include "os.h" #include "common.h" #include "Tasks.h" -#include "MotorController.h" #include "CAN_Queue.h" #include "Contactors.h" #include "Minions.h" diff --git a/Tests/Test_UpdateVelocity.c b/Tests/Test_UpdateVelocity.c index c3f03304e..2c1227205 100644 --- a/Tests/Test_UpdateVelocity.c +++ b/Tests/Test_UpdateVelocity.c @@ -6,7 +6,6 @@ #include "Display.h" #include "Contactors.h" #include "Minions.h" -#include "MotorController.h" #include "Pedals.h" #include "CAN_Queue.h" diff --git a/Tests/Test_UpdateVelocityNoSpoof.c b/Tests/Test_UpdateVelocityNoSpoof.c index ce389c15d..5a52959d2 100644 --- a/Tests/Test_UpdateVelocityNoSpoof.c +++ b/Tests/Test_UpdateVelocityNoSpoof.c @@ -6,7 +6,6 @@ #include "Display.h" #include "Contactors.h" #include "Minions.h" -#include "MotorController.h" #include "Pedals.h" #include "CAN_Queue.h" From ddfe23a13cd049c0b39b8861a44c5b7b99264294 Mon Sep 17 00:00:00 2001 From: Gage Miller Date: Wed, 7 Dec 2022 07:52:23 +0000 Subject: [PATCH 033/141] fixed velocity conversions to multiplying fixed point value by ten instead of dividing by ten so that the value is accurately displayed in fixed point format. Added macros to initialize internally held variables Motor_RPM and Motor_Velocity (they are both initialized to 0) --- Apps/Inc/ReadTritium.h | 2 ++ Apps/Src/ReadTritium.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index 3e2995a49..e8b385c6e 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -6,6 +6,8 @@ #include "os.h" #include "common.h" #include "Tasks.h" +#define MOTOR_STOPPED 0 +#define CAR_STOPPED 0 /** * Motor Error States diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index d0f1a1d03..7d5154fa1 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -11,8 +11,8 @@ uint16_t Motor_FaultBitmap = T_NONE; -static uint32_t Motor_RPM = 0; -static uint32_t Motor_Velocity = 0; +static uint32_t Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read +static uint32_t Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read /** * @brief Returns highest priority tritium error code @@ -89,7 +89,7 @@ void Task_ReadTritium(void *p_arg){ uint32_t Car_Velocity = Motor_Velocity; Car_Velocity = ((Car_Velocity * 100) * 3600); //Converting from m/s to m/h, using fixed point factor of 100 - Car_Velocity = ((Car_Velocity / 160934) / 10); //Converting from m/h to mph, dividing by 10 to account for displaying + Car_Velocity = ((Car_Velocity / 160934) * 10); //Converting from m/h to mph, multiplying by 10 to make value "larger" for displaying UpdateDisplay_SetVelocity(Car_Velocity); From 33923fd8d9307ff17a5a6085d48fcf175bc02777 Mon Sep 17 00:00:00 2001 From: Gage Miller Date: Wed, 7 Dec 2022 09:31:26 +0000 Subject: [PATCH 034/141] Implelemted motor controller restart function in ReadTritium, use this function in FaultState.c. Defined a new error code (T_INIT_FAIL) to shut off the motor controller in the event a restart/initialization fails. --- Apps/Inc/ReadTritium.h | 7 +++++++ Apps/Src/FaultState.c | 8 +++++--- Apps/Src/ReadTritium.c | 42 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index e8b385c6e..678122602 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -24,6 +24,7 @@ typedef enum{ T_UNDER_VOLTAGE_LOCKOUT_ERR = (1<<6), T_DESAT_FAULT_ERR = (1<<7), T_MOTOR_OVER_SPEED_ERR = (1<<8), + T_INIT_FAIL = (1<<9), //motor controller fails to restart or initialize T_NONE = 0x00, } tritium_error_code_t; #define NUM_TRITIUM_ERRORS 9 //9 errors, and 1 entry for no error @@ -33,4 +34,10 @@ typedef enum{ */ tritium_error_code_t MotorController_getTritiumError(void); +uint32_t Motor_RPM_Get(); +uint32_t Motor_Velocity_Get(); +void MotorController_Restart(); + + + #endif \ No newline at end of file diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index e93d41b8e..c9e291b50 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -51,9 +51,7 @@ void EnterFaultState(void) { nonrecoverableFaultHandler(); } else { hall_fault_cnt++; - //MotorController_Restart(); //re-initialize motor - //DEVELOP RESTART SEQUENCE - + MotorController_Restart(); //re-initialize motor return; } } @@ -70,6 +68,10 @@ void EnterFaultState(void) { nonrecoverableFaultHandler(); } + if(TritiumError & T_INIT_FAIL){ //motorcontroller fails to restart or initialize + nonrecoverableFaultHandler(); + } + return; /** diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 7d5154fa1..e3ce3602b 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -8,11 +8,16 @@ //status limit flag masks #define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor 6 +#define MAX_CAN_LEN 8 -uint16_t Motor_FaultBitmap = T_NONE; +uint16_t Motor_FaultBitmap = T_NONE; static uint32_t Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read static uint32_t Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read +static OS_MUTEX restartFinished_Mutex; //mutex used for restart function +static bool restartFinished = true; //initially sets restarted value to true since motor controller is technically restarted upon initialization +static OS_SEM MotorController_MailSem; +static OS_SEM MotorController_ReceiveSem; /** * @brief Returns highest priority tritium error code @@ -109,6 +114,41 @@ void Task_ReadTritium(void *p_arg){ } } +void MotorController_Restart(void){ + CPU_TS ts; + OS_ERR err; + + OSMutexPend(&restartFinished_Mutex, 0, OS_OPT_POST_NONE, &ts, &err); + assertOSError(0, err); + uint8_t data[8] = {0}; + restartFinished = false; + + OSSemPend(&MotorController_MailSem, + 0, + OS_OPT_PEND_BLOCKING, + &ts, + &err); + assertOSError(0, err); + + ErrorStatus initCommand = BSP_CAN_Write(CAN_3, MOTOR_RESET, data, MAX_CAN_LEN); //send motor controller reset command + if (initCommand == ERROR) { //error found, post mutex and shut off motor controller in FaultState.c + restartFinished = true; + MotorController_Release(); + + OSMutexPost(&restartFinished_Mutex, OS_OPT_POST_NONE, &err); + assertOSError(0, err); + + Motor_FaultBitmap = T_INIT_FAIL; + assertTritiumError(Motor_FaultBitmap); + return; + } + + OSMutexPost(&restartFinished_Mutex, OS_OPT_POST_NONE, &err); + assertOSError(0, err); + +} + + uint32_t Motor_RPM_Get(){ //getter function for motor RPM return Motor_RPM; } From 71832187ec5bb8df0d66bb0546c30897495e012f Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 10 Dec 2022 22:59:41 +0000 Subject: [PATCH 035/141] Made changes from design review, including using chargingDisable in the callback, removing extra header files, and taking out the line that set the OS error location bitmap. --- Apps/Src/FaultState.c | 5 +++++ Apps/Src/ReadCarCAN.c | 36 ++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index e7f7f78b9..24524c5c4 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -6,6 +6,8 @@ #include "MotorController.h" #include "Contactors.h" #include "Minions.h" +#include "UpdateDisplay.h" + static bool fromThread = false; //whether fault was tripped from thread extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. @@ -26,6 +28,9 @@ static void readBPS_ContactorHandler(void){ //kill contactors Contactors_Set(ARRAY_CONTACTOR, OFF, true); Contactors_Set(ARRAY_PRECHARGE, OFF, true); + + // turn off the array contactor light + UpdateDisplay_SetArray(false); } void EnterFaultState(void) { diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 576a4d7dc..6f1cb08ff 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -3,8 +3,6 @@ #include "ReadCarCAN.h" #include "UpdateDisplay.h" #include "Contactors.h" -#include "Minions.h" -#include "CAN_Queue.h" #include "FaultState.h" #include "os_cfg_app.h" @@ -65,17 +63,20 @@ static void updateSaturation(int8_t chargeMessage){ chargeMsgSaturation = newSaturation; } -// helper function to call if charging should be disabled +// helper function to disable charging +// Turns off contactors by setting fault bitmap and signaling fault state static inline void chargingDisable(void) { + OS_ERR err; + // mark regen as disabled regenEnable = false; - //kill contactors - Contactors_Set(ARRAY_CONTACTOR, OFF, true); - Contactors_Set(ARRAY_PRECHARGE, OFF, true); - - // turn off the array contactor light - UpdateDisplay_SetArray(false); + // Set fault bitmap + FaultBitmap |= FAULT_READBPS; + + // Signal fault state to kill contactors at its earliest convenience + OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); + assertOSError(OS_READ_CAN_LOC,err); } @@ -121,8 +122,11 @@ static inline void chargingEnable(void) { static void arrayRestart(void *p_tmr, void *p_arg){ if(regenEnable){ // If regen has been disabled during precharge, we don't want to turn on the main contactor immediately after - Contactors_Set(ARRAY_CONTACTOR, ON, false); - UpdateDisplay_SetArray(true); + + if (Contactors_Set(ARRAY_CONTACTOR, ON, false) != ERROR){ // Only update display if we successfully turn on the array + UpdateDisplay_SetArray(true); + } + } // done restarting the array restartingArray = false; @@ -135,19 +139,11 @@ static void arrayRestart(void *p_tmr, void *p_arg){ * @param p_arg pointer to the argument passed by timer */ void canWatchTimerCallback (void *p_tmr, void *p_arg){ - OS_ERR err; // mark regen as disabled regenEnable = false; - - // Set fault bitmaps - FaultBitmap |= FAULT_READBPS; - OSErrLocBitmap |= OS_READ_CAN_LOC; - - // Signal fault state to kill contactors at its earliest convenience - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); - assertOSError(OS_READ_CAN_LOC,err); + chargingDisable(); } From ee75c9edc94607f35e15dbbf680ad65b5ec02b43 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 24 Dec 2022 20:32:57 -0600 Subject: [PATCH 036/141] master version of CAN driver --- Drivers/Src/CANbus.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 8f7fc1eed..9cd6afa8f 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -227,6 +227,27 @@ ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t OS_OPT_POST_NONE, &err); assertOSError(OS_CANDRIVER_LOC,err); + + // Make sure this is a message we can receive + switch (MsgContainer->ID) { + case CHARGE_ENABLE: + case STATE_OF_CHARGE: + case SUPPLEMENTAL_VOLTAGE: + case MOTOR_DRIVE: + case MOTOR_POWER: + case MOTOR_RESET: + case MOTOR_STATUS: + case MC_BUS: + case VELOCITY: + case MC_PHASE_CURRENT: + case VOLTAGE_VEC: + case CURRENT_VEC: + case BACKEMF: + case TEMPERATURE: + case ODOMETER_AMPHOURS: + case ARRAY_CONTACTOR_STATE_CHANGE: break; // Continue if value is valid + default: return ERROR; // Error if we get an unexpected value + } //search LUT for id to populate idx and trim data CANLUT_T entry = CANLUT[MsgContainer->ID]; From cbd1b56f1db962c28f35ed92cbf3e7abde6a1779 Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 24 Dec 2022 21:45:17 -0600 Subject: [PATCH 037/141] fixed restart, changed CAN driver slightly. Commented out old updateVelocity. --- Apps/Src/ReadCarCAN.c | 2 +- Apps/Src/ReadTritium.c | 40 +------- Apps/Src/SendCarCAN.c | 2 +- Apps/Src/Telemetry.c | 2 +- Apps/Src/UpdateVelocity.c | 197 +++++++++++++++++++------------------- Drivers/Inc/CANbus.h | 12 ++- Drivers/Src/CANbus.c | 4 +- 7 files changed, 117 insertions(+), 142 deletions(-) diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 576a4d7dc..618a35dfa 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -198,7 +198,7 @@ void Task_ReadCarCAN(void *p_arg) { //Get any message that BPS Sent us - ErrorStatus status = CANbus_Read(&dataBuf,CAN_BLOCKING,CARCAN); + ErrorStatus status = CANbus_Read(&dataBuf,true,CARCAN); if(status != SUCCESS) { continue; } diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index e3ce3602b..d01615cc2 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -14,10 +14,6 @@ uint16_t Motor_FaultBitmap = T_NONE; static uint32_t Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read static uint32_t Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read -static OS_MUTEX restartFinished_Mutex; //mutex used for restart function -static bool restartFinished = true; //initially sets restarted value to true since motor controller is technically restarted upon initialization -static OS_SEM MotorController_MailSem; -static OS_SEM MotorController_ReceiveSem; /** * @brief Returns highest priority tritium error code @@ -74,7 +70,7 @@ void Task_ReadTritium(void *p_arg){ CANDATA_t dataBuf = {0}; while (1){ - ErrorStatus status = CANbus_Read(&dataBuf, CAN_BLOCKING, MOTORCAN); + ErrorStatus status = CANbus_Read(&dataBuf, true, MOTORCAN); if (status == SUCCESS){ switch(dataBuf.ID){ @@ -115,37 +111,9 @@ void Task_ReadTritium(void *p_arg){ } void MotorController_Restart(void){ - CPU_TS ts; - OS_ERR err; - - OSMutexPend(&restartFinished_Mutex, 0, OS_OPT_POST_NONE, &ts, &err); - assertOSError(0, err); - uint8_t data[8] = {0}; - restartFinished = false; - - OSSemPend(&MotorController_MailSem, - 0, - OS_OPT_PEND_BLOCKING, - &ts, - &err); - assertOSError(0, err); - - ErrorStatus initCommand = BSP_CAN_Write(CAN_3, MOTOR_RESET, data, MAX_CAN_LEN); //send motor controller reset command - if (initCommand == ERROR) { //error found, post mutex and shut off motor controller in FaultState.c - restartFinished = true; - MotorController_Release(); - - OSMutexPost(&restartFinished_Mutex, OS_OPT_POST_NONE, &err); - assertOSError(0, err); - - Motor_FaultBitmap = T_INIT_FAIL; - assertTritiumError(Motor_FaultBitmap); - return; - } - - OSMutexPost(&restartFinished_Mutex, OS_OPT_POST_NONE, &err); - assertOSError(0, err); - + CANDATA_t resetmsg = {0}; + resetmsg.ID = MOTOR_RESET; + CANbus_Send(resetmsg, true, MOTORCAN); } diff --git a/Apps/Src/SendCarCAN.c b/Apps/Src/SendCarCAN.c index a08ce2313..46fb4fd86 100644 --- a/Apps/Src/SendCarCAN.c +++ b/Apps/Src/SendCarCAN.c @@ -24,7 +24,7 @@ void Task_SendCarCAN(void *p_arg){ while (1) { // Send motor msg CAN_Queue_Pend(&motorMsg); - CANbus_Send(motorMsg, CAN_BLOCKING, CARCAN); + CANbus_Send(motorMsg, true, CARCAN); // Delay of few milliseconds (100) OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); diff --git a/Apps/Src/Telemetry.c b/Apps/Src/Telemetry.c index dffd39334..5fd1e2142 100644 --- a/Apps/Src/Telemetry.c +++ b/Apps/Src/Telemetry.c @@ -56,7 +56,7 @@ void Task_Telemetry(void *p_arg){ } // Send car msg - CANbus_Send(carMsg, CAN_BLOCKING, CARCAN); + CANbus_Send(carMsg, true, CARCAN); // Delay of few milliseconds (500) OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); diff --git a/Apps/Src/UpdateVelocity.c b/Apps/Src/UpdateVelocity.c index bab954537..543e6c520 100644 --- a/Apps/Src/UpdateVelocity.c +++ b/Apps/Src/UpdateVelocity.c @@ -4,6 +4,7 @@ #include "Minions.h" #include "Contactors.h" #include "ReadCarCAN.h" +#include "ReadTritium.h" #include // REGEN_CURRENT AS A PERCENTAGE (DECIMAL NUMBER) OF MAX CURRENT @@ -19,122 +20,122 @@ #define NEUTRAL_PEDALS_PERCENT 25 #define REGEN_RANGE (NEUTRAL_PEDALS_PERCENT - UNTOUCH_PEDALS_PERCENT_ACCEL) -static float cruiseSpeed = 0; //cruising speed -static float cruiseRPM = 0; -static State cruiseState = OFF; //whether cruise is enabled +// static float cruiseSpeed = 0; //cruising speed +// static float cruiseRPM = 0; +// static State cruiseState = OFF; //whether cruise is enabled -extern const float pedalToPercent[]; +// extern const float pedalToPercent[]; -bool UpdateVel_ToggleCruise = false; +// bool UpdateVel_ToggleCruise = false; -static float convertPedaltoMotorPercent(uint8_t pedalPercentage) -{ - if(pedalPercentage > 100){ - return 1.0f; - } - return pedalToPercent[pedalPercentage]; -} +// static float convertPedaltoMotorPercent(uint8_t pedalPercentage) +// { +// if(pedalPercentage > 100){ +// return 1.0f; +// } +// return pedalToPercent[pedalPercentage]; +// } -// Convert a float velocity in meters per second to a desired RPM -static float velocity_to_rpm(float velocity) { - float velocity_mpm = velocity * 60.0f; // velocity in meters per minute - const float circumference = WHEEL_DIAMETER * M_PI; - float wheel_rpm = velocity_mpm / circumference; - return wheel_rpm; -} +// // Convert a float velocity in meters per second to a desired RPM +// static float velocity_to_rpm(float velocity) { +// float velocity_mpm = velocity * 60.0f; // velocity in meters per minute +// const float circumference = WHEEL_DIAMETER * M_PI; +// float wheel_rpm = velocity_mpm / circumference; +// return wheel_rpm; +// } void Task_UpdateVelocity(void *p_arg) { OS_ERR err; - Minion_Error_t mErr; + // Minion_Error_t mErr; - float desiredVelocity = 0; //reset desired velocity to 0 - float desiredMotorCurrent = 0; //reset desired current to 0 - State RegenState = OFF; //reset regen state to 0. This state var denotes whether or not we are in the regen brake mode + // float desiredVelocity = 0; //reset desired velocity to 0 + // float desiredMotorCurrent = 0; //reset desired current to 0 + // State RegenState = OFF; //reset regen state to 0. This state var denotes whether or not we are in the regen brake mode while (1) { - uint8_t accelPedalPercent = Pedals_Read(ACCELERATOR); - uint8_t brakePedalPercent = Pedals_Read(BRAKE); - State RegenSwitchState = Minion_Read_Input(REGEN_SW, &mErr); - RegenState = ((RegenSwitchState == ON) && (RegenEnable_Get() == ON)); //AND driver regen enable and system regen enable together to decide whether we are in regen brake mode - - // Set the cruise state accordingly - if (UpdateVel_ToggleCruise) { - cruiseState = !cruiseState; - } - - if(cruiseSpeed THRESHOLD_VEL) //we're above the threshold value - && accelPedalPercent < NEUTRAL_PEDALS_PERCENT //we're in the one-pedal drive range - && (cruiseState == OFF) //we're not in cruise mode - ){ + // //record speed when we're not already cruising + // if(!cruiseState){ + // cruiseSpeed = Motor_Velocity_Get(); + // cruiseRPM = Motor_RPM_Get(); + // } + // // Set brake lights + // if(brakePedalPercent <= UNTOUCH_PEDALS_PERCENT_BRAKE){ //it is less than since we switched to a button instead of the adc + // Minion_Write_Output(BRAKELIGHT, true, &mErr); + // } + // else{ + // Minion_Write_Output(BRAKELIGHT, false, &mErr); + // } + + // cruiseState = OFF; //DISABLING CRUISE CONTROL FOR POWERED RUN, DEBUG FURTHER BEFORE REMOVING + + // // Deadband comparison + // if(brakePedalPercent <= UNTOUCH_PEDALS_PERCENT_BRAKE){ //mech brake is pushed down NOTE: it is less than since we switched to a button + // desiredVelocity = 0; //velocity setpoint becomes 0 + // cruiseState = OFF; //turn off cruise + // desiredMotorCurrent = (RegenState == ON) ? REGEN_CURRENT : 0; //either regen brake or 0 current brake + // } + // else if( //One-pedal regen drive case. + // (RegenState == ON) //we're in regen mode + // && (Motor_Velocity_Get() > THRESHOLD_VEL) //we're above the threshold value + // && accelPedalPercent < NEUTRAL_PEDALS_PERCENT //we're in the one-pedal drive range + // && (cruiseState == OFF) //we're not in cruise mode + // ){ - desiredVelocity = 0; - // set regen current based on how much the accel pedal is pressed down - if (accelPedalPercent > UNTOUCH_PEDALS_PERCENT_ACCEL) { - desiredMotorCurrent = REGEN_CURRENT * (REGEN_RANGE - (accelPedalPercent - UNTOUCH_PEDALS_PERCENT_ACCEL)) / REGEN_RANGE; - } else { - desiredMotorCurrent = REGEN_CURRENT; - } - } - else { - //determine the percentage of pedal range pushed - uint8_t forwardPercent = 0; - if ((RegenSwitchState == OFF)&&(accelPedalPercent > UNTOUCH_PEDALS_PERCENT_ACCEL)){ //the accelerator is being pushed under non-regen pedal mapping. NOTE: RegenSwitchState used because driver should have exclusive control over which pedal mapping is used. - forwardPercent = ((accelPedalPercent - UNTOUCH_PEDALS_PERCENT_ACCEL) * 100) / (100 - UNTOUCH_PEDALS_PERCENT_ACCEL); - } else if (accelPedalPercent > NEUTRAL_PEDALS_PERCENT) { // the accelerator is being pushed under regen enabled pedal mapping - forwardPercent = ((accelPedalPercent - NEUTRAL_PEDALS_PERCENT) * 100) / (100 - NEUTRAL_PEDALS_PERCENT); - } - - if(Minion_Read_Input(FOR_SW, &mErr)){ - desiredVelocity = (((cruiseState==ON)&&(forwardPercent == 0)) ? cruiseSpeed : MAX_VELOCITY); // if in cruise and not pushing accel pedal, use cruise speed, otherwise use max - } else if (Minion_Read_Input(REV_SW, &mErr)) { - desiredVelocity = -MAX_VELOCITY; //no cruising in reverse - cruiseState = OFF; - } + // desiredVelocity = 0; + // // set regen current based on how much the accel pedal is pressed down + // if (accelPedalPercent > UNTOUCH_PEDALS_PERCENT_ACCEL) { + // desiredMotorCurrent = REGEN_CURRENT * (REGEN_RANGE - (accelPedalPercent - UNTOUCH_PEDALS_PERCENT_ACCEL)) / REGEN_RANGE; + // } else { + // desiredMotorCurrent = REGEN_CURRENT; + // } + // } + // else { + // //determine the percentage of pedal range pushed + // uint8_t forwardPercent = 0; + // if ((RegenSwitchState == OFF)&&(accelPedalPercent > UNTOUCH_PEDALS_PERCENT_ACCEL)){ //the accelerator is being pushed under non-regen pedal mapping. NOTE: RegenSwitchState used because driver should have exclusive control over which pedal mapping is used. + // forwardPercent = ((accelPedalPercent - UNTOUCH_PEDALS_PERCENT_ACCEL) * 100) / (100 - UNTOUCH_PEDALS_PERCENT_ACCEL); + // } else if (accelPedalPercent > NEUTRAL_PEDALS_PERCENT) { // the accelerator is being pushed under regen enabled pedal mapping + // forwardPercent = ((accelPedalPercent - NEUTRAL_PEDALS_PERCENT) * 100) / (100 - NEUTRAL_PEDALS_PERCENT); + // } + + // if(Minion_Read_Input(FOR_SW, &mErr)){ + // desiredVelocity = (((cruiseState==ON)&&(forwardPercent == 0)) ? cruiseSpeed : MAX_VELOCITY); // if in cruise and not pushing accel pedal, use cruise speed, otherwise use max + // } else if (Minion_Read_Input(REV_SW, &mErr)) { + // desiredVelocity = -MAX_VELOCITY; //no cruising in reverse + // cruiseState = OFF; + // } - if((cruiseState == ON)&&(Minion_Read_Input(FOR_SW, &mErr))&&(forwardPercent==0)){ //we're in cruise mode and not accelerating so use total current to hit cruise velocity - desiredMotorCurrent = (float) 0.5; - } else { - desiredMotorCurrent = convertPedaltoMotorPercent(forwardPercent); - } + // if((cruiseState == ON)&&(Minion_Read_Input(FOR_SW, &mErr))&&(forwardPercent==0)){ //we're in cruise mode and not accelerating so use total current to hit cruise velocity + // desiredMotorCurrent = (float) 0.5; + // } else { + // desiredMotorCurrent = convertPedaltoMotorPercent(forwardPercent); + // } - } + // } - if ((Contactors_Get(MOTOR_CONTACTOR)) && ((Minion_Read_Input(FOR_SW, &mErr) || Minion_Read_Input(REV_SW, &mErr)))) { - MotorController_Drive(velocity_to_rpm(desiredVelocity), desiredMotorCurrent); - } + // if ((Contactors_Get(MOTOR_CONTACTOR)) && ((Minion_Read_Input(FOR_SW, &mErr) || Minion_Read_Input(REV_SW, &mErr)))) { + // MotorController_Drive(velocity_to_rpm(desiredVelocity), desiredMotorCurrent); + // } // Delay of few milliseconds (100) OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h index b64baaf60..cf5b815c7 100644 --- a/Drivers/Inc/CANbus.h +++ b/Drivers/Inc/CANbus.h @@ -70,8 +70,14 @@ typedef struct { /** * Standard identifier for whether or not a CAN transaction is blocking or not + * (DEPRECATED) */ -typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; +// typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; + +//Compatibility macros for deprecated enum +#define CAN_BLOCKING true +#define CAN_NON_BLOCKING false + /** * @brief Initializes the CAN system for a given bus @@ -87,7 +93,7 @@ ErrorStatus CANbus_Init(CAN_t bus); * @param bus The bus to transmit on. This should be either CARCAN or MOTORCAN. * @return ERROR if data wasn't sent, otherwise it was sent. */ -ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus); +ErrorStatus CANbus_Send(CANDATA_t CanData,bool blocking, CAN_t bus); /** * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers. @@ -96,6 +102,6 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus); * @param bus The bus to use. This should either be CARCAN or MOTORCAN. * @returns ERROR if read failed, SUCCESS otherwise */ -ErrorStatus CANbus_Read(CANDATA_t* data, CAN_blocking_t blocking, CAN_t bus); +ErrorStatus CANbus_Read(CANDATA_t* data, bool blocking, CAN_t bus); #endif diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c index 9cd6afa8f..7c278135c 100755 --- a/Drivers/Src/CANbus.c +++ b/Drivers/Src/CANbus.c @@ -86,7 +86,7 @@ ErrorStatus CANbus_Init(CAN_t bus) * @param blocking: Whether or not this should be a blocking call * @return ERROR if data wasn't sent, SUCCESS if it was sent. */ -ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) +ErrorStatus CANbus_Send(CANDATA_t CanData,bool blocking, CAN_t bus) { CPU_TS timestamp; OS_ERR err; @@ -175,7 +175,7 @@ ErrorStatus CANbus_Send(CANDATA_t CanData,CAN_blocking_t blocking, CAN_t bus) * @returns ERROR if read failed, SUCCESS otherwise */ -ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, CAN_blocking_t blocking, CAN_t bus) +ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, bool blocking, CAN_t bus) { CPU_TS timestamp; OS_ERR err; From cd8aff51d773b71f5210f336193b3ee3c1a990df Mon Sep 17 00:00:00 2001 From: diyarajon Date: Sat, 14 Jan 2023 22:12:10 +0000 Subject: [PATCH 038/141] erged updatevelocity_rewrite --- .vscode/c_cpp_properties.json | 4 +- Apps/Inc/ReadCarCAN.h | 2 +- Apps/Inc/ReadTritium.h | 2 - Apps/Inc/SendTritium.h | 32 ++ Apps/Inc/Tasks.h | 10 +- Apps/Inc/UpdateDisplay.h | 19 + Apps/Inc/UpdateVelocity.h | 12 - Apps/Src/FaultState.c | 4 +- Apps/Src/ReadCarCAN.c | 20 +- Apps/Src/SendTritium.c | 621 +++++++++++++++++++++++++++++ Apps/Src/Tasks.c | 4 +- Apps/Src/UpdateVelocity.c | 147 ------- Apps/Src/main.c | 14 +- Drivers/Inc/Display.h | 19 - Tests/Test_SendTritium.c | 587 +++++++++++++++++++++++++++ Tests/Test_UpdateVelocity.c | 101 ----- Tests/Test_UpdateVelocityNoSpoof.c | 186 --------- 17 files changed, 1289 insertions(+), 495 deletions(-) create mode 100644 Apps/Inc/SendTritium.h delete mode 100644 Apps/Inc/UpdateVelocity.h create mode 100644 Apps/Src/SendTritium.c delete mode 100644 Apps/Src/UpdateVelocity.c create mode 100644 Tests/Test_SendTritium.c delete mode 100644 Tests/Test_UpdateVelocity.c delete mode 100644 Tests/Test_UpdateVelocityNoSpoof.c diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index ad00b700f..4b6ca044e 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -7,6 +7,9 @@ "${workspaceFolder}/Apps/Inc", "${workspaceFolder}/Apps/Src", + "${workspaceFolder}/Drivers/Inc", + "${workspaceFolder}/Drivers/Src", + "${workspaceFolder}/Config/Inc", "${workspaceFolder}/BSP/STM32F413/Src", @@ -14,7 +17,6 @@ "${workspaceFolder}/BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Inc", "${workspaceFolder}/BSP/Template/Src", - "${workspaceFolder}/RTOS/uCOS-III-STM32F4/uC-CPU", "${workspaceFolder}/RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU", "${workspaceFolder}/RTOS/uCOS-III-STM32F4/uC-LIB", diff --git a/Apps/Inc/ReadCarCAN.h b/Apps/Inc/ReadCarCAN.h index ba27b9c7d..2cdc4c48c 100644 --- a/Apps/Inc/ReadCarCAN.h +++ b/Apps/Inc/ReadCarCAN.h @@ -15,6 +15,6 @@ * @brief Returns whether regen braking is enabled or not * @return Whether regen braking is enabled or not */ -bool RegenEnable_Get(); +bool ChargeEnable_Get(); #endif \ No newline at end of file diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index 678122602..7d4791934 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -38,6 +38,4 @@ uint32_t Motor_RPM_Get(); uint32_t Motor_Velocity_Get(); void MotorController_Restart(); - - #endif \ No newline at end of file diff --git a/Apps/Inc/SendTritium.h b/Apps/Inc/SendTritium.h new file mode 100644 index 000000000..f0d3d48b3 --- /dev/null +++ b/Apps/Inc/SendTritium.h @@ -0,0 +1,32 @@ +#ifndef __SENDTRITIUM_H +#define __SENDTRITIUM_H + +#define MOTOR_MSG_PERIOD 100 +#define FSM_PERIOD 20 +#define DEBOUNCE_PERIOD 2 // in units of FSM_PERIOD +#define MOTOR_MSG_COUNTER_THRESHOLD (MOTOR_MSG_PERIOD)/(FSM_PERIOD) + +typedef enum{ + FORWARD_GEAR, + NEUTRAL_GEAR, + REVERSE_GEAR +} Gear_t; + +#ifdef __TEST_SENDTRITIUM +// Inputs +extern bool cruiseEnable; +extern bool cruiseSet; +extern bool onePedalEnable; +extern bool regenEnable; + +extern uint8_t brakePedalPercent; +extern uint8_t accelPedalPercent; + +extern Gear_t gear; + +extern uint8_t state; +extern float velocityObserved; +extern float cruiseVelSetpoint; +#endif + +#endif diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 27ae81ad3..61d6474f4 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -21,7 +21,7 @@ #define TASK_FAULT_STATE_PRIO 1 #define TASK_INIT_PRIO 2 #define TASK_READ_TRITIUM_PRIO 3 -#define TASK_UPDATE_VELOCITY_PRIO 4 +#define TASK_SEND_TRITIUM_PRIO 4 #define TASK_READ_CAR_CAN_PRIO 5 #define TASK_UPDATE_DISPLAY_PRIO 6 #define TASK_SEND_CAR_CAN_PRIO 8 @@ -37,7 +37,7 @@ #define TASK_FAULT_STATE_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_INIT_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_UPDATE_VELOCITY_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_SEND_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_READ_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_UPDATE_DISPLAY_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_READ_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE @@ -54,7 +54,7 @@ void Task_FaultState(void* p_arg); void Task_Init(void* p_arg); -void Task_UpdateVelocity(void* p_arg); +void Task_SendTritium(void* p_arg); void Task_ReadCarCAN(void* p_arg); @@ -75,7 +75,7 @@ void Task_Contactor_Ignition(void* p_arg); */ extern OS_TCB FaultState_TCB; extern OS_TCB Init_TCB; -extern OS_TCB UpdateVelocity_TCB; +extern OS_TCB SendTritium_TCB; extern OS_TCB ReadCarCAN_TCB; extern OS_TCB UpdateDisplay_TCB; extern OS_TCB ReadTritium_TCB; @@ -90,7 +90,7 @@ extern OS_TCB IgnCont_TCB; */ extern CPU_STK FaultState_Stk[TASK_FAULT_STATE_STACK_SIZE]; extern CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; -extern CPU_STK UpdateVelocity_Stk[TASK_UPDATE_VELOCITY_STACK_SIZE]; +extern CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; extern CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; extern CPU_STK UpdateDisplay_Stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; extern CPU_STK ReadTritium_Stk[TASK_READ_TRITIUM_STACK_SIZE]; diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index f0359bc97..c45c496b6 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -33,6 +33,25 @@ typedef enum{ UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value } UpdateDisplayError_t; +/** + * For display elements with three states + */ +typedef enum{ + STATE_0 =0, + STATE_1 =1, + STATE_2 =2 +} TriState_t; + +// For cruise control and regen +#define DISP_DISABLED STATE_0 +#define DISP_ENABLED STATE_1 // Able to be used +#define DISP_ACTIVE STATE_2 // Actively being used right now + +// For gear changes +#define DISP_NEUTRAL STATE_0 +#define DISP_FORWARD STATE_1 +#define DISP_REVERSE STATE_2 + /** * @brief Initializes UpdateDisplay application * @returns UpdateDisplayError_t diff --git a/Apps/Inc/UpdateVelocity.h b/Apps/Inc/UpdateVelocity.h deleted file mode 100644 index 5042f515c..000000000 --- a/Apps/Inc/UpdateVelocity.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __UPDATE_VELOCITY_H -#define __UPDATE_VELOCITY_H - -#include "os.h" -#include "common.h" -#include "Tasks.h" -#include "Pedals.h" - -// MAX_VELOCITY IN M/S -#define MAX_VELOCITY 50.0f - -#endif \ No newline at end of file diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 9ac1d773e..2814fb65b 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -5,8 +5,8 @@ #include "Tasks.h" #include "Contactors.h" #include "Minions.h" -#include "ReadTritium.h" #include "UpdateDisplay.h" +#include "ReadTritium.h" #define RESTART_THRESHOLD 3 @@ -31,7 +31,7 @@ static void readBPS_ContactorHandler(void){ Contactors_Set(ARRAY_CONTACTOR, OFF, true); Contactors_Set(ARRAY_PRECHARGE, OFF, true); - // turn off the array contactor light + // turn off the array contactor display light UpdateDisplay_SetArray(false); } diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index af40cdf72..ae23f12b9 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -26,7 +26,7 @@ static bool restartingArray = false; // NOTE: This should not be written to anywhere other than ReadCarCAN. If the need arises, a mutex to protect it must be added. // Indicates whether or not regenerative braking / charging is enabled. -static bool regenEnable = false; +static bool chargeEnable = false; // Saturation buffer variables static int8_t chargeMsgBuffer[SAT_BUF_LENGTH]; @@ -38,10 +38,10 @@ static uint8_t oldestMsgIdx = 0; static void arrayRestart(void *p_tmr, void *p_arg); -// Getter function for regenEnable -bool RegenEnable_Get() +// Getter function for chargeEnable +bool ChargeEnable_Get() { - return regenEnable; + return chargeEnable; } @@ -69,7 +69,7 @@ static inline void chargingDisable(void) { OS_ERR err; // mark regen as disabled - regenEnable = false; + chargeEnable = false; // Set fault bitmap FaultBitmap |= FAULT_READBPS; @@ -86,7 +86,7 @@ static inline void chargingEnable(void) { CPU_TS ts; // mark regen as enabled - regenEnable = true; + chargeEnable = true; // check if we need to run the precharge sequence to turn on the array bool shouldRestartArray = false; @@ -121,9 +121,9 @@ static inline void chargingEnable(void) { */ static void arrayRestart(void *p_tmr, void *p_arg){ - if(regenEnable){ // If regen has been disabled during precharge, we don't want to turn on the main contactor immediately after + if(chargeEnable){ // If regen has been disabled during precharge, we don't want to turn on the main contactor immediately after - if (Contactors_Set(ARRAY_CONTACTOR, ON, false) != ERROR){ // Only update display if we successfully turn on the array + if(Contactors_Set(ARRAY_CONTACTOR, ON, false) != ERROR){ // Only update display if we successfully turn on the array UpdateDisplay_SetArray(true); } @@ -141,7 +141,7 @@ static void arrayRestart(void *p_tmr, void *p_arg){ void canWatchTimerCallback (void *p_tmr, void *p_arg){ // mark regen as disabled - regenEnable = false; + chargeEnable= false; chargingDisable(); } @@ -207,7 +207,7 @@ void Task_ReadCarCAN(void *p_arg) assertOSError(OS_READ_CAN_LOC, err); - if(dataBuf.data[0] == 0){ // If the buffer doesn't contain 1 for enable, turn off RegenEnable and turn array off + if(dataBuf.data[0] == 0){ // If the buffer doesn't contain 1 for enable, turn off chargeEnable and turn array off chargingDisable(); updateSaturation(-1); // Update saturation and buffer diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c new file mode 100644 index 000000000..db7ce446b --- /dev/null +++ b/Apps/Src/SendTritium.c @@ -0,0 +1,621 @@ +/** + * @copyright Copyright (c) 2022 UT Longhorn Racing Solar + * + * @file SendTritium.c + * @brief Function implementations for the SendTritium application. + * + * This contains functions relevant to updating the velocity and current setpoitns + * of the Tritium motor controller. The implementation includes a normal current + * controlled mode, a one-pedal driving mode (with regenerative braking), and cruise control. + * The logic is determined through a finite state machine implementation. + * + * If the macro __TEST_SENDTRITIUM is defined prior to including SendTritium.h, relevant + * variables will be exposed as externs for unit testing. + * + * @author Nathaniel Delgado (NathanielDelgado) + * @author Diya Rajon (diyarajon) + * @author Ishan Deshpande (IshDeshpa, ishdeshpa@utexas.edu) + */ + +#include "Pedals.h" +#include "ReadCarCAN.h" +#include "Minions.h" +#include "SendTritium.h" +#include "ReadTritium.h" +#include "CANbus.h" +#include "UpdateDisplay.h" + +// Macros +#define MAX_VELOCITY 20000.0f // rpm (unobtainable value) +#define MIN_CRUISE_VELOCITY 20.0f // m/s +#define MAX_GEARSWITCH_VELOCITY 8.0f // m/s + +#define BRAKE_PEDAL_THRESHOLD 5 // percent +#define ACCEL_PEDAL_THRESHOLD 10 // percent + +#define ONEPEDAL_BRAKE_THRESHOLD 25 // percent +#define ONEPEDAL_NEUTRAL_THRESHOLD 35 // percent + +#define GEAR_FAULT_THRESHOLD 3 // number of times gear fault can occur before it is considered a fault + +#ifdef __TEST_SENDTRITIUM +#define STATIC(def) static def +#else +#define STATIC(def) def +#endif + +// Inputs +STATIC(bool) cruiseEnable = false; +STATIC(bool) cruiseSet = false; +STATIC(bool) onePedalEnable = false; +STATIC(bool) regenEnable = false; + +STATIC(uint8_t) brakePedalPercent = 0; +STATIC(uint8_t) accelPedalPercent = 0; + +STATIC(Gear_t) gear = NEUTRAL_GEAR; + +// Outputs +float currentSetpoint = 0; +float velocitySetpoint = 0; +float cruiseVelSetpoint = 0; + +// Current observed velocity +STATIC(float) velocityObserved = 0; + +// Counter for sending setpoints to motor +static uint8_t motorMsgCounter = 0; + +#ifndef __TEST_SENDTRITIUM +// Debouncing counters +static uint8_t onePedalCounter = 0; +static uint8_t cruiseEnableCounter = 0; +static uint8_t cruiseSetCounter = 0; + +// Button states +static bool onePedalButton = false; +static bool onePedalPrevious = false; + +static bool cruiseEnableButton = false; +static bool cruiseEnablePrevious = false; + +#endif + +// Handler & Decider Declarations +static void ForwardDriveHandler(void); +static void ForwardDriveDecider(void); +static void NeutralDriveHandler(void); +static void NeutralDriveDecider(void); +static void ReverseDriveHandler(void); +static void ReverseDriveDecider(void); +static void RecordVelocityHandler(void); +static void RecordVelocityDecider(void); +static void PoweredCruiseHandler(void); +static void PoweredCruiseDecider(void); +static void CoastingCruiseHandler(void); +static void CoastingCruiseDecider(void); +static void BrakeHandler(void); +static void BrakeDecider(void); +static void OnePedalDriveHandler(void); +static void OnePedalDriveDecider(void); +static void AccelerateCruiseHandler(void); +static void AccelerateCruiseDecider(void); + +// State Names +typedef enum{ + FORWARD_DRIVE, + NEUTRAL_DRIVE, + REVERSE_DRIVE, + RECORD_VELOCITY, + POWERED_CRUISE, + COASTING_CRUISE, + BRAKE_STATE, + ONEPEDAL, + ACCELERATE_CRUISE +} TritiumStateName_t; + +// State Struct for FSM +typedef struct TritiumState{ + TritiumStateName_t name; + void (*stateHandler)(void); + void (*stateDecider)(void); +} TritiumState_t; + +// FSM +static const TritiumState_t FSM[9] = { + {FORWARD_DRIVE, &ForwardDriveHandler, &ForwardDriveDecider}, + {NEUTRAL_DRIVE, &NeutralDriveHandler, &NeutralDriveDecider}, + {REVERSE_DRIVE, &ReverseDriveHandler, &ReverseDriveDecider}, + {RECORD_VELOCITY, &RecordVelocityHandler, &RecordVelocityDecider}, + {POWERED_CRUISE, &PoweredCruiseHandler, &PoweredCruiseDecider}, + {COASTING_CRUISE, &CoastingCruiseHandler, &CoastingCruiseDecider}, + {BRAKE_STATE, &BrakeHandler, &BrakeDecider}, + {ONEPEDAL, &OnePedalDriveHandler, &OnePedalDriveDecider}, + {ACCELERATE_CRUISE, &AccelerateCruiseHandler, &AccelerateCruiseDecider} +}; + +static TritiumState_t prevState; // Previous state +static TritiumState_t state; // Current state + +/** + * @brief Dumps info to UART during testing +*/ +#ifdef __TEST_SENDTRITIUM +static void dumpInfo(){ + printf("-------------------\n\r"); + printf("State: %d\n\r", state); + printf("cruiseEnable: %d\n\r", cruiseEnable); + printf("cruiseSet: %d\n\r", cruiseSet); + printf("onePedalEnable: %d\n\r", onePedalEnable); + printf("brakePedalPercent: %d\n\r", brakePedalPercent); + printf("accelPedalPercent: %d\n\r", accelPedalPercent); + printf("reverseSwitch: %d\n\r", reverseSwitch); + printf("forwardSwitch: %d\n\r", forwardSwitch); + printf("currentSetpoint: %f\n\r", currentSetpoint); + printf("velocitySetpoint: %f\n\r", velocitySetpoint); + printf("velocityObserved: %f\n\r", velocityObserved); + printf("-------------------\n\r"); +} +#endif + +#ifndef __TEST_SENDTRITIUM +/** + * @brief Reads inputs from the system +*/ +static void readInputs(){ + Minion_Error_t err; + + // Update pedals + brakePedalPercent = Pedals_Read(BRAKE); + accelPedalPercent = Pedals_Read(ACCELERATOR); + + // Update regen enable + regenEnable = ChargeEnable_Get(); + + // Update buttons + if(Minion_Read_Pin(REGEN_SW, &err) && onePedalCounter < DEBOUNCE_PERIOD){onePedalCounter++;} + else if(onePedalCounter > 0){onePedalCounter--;} + + if(Minion_Read_Pin(CRUZ_EN, &err) && cruiseEnableCounter < DEBOUNCE_PERIOD){cruiseEnableCounter++;} + else if(cruiseEnableCounter > 0){cruiseEnableCounter--;} + + if(Minion_Read_Pin(CRUZ_ST, &err) && cruiseSetCounter < DEBOUNCE_PERIOD){cruiseSetCounter++;} + else if(cruiseSetCounter > 0){cruiseSetCounter--;} + + // Update gears + bool forwardSwitch = Minion_Read_Pin(FOR_SW, &err); + bool reverseSwitch = Minion_Read_Pin(REV_SW, &err); + bool forwardGear = (forwardSwitch && !reverseSwitch); + bool reverseGear = (!forwardSwitch && reverseSwitch); + bool neutralGear = (!forwardSwitch && !reverseSwitch); + + uint8_t gearFault = (uint8_t) forwardGear + (uint8_t) reverseGear + (uint8_t) neutralGear; + static uint8_t gearFaultCnt = 0; + + if(gearFault != 1){ + // Fault behavior + if(gearFaultCnt > GEAR_FAULT_THRESHOLD) state = FSM[NEUTRAL_DRIVE]; + else gearFaultCnt++; + } + else{ + gearFaultCnt = 0; + } + + if(neutralGear) gear = NEUTRAL_GEAR; + else if(forwardGear) gear = FORWARD_GEAR; + else if(reverseGear) gear = REVERSE_GEAR; + else gear = NEUTRAL_GEAR; + + // Debouncing + if(onePedalCounter == DEBOUNCE_PERIOD){onePedalButton = true;} + else if(onePedalCounter == 0){onePedalButton = false;} + + if(cruiseEnableCounter == DEBOUNCE_PERIOD){cruiseEnableButton = true;} + else if(cruiseEnableCounter == 0){cruiseEnableButton = false;} + + if(cruiseSetCounter == DEBOUNCE_PERIOD){cruiseSet = true;} + else if(cruiseSetCounter == 0){cruiseSet = false;} + + // Toggle + if(onePedalButton != onePedalPrevious && onePedalPrevious){onePedalEnable = !onePedalEnable;} + if(!regenEnable) onePedalEnable = false; + onePedalPrevious = onePedalButton; + + if(cruiseEnableButton != cruiseEnablePrevious && cruiseEnablePrevious){cruiseEnable = !cruiseEnable;} + cruiseEnablePrevious = cruiseEnableButton; + + // Get observed velocity + velocityObserved = Motor_Velocity_Get(); +} +#endif + +// Helper Functions + +/** + * @brief Converts integer percentage to float percentage + * @param percent integer percentage from 0-100 + * @returns float percentage from 0.0-1.0 +*/ +extern const float pedalToPercent[]; +static float percentToFloat(uint8_t percent){ + if(percent > 100){ + return 1.0f; + } + return pedalToPercent[percent]; +} + +/** + * @brief Linearly map range of integers to another range of integers. + * in_min to in_max is mapped to out_min to out_max. + * @param input input integer value + * @param in_min minimum value of input range + * @param in_max maximum value of input range + * @param out_min minimum value of output range + * @param out_max maximum value of output range + * @returns integer value from out_min to out_max +*/ +static uint8_t map(uint8_t input, uint8_t in_min, uint8_t in_max, uint8_t out_min, uint8_t out_max){ + if(in_max >= in_min) in_max = in_min; + if(input <= in_min) return out_min; + else if(input >= in_max) return out_max; + else return ((out_max - in_max) * (input - in_min))/(out_min - in_min) + out_min; +} + + +// State Handlers & Deciders + +/** + * @brief Forward Drive State Handler. Accelerator is mapped directly + * to current setpoint at positive velocity. +*/ +static void ForwardDriveHandler(){ + if(prevState.name != state.name){ + UpdateDisplay_SetCruiseState(DISP_DISABLED); + UpdateDisplay_SetRegenState(DISP_DISABLED); + UpdateDisplay_SetGear(DISP_FORWARD); + } + velocitySetpoint = MAX_VELOCITY; + currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, 100, 0, 100)); +} + +/** + * @brief Forward Drive State Decider. Determines transitions out of + * forward drive state (brake, record velocity, one pedal, neutral drive). +*/ +static void ForwardDriveDecider(){ + if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ + state = FSM[BRAKE]; + }else if(cruiseSet && cruiseEnable && velocityObserved >= MIN_CRUISE_VELOCITY){ + state = FSM[RECORD_VELOCITY]; + }else if(onePedalEnable){ + state = FSM[ONEPEDAL]; + }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ + state = FSM[NEUTRAL_DRIVE]; + } +} + +/** + * @brief Neutral Drive State Handler. No current is sent to the motor. +*/ +static void NeutralDriveHandler(){ + if(prevState.name != state.name){ + UpdateDisplay_SetCruiseState(DISP_DISABLED); + UpdateDisplay_SetRegenState(DISP_DISABLED); + UpdateDisplay_SetGear(DISP_NEUTRAL); + } + velocitySetpoint = MAX_VELOCITY; + currentSetpoint = 0.0f; + + cruiseEnable = false; + onePedalEnable = false; +} + +/** + * @brief Neutral Drive State Decider. Determines transitions out of + * neutral drive state (brake, forward drive, reverse drive). +*/ +static void NeutralDriveDecider(){ + if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ + state = FSM[BRAKE]; + }else if(gear == FORWARD_GEAR && velocityObserved >= -MAX_GEARSWITCH_VELOCITY){ + state = FSM[FORWARD_DRIVE]; + }else if(gear == REVERSE_GEAR && velocityObserved <= MAX_GEARSWITCH_VELOCITY){ + state = FSM[REVERSE_DRIVE]; + } +} + +/** + * @brief Reverse Drive State Handler. Accelerator is mapped directly to + * current setpoint (at negative velocity). +*/ +static void ReverseDriveHandler(){ + if(prevState.name != state.name){ + UpdateDisplay_SetCruiseState(DISP_DISABLED); + UpdateDisplay_SetRegenState(DISP_DISABLED); + UpdateDisplay_SetGear(DISP_REVERSE); + } + velocitySetpoint = -MAX_VELOCITY; + currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, 100, 0, 100)); + cruiseEnable = false; + onePedalEnable = false; +} + +/** + * @brief Reverse Drive State Decider. Determines transitions out of + * reverse drive state (brake, neutral drive). +*/ +static void ReverseDriveDecider(){ + if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ + state = FSM[BRAKE]; + } + else if(gear == NEUTRAL_GEAR || gear == FORWARD_GEAR){ + state = FSM[NEUTRAL_DRIVE]; + } +} + +/** + * @brief Record Velocity State. While pressing the cruise set button, + * the car will record the observed velocity into velocitySetpoint. +*/ +static void RecordVelocityHandler(){ + if(prevState.name != state.name){ + UpdateDisplay_SetCruiseState(DISP_ACTIVE); + UpdateDisplay_SetRegenState(DISP_DISABLED); + UpdateDisplay_SetGear(DISP_FORWARD); + } + // put car in neutral while recording velocity (while button is held) + velocitySetpoint = MAX_VELOCITY; + currentSetpoint = 0; + cruiseVelSetpoint = velocityObserved; +} + +/** + * @brief Record Velocity State Decider. Determines transitions out of record velocity + * state (brake, neutral drive, one pedal, forward drive, powered cruise). +*/ +static void RecordVelocityDecider(){ + if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ + state = FSM[BRAKE_STATE]; + }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ + state = FSM[NEUTRAL_DRIVE]; + }else if(onePedalEnable){ + cruiseEnable = false; + state = FSM[ONEPEDAL]; + }else if(!cruiseEnable){ + state = FSM[FORWARD_DRIVE]; + }else if(cruiseEnable && !cruiseSet){ + state = FSM[POWERED_CRUISE]; + } +} + +/** + * @brief Powered Cruise State. Continue to travel at the recorded velocity as long as + * Observed Velocity <= Velocity Setpoint +*/ +static void PoweredCruiseHandler(){ + velocitySetpoint = cruiseVelSetpoint; + currentSetpoint = 1.0f; +} + +/** + * @brief Powered Cruise State Decider. Determines transitions out of powered + * cruise state (brake, neutral drive, one pedal, forward drive, record velocity, + * accelerate cruise, coasting cruise). +*/ +static void PoweredCruiseDecider(){ + if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ + state = FSM[BRAKE_STATE]; + }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ + state = FSM[NEUTRAL_DRIVE]; + }else if(onePedalEnable){ + cruiseEnable = false; + state = FSM[ONEPEDAL]; + }else if(!cruiseEnable){ + state = FSM[FORWARD_DRIVE]; + }else if(cruiseSet && velocityObserved >= MIN_CRUISE_VELOCITY){ + state = FSM[RECORD_VELOCITY]; + }else if(accelPedalPercent >= ACCEL_PEDAL_THRESHOLD){ + state = FSM[ACCELERATE_CRUISE]; + }else if(velocityObserved > cruiseVelSetpoint){ + state = FSM[COASTING_CRUISE]; + } +} + +/** + * @brief Coasting Cruise State. We do not want to utilize motor braking + * in cruise control mode due to safety issues. Coast the motor (go into neutral) + * if we want to slow down. +*/ +static void CoastingCruiseHandler(){ + velocitySetpoint = cruiseVelSetpoint; + currentSetpoint = 0; +} + +/** + * @brief Coasting Cruise State Decider. Determines transitions out of coasting + * cruise state (brake, neutral drive, one pedal, forward drive, record velocity, + * accelerate cruise, powered cruise). +*/ +static void CoastingCruiseDecider(){ + if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ + state = FSM[BRAKE_STATE]; + }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ + state = FSM[NEUTRAL_DRIVE]; + }else if(onePedalEnable){ + cruiseEnable = false; + state = FSM[ONEPEDAL]; + }else if(!cruiseEnable){ + state = FSM[FORWARD_DRIVE]; + }else if(cruiseSet && velocityObserved >= MIN_CRUISE_VELOCITY){ + state = FSM[RECORD_VELOCITY]; + }else if(accelPedalPercent >= ACCEL_PEDAL_THRESHOLD){ + state = FSM[ACCELERATE_CRUISE]; + }else if(velocityObserved <= cruiseVelSetpoint){ + state = FSM[POWERED_CRUISE]; + } +} + +/** + * @brief Accelerate Cruise State. In the event that the driver needs to accelerate in cruise + * mode, we will accelerate to the pedal percentage. Upon release of the accelerator + * pedal, we will return to cruise mode at the previously recorded velocity. +*/ +static void AccelerateCruiseHandler(){ + velocitySetpoint = MAX_VELOCITY; + currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, 100, 0, 100)); +} + +/** + * @brief Accelerate Cruise State Decider. Determines transitions out of accelerate + * cruise state (brake, neutral drive, one pedal, forward drive, record velocity, + * coasting cruise). +*/ +static void AccelerateCruiseDecider(){ + if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ + state = FSM[BRAKE_STATE]; + }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ + state = FSM[NEUTRAL_DRIVE]; + }else if(onePedalEnable){ + cruiseEnable = false; + state = FSM[ONEPEDAL]; + }else if(!cruiseEnable){ + state = FSM[FORWARD_DRIVE]; + }else if(cruiseSet && velocityObserved >= MIN_CRUISE_VELOCITY){ + state = FSM[RECORD_VELOCITY]; + }else if(accelPedalPercent < ACCEL_PEDAL_THRESHOLD){ + state = FSM[COASTING_CRUISE]; + } +} + +/** + * @brief One Pedal Drive State. When in one pedal drive, if the accelerator percentage is lower + * than ONEPEDAL_BRAKE_THRESHOLD, the car will utilize motor braking to slow down. If accelerator + * percentage is in the neutral zone, the car will coast. If accelerator percentage is above + * the NEUTRAL_THRESHOLD, the car will accelerate as normal. +*/ +static void OnePedalDriveHandler(){ + if(prevState.name != state.name){ + UpdateDisplay_SetCruiseState(DISP_DISABLED); + UpdateDisplay_SetGear(DISP_FORWARD); + } + Minion_Error_t minion_err; + if(accelPedalPercent <= ONEPEDAL_BRAKE_THRESHOLD){ + // Regen brake: Map 0 -> brake to 100 -> 0 + velocitySetpoint = 0; + currentSetpoint = percentToFloat(map(accelPedalPercent, 0, ONEPEDAL_BRAKE_THRESHOLD, 100, 0)); + Minion_Write_Output(BRAKELIGHT, true, &minion_err); + UpdateDisplay_SetRegenState(DISP_ACTIVE); + }else if(ONEPEDAL_BRAKE_THRESHOLD < accelPedalPercent && accelPedalPercent <= ONEPEDAL_NEUTRAL_THRESHOLD){ + // Neutral: coast + velocitySetpoint = MAX_VELOCITY; + currentSetpoint = 0; + Minion_Write_Output(BRAKELIGHT, false, &minion_err); + UpdateDisplay_SetRegenState(DISP_ENABLED); + }else if(ONEPEDAL_NEUTRAL_THRESHOLD < accelPedalPercent){ + // Accelerate: Map neutral -> 100 to 0 -> 100 + velocitySetpoint = MAX_VELOCITY; + currentSetpoint = percentToFloat(map(accelPedalPercent, ONEPEDAL_NEUTRAL_THRESHOLD, 100, 0, 100)); + Minion_Write_Output(BRAKELIGHT, false, &minion_err); + UpdateDisplay_SetRegenState(DISP_ENABLED); + } +} + +/** + * @brief One Pedal Drive State Decider. Determines transitions out of one pedal + * drive state (brake, record velocity, neutral drive). +*/ +static void OnePedalDriveDecider(){ + Minion_Error_t minion_err; + if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ + state = FSM[BRAKE]; + }else if(cruiseSet && cruiseEnable && velocityObserved >= MIN_CRUISE_VELOCITY){ + state = FSM[RECORD_VELOCITY]; + Minion_Write_Output(BRAKELIGHT, false, &minion_err); + }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ + state = FSM[NEUTRAL_DRIVE]; + Minion_Write_Output(BRAKELIGHT, false, &minion_err); + } +} + +/** + * @brief Brake State. When brake pedal is pressed, physical brakes will be active. + * Put motor in neutral to prevent motor braking while physical brakes are engaged. + * Additionally, disable all cruise control and one pedal functionality. +*/ +static void BrakeHandler(){ + if(prevState.name != state.name){ + UpdateDisplay_SetCruiseState(DISP_DISABLED); + UpdateDisplay_SetRegenState(DISP_DISABLED); + UpdateDisplay_SetGear(DISP_FORWARD); + } + Minion_Error_t minion_err; + velocitySetpoint = MAX_VELOCITY; + currentSetpoint = 0; + cruiseEnable = false; + onePedalEnable = false; + Minion_Write_Output(BRAKELIGHT, true, &minion_err); +} + +/** + * @brief Brake State Decider. Determines transitions out of brake state (forward drive, + * neutral drive). +*/ +static void BrakeDecider(){ + Minion_Error_t minion_err; + if(brakePedalPercent < BRAKE_PEDAL_THRESHOLD){ + if(gear == FORWARD_GEAR) state = FSM[FORWARD_DRIVE]; + else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR) state = FSM[NEUTRAL_DRIVE]; + Minion_Write_Output(BRAKELIGHT, false, &minion_err); + } +} + +// Task (main loop) + +/** + * @brief Follows the FSM to update the velocity of the car +*/ +void Task_SendTritium(void *p_arg){ + OS_ERR err; + + // Initialize current state to FORWARD_DRIVE + state = FSM[NEUTRAL_DRIVE]; + prevState = FSM[NEUTRAL_DRIVE]; + + CANbus_Init(MOTORCAN); + CANDATA_t driveCmd = { + .ID=MOTOR_DRIVE, + .idx=0, + .data={0.0f, 0.0f}, + }; + + while(1){ + prevState = state; + + state.stateHandler(); // do what the current state does + #ifndef __TEST_SENDTRITIUM + readInputs(); // read inputs from the system + UpdateDisplay_SetAccel(accelPedalPercent); + #endif + state.stateDecider(); // decide what the next state is + + // Drive + #ifdef __TEST_SENDTRITIUM + dumpInfo(); + #else + if(MOTOR_MSG_COUNTER_THRESHOLD == motorMsgCounter){ + driveCmd.data[0] = currentSetpoint; + driveCmd.data[1] = velocitySetpoint; + CANbus_Send(driveCmd, CAN_NON_BLOCKING, MOTORCAN); + motorMsgCounter = 0; + }else{ + motorMsgCounter++; + } + #endif + + // Delay of MOTOR_MSG_PERIOD ms + OSTimeDlyHMSM(0, 0, 0, MOTOR_MSG_PERIOD, OS_OPT_TIME_HMSM_STRICT, &err); + if (err != OS_ERR_NONE){ + assertOSError(OS_UPDATE_VEL_LOC, err); + } + } +} diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index b6cc8a646..46a2e435d 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -14,7 +14,7 @@ */ OS_TCB FaultState_TCB; OS_TCB Init_TCB; -OS_TCB UpdateVelocity_TCB; +OS_TCB SendTritium_TCB; OS_TCB ReadCarCAN_TCB; OS_TCB UpdateDisplay_TCB; OS_TCB ReadTritium_TCB; @@ -28,7 +28,7 @@ OS_TCB IgnCont_TCB; */ CPU_STK FaultState_Stk[TASK_FAULT_STATE_STACK_SIZE]; CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; -CPU_STK UpdateVelocity_Stk[TASK_UPDATE_VELOCITY_STACK_SIZE]; +CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; CPU_STK UpdateDisplay_Stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; CPU_STK ReadTritium_Stk[TASK_READ_TRITIUM_STACK_SIZE]; diff --git a/Apps/Src/UpdateVelocity.c b/Apps/Src/UpdateVelocity.c deleted file mode 100644 index 543e6c520..000000000 --- a/Apps/Src/UpdateVelocity.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "UpdateVelocity.h" -#include "Pedals.h" -#include "Tasks.h" -#include "Minions.h" -#include "Contactors.h" -#include "ReadCarCAN.h" -#include "ReadTritium.h" -#include - -// REGEN_CURRENT AS A PERCENTAGE (DECIMAL NUMBER) OF MAX CURRENT -#define REGEN_CURRENT 0.5f -// THRESHOLD VELOCITY IN M/S -#define THRESHOLD_VEL 1.0f -// UNTOUCH PEDAL PERCENTS AS A PERCENTAGE OF MAX PEDAL POSITION -#define UNTOUCH_PEDALS_PERCENT_ACCEL 0 //tuning constant for the accelerator pedal -#define UNTOUCH_PEDALS_PERCENT_BRAKE UNTOUCH_PEDALS_PERCENT //tuning constant for the brake pedal -#define UNTOUCH_PEDALS_PERCENT 5 //generic tuning constant for both pedals (assuming we want to use the same one for both) - -// percent of pedal to count as neutral (to add support for one-pedal drive) -#define NEUTRAL_PEDALS_PERCENT 25 -#define REGEN_RANGE (NEUTRAL_PEDALS_PERCENT - UNTOUCH_PEDALS_PERCENT_ACCEL) - -// static float cruiseSpeed = 0; //cruising speed -// static float cruiseRPM = 0; -// static State cruiseState = OFF; //whether cruise is enabled - -// extern const float pedalToPercent[]; - -// bool UpdateVel_ToggleCruise = false; - -// static float convertPedaltoMotorPercent(uint8_t pedalPercentage) -// { -// if(pedalPercentage > 100){ -// return 1.0f; -// } -// return pedalToPercent[pedalPercentage]; -// } - -// // Convert a float velocity in meters per second to a desired RPM -// static float velocity_to_rpm(float velocity) { -// float velocity_mpm = velocity * 60.0f; // velocity in meters per minute -// const float circumference = WHEEL_DIAMETER * M_PI; -// float wheel_rpm = velocity_mpm / circumference; -// return wheel_rpm; -// } - -void Task_UpdateVelocity(void *p_arg) -{ - OS_ERR err; - // Minion_Error_t mErr; - - // float desiredVelocity = 0; //reset desired velocity to 0 - // float desiredMotorCurrent = 0; //reset desired current to 0 - // State RegenState = OFF; //reset regen state to 0. This state var denotes whether or not we are in the regen brake mode - - while (1) - { - // uint8_t accelPedalPercent = Pedals_Read(ACCELERATOR); - // uint8_t brakePedalPercent = Pedals_Read(BRAKE); - // State RegenSwitchState = Minion_Read_Input(REGEN_SW, &mErr); - // RegenState = ((RegenSwitchState == ON) && (RegenEnable_Get() == ON)); //AND driver regen enable and system regen enable together to decide whether we are in regen brake mode - - // // Set the cruise state accordingly - // if (UpdateVel_ToggleCruise) { - // cruiseState = !cruiseState; - // } - - // if(cruiseSpeed THRESHOLD_VEL) //we're above the threshold value - // && accelPedalPercent < NEUTRAL_PEDALS_PERCENT //we're in the one-pedal drive range - // && (cruiseState == OFF) //we're not in cruise mode - // ){ - - // desiredVelocity = 0; - // // set regen current based on how much the accel pedal is pressed down - // if (accelPedalPercent > UNTOUCH_PEDALS_PERCENT_ACCEL) { - // desiredMotorCurrent = REGEN_CURRENT * (REGEN_RANGE - (accelPedalPercent - UNTOUCH_PEDALS_PERCENT_ACCEL)) / REGEN_RANGE; - // } else { - // desiredMotorCurrent = REGEN_CURRENT; - // } - // } - // else { - // //determine the percentage of pedal range pushed - // uint8_t forwardPercent = 0; - // if ((RegenSwitchState == OFF)&&(accelPedalPercent > UNTOUCH_PEDALS_PERCENT_ACCEL)){ //the accelerator is being pushed under non-regen pedal mapping. NOTE: RegenSwitchState used because driver should have exclusive control over which pedal mapping is used. - // forwardPercent = ((accelPedalPercent - UNTOUCH_PEDALS_PERCENT_ACCEL) * 100) / (100 - UNTOUCH_PEDALS_PERCENT_ACCEL); - // } else if (accelPedalPercent > NEUTRAL_PEDALS_PERCENT) { // the accelerator is being pushed under regen enabled pedal mapping - // forwardPercent = ((accelPedalPercent - NEUTRAL_PEDALS_PERCENT) * 100) / (100 - NEUTRAL_PEDALS_PERCENT); - // } - - // if(Minion_Read_Input(FOR_SW, &mErr)){ - // desiredVelocity = (((cruiseState==ON)&&(forwardPercent == 0)) ? cruiseSpeed : MAX_VELOCITY); // if in cruise and not pushing accel pedal, use cruise speed, otherwise use max - // } else if (Minion_Read_Input(REV_SW, &mErr)) { - // desiredVelocity = -MAX_VELOCITY; //no cruising in reverse - // cruiseState = OFF; - // } - - - // if((cruiseState == ON)&&(Minion_Read_Input(FOR_SW, &mErr))&&(forwardPercent==0)){ //we're in cruise mode and not accelerating so use total current to hit cruise velocity - // desiredMotorCurrent = (float) 0.5; - // } else { - // desiredMotorCurrent = convertPedaltoMotorPercent(forwardPercent); - // } - - // } - - // if ((Contactors_Get(MOTOR_CONTACTOR)) && ((Minion_Read_Input(FOR_SW, &mErr) || Minion_Read_Input(REV_SW, &mErr)))) { - // MotorController_Drive(velocity_to_rpm(desiredVelocity), desiredMotorCurrent); - // } - - // Delay of few milliseconds (100) - OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); - - if (err != OS_ERR_NONE){ - assertOSError(OS_UPDATE_VEL_LOC, err); - } - } -} diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 49d2edc9d..96decfd20 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -100,16 +100,16 @@ void Task_Init(void *p_arg){ ); assertOSError(OS_MAIN_LOC, err); - // Initialize UpdateVelocity + // Initialize SendTritium OSTaskCreate( - (OS_TCB*)&UpdateVelocity_TCB, - (CPU_CHAR*)"UpdateVelocity", - (OS_TASK_PTR)Task_UpdateVelocity, + (OS_TCB*)&SendTritium_TCB, + (CPU_CHAR*)"SendTritium", + (OS_TASK_PTR)Task_SendTritium, (void*)NULL, - (OS_PRIO)TASK_UPDATE_VELOCITY_PRIO, - (CPU_STK*)UpdateVelocity_Stk, + (OS_PRIO)TASK_SEND_TRITIUM_PRIO, + (CPU_STK*)SendTritium_Stk, (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_UPDATE_VELOCITY_STACK_SIZE, + (CPU_STK_SIZE)TASK_SEND_TRITIUM_STACK_SIZE, (OS_MSG_QTY)0, (OS_TICK)0, (void*)NULL, diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index 8f9330c28..a8100fc95 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -51,25 +51,6 @@ typedef enum{ FAULT } Page_t; -/** - * For display elements with three states - */ -typedef enum{ - STATE_0 =0, - STATE_1 =1, - STATE_2 =2 -} TriState_t; - -// For cruise control and regen -#define DISABLED STATE_0 -#define ENABLED STATE_1 // Able to be used -#define ACTIVE STATE_2 // Actively being used right now - -// For gear changes -#define NEUTRAL STATE_0 -#define FORWARD STATE_1 -#define REVERSE STATE_2 - /** * Argument types */ diff --git a/Tests/Test_SendTritium.c b/Tests/Test_SendTritium.c new file mode 100644 index 000000000..d6bc6a8c5 --- /dev/null +++ b/Tests/Test_SendTritium.c @@ -0,0 +1,587 @@ +#include "Minions.h" +#include "Pedals.h" +#include "FaultState.h" +#include "CANbus.h" +//#include "MotorController.h" +#include "ReadCarCAN.h" +#include "BSP_UART.h" +#include "Tasks.h" + +// Test macro for SendTritium +#define __TEST_SENDTRITIUM +#include "SendTritium.h" + +static OS_TCB Task1TCB; +static CPU_STK Task1Stk[DEFAULT_STACK_SIZE]; + +void stateBuffer(){ + OS_ERR err; + OSTimeDlyHMSM(0, 0, 0, FSM_PERIOD + 10, OS_OPT_TIME_HMSM_STRICT, &err); + assertOSError(OS_UPDATE_VEL_LOC, err); +} + +void goToBrakeState(){ + // Brake State + brakePedalPercent = 15; + stateBuffer(); +} + +void goToForwardDrive(){ + goToBrakeState(); + + //Forward Drive + brakePedalPercent = 0; + + gear = FORWARD_GEAR; + + stateBuffer(); +} + +void goToNeutralDrive(){ + goToForwardDrive(); + + // Neutral Drive + gear = NEUTRAL_GEAR; + + stateBuffer(); +} + +void goToReverseDrive(){ + goToForwardDrive(); + + // Reverse Drive + gear = REVERSE_GEAR; + + stateBuffer(); // Transition to neutral + + velocityObserved = 5; + stateBuffer(); // Transition to reverse +} + + +void goToOnePedalDrive(){ + goToForwardDrive(); + + // One Pedal Drive + cruiseEnable = false; + onePedalEnable = true; + regenEnable = true; + stateBuffer(); +} + +void goToRecordVelocity(){ + goToForwardDrive(); + + // Record Velocity + cruiseEnable = true; + cruiseSet = true; + stateBuffer(); + +} + +void goToPoweredCruise(){ + goToRecordVelocity(); + + // Powered Cruise + cruiseEnable = true; + cruiseSet = false; + velocityObserved = 30; + cruiseVelSetpoint = 40; + stateBuffer(); +} + +void goToCoastingCruise(){ + goToPoweredCruise(); + + // Coasting Cruise + cruiseEnable = true; + cruiseSet = false; + velocityObserved = 40; + cruiseVelSetpoint = 30; + stateBuffer(); +} + +void goToAccelerateCruise(){ + goToPoweredCruise(); + + // Coasting Cruise + cruiseEnable = true; + cruiseSet = false; + velocityObserved = 30; + cruiseVelSetpoint = 30; + accelPedalPercent = 10; + stateBuffer(); +} + +void Task1(void *arg) +{ + OS_ERR err; + + CPU_Init(); + BSP_UART_Init(UART_2); + Pedals_Init(); + CANbus_Init(MOTORCAN); + Minion_Init(); + + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U)OSCfg_TickRate_Hz); + regenEnable = ON; + + OSTaskCreate( + (OS_TCB*)&SendTritium_TCB, + (CPU_CHAR*)"SendTritium", + (OS_TASK_PTR)Task_SendTritium, + (void*) NULL, + (OS_PRIO)TASK_SEND_TRITIUM_PRIO, + (CPU_STK*)SendTritium_Stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT/10, + (CPU_STK_SIZE)TASK_SEND_TRITIUM_STACK_SIZE, + (OS_MSG_QTY) 0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR*)&err + ); + //assertOSError(err); + + /** + * ======= Forward Drive ========== + * State Transitions: + * Brake, Record Velocity, One Pedal, Neutral, Reverse + */ + printf("\n\r============ Testing Forward Drive State ============\n\r"); + + // Forward Drive to Brake + printf("\n\rTesting: Forward Drive -> Brake\n\r"); + goToForwardDrive(); + brakePedalPercent = 15; + stateBuffer(); + + // Forward Drive to Record Velocity + printf("\n\rTesting: Forward Drive -> Record Velocity\n\r"); + goToForwardDrive(); + cruiseEnable = true; + cruiseSet = true; + velocityObserved = 20.0; + stateBuffer(); + velocityObserved = 25.0; + stateBuffer(); + + // Forward Drive to One Pedal + printf("\n\rTesting: Forward Drive -> One Pedal\n\r"); + goToForwardDrive(); + onePedalEnable = true; + stateBuffer(); + + // Forward Drive to Neutral Drive + printf("\n\rTesting: Forward Drive -> Neutral Drive\n\r"); + goToForwardDrive(); + gear = NEUTRAL_GEAR; + stateBuffer(); + + // Forward Drive to Reverse Drive + printf("\n\rTesting: Forward Drive -> Reverse Drive\n\r"); + goToForwardDrive(); + gear = REVERSE_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + /** + * ======= Neutral Drive ========== + * State Transitions: + * Brake, Forward Drive, Reverse Drive + */ + + printf("\n\r============ Testing Neutral Drive State ============\n\r"); + + // Neutral Drive to Brake + printf("\n\rTesting: Neutral Drive -> Brake\n\r"); + goToNeutralDrive(); + brakePedalPercent = 15; + stateBuffer(); + + // Neutral Drive to Forward Drive + printf("\n\rTesting: Neutral Drive -> Forward Drive\n\r"); + goToNeutralDrive(); + velocityObserved = 5; + gear = FORWARD_GEAR; + stateBuffer(); + + // Neutral Drive to Reverse Drive + printf("\n\rTesting: Neutral Drive -> Reverse Drive\n\r"); + goToNeutralDrive(); + velocityObserved = 5; + gear = REVERSE_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + /** + * ======= Reverse Drive ========== + * State Transitions: + * Brake, Neutral Drive + */ + + printf("\n\r============ Testing Reverse Drive State ============\n\r"); + + // Reverse Drive to Brake + printf("\n\rTesting: Reverse Drive -> Brake\n\r"); + goToReverseDrive(); + brakePedalPercent = 15; + stateBuffer(); + + // Reverse Drive to Neutral Drive + printf("\n\rTesting: Reverse Drive -> Neutral Drive\n\r"); + goToReverseDrive(); + velocityObserved = 35; + gear = NEUTRAL_GEAR; + stateBuffer(); + + // Reverse Drive to Forward Drive + printf("\n\rTesting: Reverse Drive -> Forward Drive\n\r"); + goToReverseDrive(); + gear = FORWARD_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + /** + * ======= Record Velocity ========== + * State Transitions: + * Brake State, Neutral, One Pedal, Forward Drive, Powered Cruise + */ + printf("\n\r============ Testing Record Velocity State ============\n\r"); + + // Record Velocity to Brake State + printf("\n\rTesting: Record Velocity -> Brake\n\r"); + goToRecordVelocity(); + brakePedalPercent = 15; + stateBuffer(); + + // Record Velocity to Neutral Drive + printf("\n\rTesting: Record Velocity -> Brake\n\r"); + goToRecordVelocity(); + gear = NEUTRAL_GEAR; + stateBuffer(); + + // Record Velocity to Reverse Drive + printf("\n\rTesting: Record Velocity -> Reverse Drive\n\r"); + goToRecordVelocity(); + gear = REVERSE_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + // Record Velocity to One Pedal Drive + printf("\n\rTesting: Record Velocity -> One Pedal Drive\n\r"); + goToRecordVelocity(); + onePedalEnable = true; + stateBuffer(); + + // Record Velocity to Forward Normal Drive + printf("\n\rTesting: Record Velocity -> Forward Drive\n\r"); + goToRecordVelocity(); + cruiseEnable = false; + stateBuffer(); + + // Record Velocity to Powered Cruise + printf("\n\rTesting: Record Velocity -> Powered Cruise\n\r"); + goToRecordVelocity(); + cruiseEnable = true; + cruiseSet = false; + stateBuffer(); + + /** + * ======= Powered Cruise ========== + * State Transitions: + * Brake, Neutral, One Pedal, Forward Drive, Record Velocity, Accelerate Cruise, Coasting Cruise + */ + printf("\n\r============ Testing Powered Cruise State ============\n\r"); + + // Powered Cruise to Brake State + printf("\n\rTesting: Powered Cruise -> Brake\n\r"); + goToPoweredCruise(); + brakePedalPercent = 15; + stateBuffer(); + + // Powered Cruise to Neutral Drive + printf("\n\rTesting: Powered Cruise -> Neutral Drive\n\r"); + goToPoweredCruise(); + gear = NEUTRAL_GEAR; + stateBuffer(); + + // Powered Cruise to Reverse Drive + printf("\n\rTesting: Powered Cruise -> Reverse Drive\n\r"); + goToPoweredCruise(); + gear = REVERSE_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + // Powered Cruise to One Pedal Drive + printf("\n\rTesting: Powered Cruise -> One Pedal Drive\n\r"); + goToPoweredCruise(); + onePedalEnable = true; + stateBuffer(); + + // Powered Cruise to Forward Drive + printf("\n\rTesting: Powered Cruise -> Forward Drive\n\r"); + goToPoweredCruise(); + cruiseEnable = false; + stateBuffer(); + + // Powered Cruise to Record Velocity + printf("\n\rTesting: Powered Cruise -> Record Velocity\n\r"); + goToPoweredCruise(); + cruiseSet = true; + stateBuffer(); + + // Powered Cruise to Accelerate Cruise + printf("\n\rTesting: Powered Cruise -> Accelerate Cruise\n\r"); + goToPoweredCruise(); + accelPedalPercent = 10; + stateBuffer(); + + // Powered Cruise to Coasting Cruise + printf("\n\rTesting: Powered Cruise -> Coasting Cruise\n\r"); + goToPoweredCruise(); + velocityObserved = 40; + cruiseVelSetpoint = 30; + stateBuffer(); + + /** + * ======= Coasting Cruise ========== + * State Transitions: + * Brake, Neutral Drive, One Pedal, Forward Drive, Record Velocity, + * Accelerate Cruise, Powered Cruise + */ + printf("\n\r============ Testing Coasting Cruise State ============\n\r"); + + // Coasting Cruise to Brake State + printf("\n\rTesting: Coasting Cruise -> Brake\n\r"); + goToCoastingCruise(); + brakePedalPercent = 15; + stateBuffer(); + + // Coasting Cruise to Neutral Drive + printf("\n\rTesting: Coasting Cruise -> Neutral Drive\n\r"); + goToCoastingCruise(); + gear = NEUTRAL_GEAR; + stateBuffer(); + + // Coasting Cruise to Reverse Drive + printf("\n\rTesting: Coasting Cruise -> Reverse Drive\n\r"); + goToCoastingCruise(); + gear = REVERSE_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + // Coasting Cruise to One Pedal Drive + printf("\n\rTesting: Coasting Cruise -> One Pedal Drive\n\r"); + goToCoastingCruise(); + onePedalEnable = true; + stateBuffer(); + + // Coasting Cruise to Forward Drive + printf("\n\rTesting: Coasting Cruise -> Forward Drive\n\r"); + goToCoastingCruise(); + cruiseEnable = false; + stateBuffer(); + + // Coasting Cruise to Record Velocity + printf("\n\rTesting: Coasting Cruise -> Record Velocity\n\r"); + goToCoastingCruise(); + cruiseSet = true; + velocityObserved = 25.0; + stateBuffer(); + + // Coasting Cruise to Accelerate Cruise + printf("\n\rTesting: Coasting Cruise -> Accelerate Cruise\n\r"); + goToCoastingCruise(); + accelPedalPercent = 10; + stateBuffer(); + + // Coasting Cruise to Powered Cruise + printf("\n\rTesting: Powered Cruise -> Coasting Cruise\n\r"); + goToPoweredCruise(); + velocityObserved = 29; + cruiseVelSetpoint = 30; + stateBuffer(); + + /** + * ======= Accelerate Cruise State ========== + * State Transitions: + * Coasting Cruise, Brake State + */ + printf("\n\r============ Testing Accelerate Cruise State ============\n\r"); + + // Accelerate Cruise to Brake State + printf("\n\rTesting: Accelerate Cruise -> Brake\n\r"); + goToOnePedalDrive(); + brakePedalPercent = 15; + stateBuffer(); + + // Accelerate Cruise to Neutral Drive + printf("\n\rTesting: Accelerate Cruise -> Nuetral Drive\n\r"); + goToOnePedalDrive(); + gear = NEUTRAL_GEAR; + stateBuffer(); + + // Accelerate Cruise to Reverse Drive + printf("\n\rTesting: Accelerate Cruise -> Reverse Drive\n\r"); + goToOnePedalDrive(); + gear = REVERSE_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + // Accelerate Cruise to One Pedal Drive + printf("\n\rTesting: Accelerate Cruise -> One Pedal Drive\n\r"); + goToOnePedalDrive(); + onePedalEnable = true; + stateBuffer(); + + // Accelerate Cruise to Normal Drive + printf("\n\rTesting: Accelerate Cruise -> Forward Normal Drive\n\r"); + goToOnePedalDrive(); + cruiseEnable = false; + stateBuffer(); + + // Accelerate Cruise to Record Velocity + printf("\n\rTesting: Accelerate Cruise -> Record Velocity\n\r"); + goToOnePedalDrive(); + cruiseSet = true; + velocityObserved = 25.0; + stateBuffer(); + + // Accelerate Cruise to Coasting Cruise + printf("\n\rTesting: Accelerate Cruise -> Coasting Cruise\n\r"); + goToCoastingCruise(); + accelPedalPercent = 0; + stateBuffer(); + + /** + * ======= One Pedal Drive ========== + * State Transitions: + * Brake, Neutral Drive, Forward Drive + */ + + printf("\n\r============ Testing One Pedal Drive State ============\n\r"); + + // One Pedal Drive to Brake + printf("\n\rTesting: One Pedal Drive -> Brake\n\r"); + goToOnePedalDrive(); + brakePedalPercent = 15; + stateBuffer(); + + // One Pedal Drive to Neutral Drive + printf("\n\rTesting: One Pedal Drive -> Neutral Drive\n\r"); + gear = NEUTRAL_GEAR; + stateBuffer(); + + // One Pedal Drive to Reverse Drive + printf("\n\rTesting: One Pedal Drive -> Reverse Drive\n\r"); + gear = NEUTRAL_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + // One Pedal Drive to Record Velocity + printf("\n\rTesting: One Pedal Drive -> Record Velocity\n\r"); + cruiseSet = true; + cruiseEnable = true; + velocityObserved = 25.0; + stateBuffer(); + + /** + * ======= Brake State ========== + * State Transitions: + * Brake Disable State + */ + printf("\n\r============ Testing Brake State ============\n\r"); + + // Brake State to Forward Drive + printf("\n\rTesting: Brake -> Forward Drive\n\r"); + goToBrakeState(); + brakePedalPercent = 1; + gear = FORWARD_GEAR; + stateBuffer(); + + // Brake State to Neutral Drive + printf("\n\rTesting: Brake -> Neutral Drive\n\r"); + goToBrakeState(); + brakePedalPercent = 1; + gear = NEUTRAL_GEAR; + stateBuffer(); + + // Brake State to Reverse Drive + printf("\n\rTesting: Brake -> Reverse Drive\n\r"); + goToBrakeState(); + brakePedalPercent = 1; + gear = REVERSE_GEAR; + velocityObserved = 35; + stateBuffer(); + velocityObserved = 5; + stateBuffer(); + + while (1){ + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + assertOSError(OS_MAIN_LOC, err); + } +}; + +int main() +{ + OS_ERR err; + OSInit(&err); + OSSemCreate( // create fault sem4 + &FaultState_Sem4, + "Fault State Semaphore", + 0, + &err); + assertOSError(OS_MAIN_LOC, err); + + OSTaskCreate( // create fault task + (OS_TCB *)&FaultState_TCB, + (CPU_CHAR *)"Fault State", + (OS_TASK_PTR)&Task_FaultState, + (void *)NULL, + (OS_PRIO)1, + (CPU_STK *)FaultState_Stk, + (CPU_STK_SIZE)128 / 10, + (CPU_STK_SIZE)128, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR *)&err); + assertOSError(OS_MAIN_LOC, err); + + // create tester thread + OSTaskCreate( + (OS_TCB *)&Task1TCB, + (CPU_CHAR *)"Task 1", + (OS_TASK_PTR)Task1, + (void *)NULL, + (OS_PRIO)13, + (CPU_STK *)Task1Stk, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE / 10, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR *)&err); + assertOSError(OS_MAIN_LOC, err); + + OSStart(&err); +} \ No newline at end of file diff --git a/Tests/Test_UpdateVelocity.c b/Tests/Test_UpdateVelocity.c deleted file mode 100644 index 2c1227205..000000000 --- a/Tests/Test_UpdateVelocity.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "common.h" -#include "config.h" -#include "UpdateVelocity.h" -#include "BSP_UART.h" -#include "CANbus.h" -#include "Display.h" -#include "Contactors.h" -#include "Minions.h" -#include "Pedals.h" -#include "CAN_Queue.h" - -static volatile int x = 0; - -OS_TCB Task1_TCB; -CPU_STK Task1_Stk[256]; - -void Task1(void *p_arg) { - OS_ERR err; - - BSP_UART_Init(UART_2); - CANbus_Init(); - Contactors_Init(); - Display_Init(); - Minions_Init(); - MotorController_Init(1.0f); // Let motor controller use 100% of bus current - Pedals_Init(); - CAN_Queue_Init(); - - OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - OSTaskCreate( - (OS_TCB*)&UpdateVelocity_TCB, - (CPU_CHAR*)"UpdateVelocity", - (OS_TASK_PTR)Task_UpdateVelocity, - (void*) NULL, - (OS_PRIO)TASK_UPDATE_VELOCITY_PRIO, - (CPU_STK*)UpdateVelocity_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT/10, - (CPU_STK_SIZE)TASK_UPDATE_VELOCITY_STACK_SIZE, - (OS_MSG_QTY) 0, - (OS_TICK)NULL, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - if (err != OS_ERR_NONE) { - for(;;) x++; - } - - OSSemCreate(&FaultState_Sem4, "Fault State Semaphore", 0, &err); - if (err != OS_ERR_NONE) { - for(;;) x++; - } - - static bool lastCruiseEnPushed = true; - State cruiseEnablePushed = OFF; - while (1) { - OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_HMSM_STRICT, &err); - Switches_UpdateStates(); //UpdateVelocity thread depends on switch Values - cruiseEnablePushed = Switches_Read(CRUZ_EN); //read cruise enable switch - if (!lastCruiseEnPushed && cruiseEnablePushed) { //Rising Edge detector for updateVelocity thread - UpdateVel_ToggleCruise = true; - } - lastCruiseEnPushed = cruiseEnablePushed; - CANbuff buf; - __unused - ErrorStatus status = MotorController_Read(&buf); - } -} - -int main() { - OS_ERR err; - OSInit(&err); - - if(err != OS_ERR_NONE){ - for (;;) x++; - } - - OSTaskCreate(&Task1_TCB, - "Task 1", - Task1, - (void *) NULL, - 5, - Task1_Stk, - 16, - 256, - 0, - 0, - (void *) NULL, - OS_OPT_TASK_STK_CHK, - &err - ); - - if (err != OS_ERR_NONE) { - for(;;) x++; - } - - OSStart(&err); - if (err != OS_ERR_NONE) { - for(;;) x++; - } -} \ No newline at end of file diff --git a/Tests/Test_UpdateVelocityNoSpoof.c b/Tests/Test_UpdateVelocityNoSpoof.c deleted file mode 100644 index 5a52959d2..000000000 --- a/Tests/Test_UpdateVelocityNoSpoof.c +++ /dev/null @@ -1,186 +0,0 @@ -#include "common.h" -#include "config.h" -#include "UpdateVelocity.h" -#include "BSP_UART.h" -#include "CANbus.h" -#include "Display.h" -#include "Contactors.h" -#include "Minions.h" -#include "Pedals.h" -#include "CAN_Queue.h" - -static volatile int x = 0; - -OS_TCB Task1_TCB; -CPU_STK Task1_Stk[256]; - -void Task1(void *p_arg) { - OS_ERR err; - - OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - Pedals_Init(); - OSTimeDlyHMSM(0,0,5,0,OS_OPT_TIME_HMSM_STRICT,&err); - MotorController_Init(1.0f); // Let motor controller use 100% of bus current - OSTimeDlyHMSM(0,0,10,0,OS_OPT_TIME_HMSM_STRICT,&err); - BSP_UART_Init(UART_2); - CANbus_Init(); - Contactors_Init(); - Display_Init(); - Minions_Init(); - CAN_Queue_Init(); - - //init updatevelocity - OSTaskCreate( - (OS_TCB*)&UpdateVelocity_TCB, - (CPU_CHAR*)"UpdateVelocity", - (OS_TASK_PTR)Task_UpdateVelocity, - (void*) NULL, - (OS_PRIO)TASK_UPDATE_VELOCITY_PRIO, - (CPU_STK*)UpdateVelocity_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT/10, - (CPU_STK_SIZE)TASK_UPDATE_VELOCITY_STACK_SIZE, - (OS_MSG_QTY) 0, - (OS_TICK)NULL, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - // Initialize ReadSwitches - OSTaskCreate( - (OS_TCB*)&ReadSwitches_TCB, - (CPU_CHAR*)"ReadSwitches", - (OS_TASK_PTR)Task_ReadSwitches, - (void*)NULL, - (OS_PRIO)TASK_READ_SWITCHES_PRIO, - (CPU_STK*)ReadSwitches_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_READ_SWITCHES_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - - // Initialize BlinkLights - OSTaskCreate( - (OS_TCB*)&BlinkLight_TCB, - (CPU_CHAR*)"BlinkLight", - (OS_TASK_PTR)Task_BlinkLight, - (void*)NULL, - (OS_PRIO)TASK_BLINK_LIGHT_PRIO, - (CPU_STK*)BlinkLight_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_BLINK_LIGHT_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - assertOSError(OS_MAIN_LOC, err); - - // Initialize ReadTritium - OSTaskCreate( - (OS_TCB*)&ReadTritium_TCB, - (CPU_CHAR*)"ReadTritium", - (OS_TASK_PTR)Task_ReadTritium, - (void*)NULL, - (OS_PRIO)TASK_READ_TRITIUM_PRIO, - (CPU_STK*)ReadTritium_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_READ_TRITIUM_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - - OSTaskCreate( - (OS_TCB*)&UpdateDisplay_TCB, - (CPU_CHAR*)"UpdateDisplay", - (OS_TASK_PTR)Task_UpdateDisplay, - (void*)NULL, - (OS_PRIO)TASK_UPDATE_DISPLAY_PRIO, - (CPU_STK*)UpdateDisplay_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_UPDATE_DISPLAY_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - - OSTaskCreate( - (OS_TCB*)&FaultState_TCB, - (CPU_CHAR*)"FaultState", - (OS_TASK_PTR)Task_FaultState, - (void*)NULL, - (OS_PRIO)TASK_FAULT_STATE_PRIO, - (CPU_STK*)FaultState_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_FAULT_STATE_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - assertOSError(OS_MAIN_LOC, err); - - - if (err != OS_ERR_NONE) { - for(;;) x++; - } - - OSSemCreate(&FaultState_Sem4, "Fault State Semaphore", 0, &err); - if (err != OS_ERR_NONE) { - for(;;) x++; - } - - //value injection for display - SupplementalVoltage = 2000; - StateOfCharge = 100 * 1000000; - - - while (1) { - OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_HMSM_STRICT, &err); - // SupplementalVoltage += 100; //value injection for display thread, normally would be handled by ReadCarCAN thread - - } -} - -int main() { - OS_ERR err; - OSInit(&err); - - if(err != OS_ERR_NONE){ - for (;;) x++; - } - - OSTaskCreate(&Task1_TCB, - "Task 1", - Task1, - (void *) NULL, - 5, - Task1_Stk, - 16, - 256, - 0, - 0, - (void *) NULL, - OS_OPT_TASK_STK_CHK, - &err - ); - - if (err != OS_ERR_NONE) { - for(;;) x++; - } - - OSStart(&err); - if (err != OS_ERR_NONE) { - for(;;) x++; - } -} \ No newline at end of file From 0a95ef01e028ebc89f79978d1a490e0f9d66dbeb Mon Sep 17 00:00:00 2001 From: ishdeshpa Date: Mon, 16 Jan 2023 03:25:57 +0000 Subject: [PATCH 039/141] verified all FSM transitions in Test_SendTritium on renode simulation platform --- Apps/Inc/SendTritium.h | 27 ++++++++++-- Apps/Src/SendTritium.c | 85 +++++++++++++++++++++-------------- Tests/Test_SendTritium.c | 95 +++++++++++++++++++++++++++++++--------- 3 files changed, 150 insertions(+), 57 deletions(-) diff --git a/Apps/Inc/SendTritium.h b/Apps/Inc/SendTritium.h index f0d3d48b3..a64ec2d6a 100644 --- a/Apps/Inc/SendTritium.h +++ b/Apps/Inc/SendTritium.h @@ -1,8 +1,8 @@ #ifndef __SENDTRITIUM_H #define __SENDTRITIUM_H -#define MOTOR_MSG_PERIOD 100 -#define FSM_PERIOD 20 +#define MOTOR_MSG_PERIOD 500 +#define FSM_PERIOD 250 #define DEBOUNCE_PERIOD 2 // in units of FSM_PERIOD #define MOTOR_MSG_COUNTER_THRESHOLD (MOTOR_MSG_PERIOD)/(FSM_PERIOD) @@ -12,6 +12,27 @@ typedef enum{ REVERSE_GEAR } Gear_t; +// State Names +typedef enum{ + FORWARD_DRIVE, + NEUTRAL_DRIVE, + REVERSE_DRIVE, + RECORD_VELOCITY, + POWERED_CRUISE, + COASTING_CRUISE, + BRAKE_STATE, + ONEPEDAL, + ACCELERATE_CRUISE +} TritiumStateName_t; + +// State Struct for FSM +typedef struct TritiumState{ + TritiumStateName_t name; + void (*stateHandler)(void); + void (*stateDecider)(void); +} TritiumState_t; + +#define __TEST_SENDTRITIUM #ifdef __TEST_SENDTRITIUM // Inputs extern bool cruiseEnable; @@ -24,7 +45,7 @@ extern uint8_t accelPedalPercent; extern Gear_t gear; -extern uint8_t state; +extern TritiumState_t state; extern float velocityObserved; extern float cruiseVelSetpoint; #endif diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index db7ce446b..7ec815bab 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -38,7 +38,7 @@ #define GEAR_FAULT_THRESHOLD 3 // number of times gear fault can occur before it is considered a fault -#ifdef __TEST_SENDTRITIUM +#ifndef __TEST_SENDTRITIUM #define STATIC(def) static def #else #define STATIC(def) def @@ -63,10 +63,10 @@ float cruiseVelSetpoint = 0; // Current observed velocity STATIC(float) velocityObserved = 0; +#ifndef __TEST_SENDTRITIUM // Counter for sending setpoints to motor static uint8_t motorMsgCounter = 0; -#ifndef __TEST_SENDTRITIUM // Debouncing counters static uint8_t onePedalCounter = 0; static uint8_t cruiseEnableCounter = 0; @@ -101,26 +101,6 @@ static void OnePedalDriveDecider(void); static void AccelerateCruiseHandler(void); static void AccelerateCruiseDecider(void); -// State Names -typedef enum{ - FORWARD_DRIVE, - NEUTRAL_DRIVE, - REVERSE_DRIVE, - RECORD_VELOCITY, - POWERED_CRUISE, - COASTING_CRUISE, - BRAKE_STATE, - ONEPEDAL, - ACCELERATE_CRUISE -} TritiumStateName_t; - -// State Struct for FSM -typedef struct TritiumState{ - TritiumStateName_t name; - void (*stateHandler)(void); - void (*stateDecider)(void); -} TritiumState_t; - // FSM static const TritiumState_t FSM[9] = { {FORWARD_DRIVE, &ForwardDriveHandler, &ForwardDriveDecider}, @@ -135,25 +115,62 @@ static const TritiumState_t FSM[9] = { }; static TritiumState_t prevState; // Previous state -static TritiumState_t state; // Current state +STATIC(TritiumState_t) state; // Current state /** * @brief Dumps info to UART during testing */ #ifdef __TEST_SENDTRITIUM +static void getName(char* nameStr, uint8_t stateNameNum){ + switch(stateNameNum){ + case FORWARD_DRIVE: + strcpy(nameStr, "FORWARD_DRIVE"); + break; + case NEUTRAL_DRIVE: + strcpy(nameStr, "NEUTRAL_DRIVE"); + break; + case REVERSE_DRIVE: + strcpy(nameStr, "REVERSE_DRIVE"); + break; + case RECORD_VELOCITY: + strcpy(nameStr, "RECORD_VELOCITY"); + break; + case POWERED_CRUISE: + strcpy(nameStr, "POWERED_CRUISE"); + break; + case COASTING_CRUISE: + strcpy(nameStr, "COASTING_CRUISE"); + break; + case BRAKE_STATE: + strcpy(nameStr, "BRAKE_STATE"); + break; + case ONEPEDAL: + strcpy(nameStr, "ONEPEDAL"); + break; + case ACCELERATE_CRUISE: + strcpy(nameStr, "ACCELERATE_CRUISE"); + break; + default: + strcpy(nameStr, "UNKNOWN"); + break; + } + return; +} + static void dumpInfo(){ printf("-------------------\n\r"); - printf("State: %d\n\r", state); + char stateName[20]; + getName(stateName, state.name); + printf("State: %s\n\r", stateName); printf("cruiseEnable: %d\n\r", cruiseEnable); printf("cruiseSet: %d\n\r", cruiseSet); printf("onePedalEnable: %d\n\r", onePedalEnable); printf("brakePedalPercent: %d\n\r", brakePedalPercent); printf("accelPedalPercent: %d\n\r", accelPedalPercent); - printf("reverseSwitch: %d\n\r", reverseSwitch); - printf("forwardSwitch: %d\n\r", forwardSwitch); - printf("currentSetpoint: %f\n\r", currentSetpoint); - printf("velocitySetpoint: %f\n\r", velocitySetpoint); - printf("velocityObserved: %f\n\r", velocityObserved); + printf("gear: %d\n\r", (uint8_t)gear); + printf("currentSetpoint: %4.2f\n\r", currentSetpoint); + printf("velocitySetpoint: %4.2f\n\r", velocitySetpoint); + printf("velocityObserved: %4.2f\n\r", velocityObserved); printf("-------------------\n\r"); } #endif @@ -284,7 +301,7 @@ static void ForwardDriveHandler(){ */ static void ForwardDriveDecider(){ if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE]; + state = FSM[BRAKE_STATE]; }else if(cruiseSet && cruiseEnable && velocityObserved >= MIN_CRUISE_VELOCITY){ state = FSM[RECORD_VELOCITY]; }else if(onePedalEnable){ @@ -316,7 +333,7 @@ static void NeutralDriveHandler(){ */ static void NeutralDriveDecider(){ if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE]; + state = FSM[BRAKE_STATE]; }else if(gear == FORWARD_GEAR && velocityObserved >= -MAX_GEARSWITCH_VELOCITY){ state = FSM[FORWARD_DRIVE]; }else if(gear == REVERSE_GEAR && velocityObserved <= MAX_GEARSWITCH_VELOCITY){ @@ -346,7 +363,7 @@ static void ReverseDriveHandler(){ */ static void ReverseDriveDecider(){ if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE]; + state = FSM[BRAKE_STATE]; } else if(gear == NEUTRAL_GEAR || gear == FORWARD_GEAR){ state = FSM[NEUTRAL_DRIVE]; @@ -527,7 +544,7 @@ static void OnePedalDriveHandler(){ static void OnePedalDriveDecider(){ Minion_Error_t minion_err; if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE]; + state = FSM[BRAKE_STATE]; }else if(cruiseSet && cruiseEnable && velocityObserved >= MIN_CRUISE_VELOCITY){ state = FSM[RECORD_VELOCITY]; Minion_Write_Output(BRAKELIGHT, false, &minion_err); @@ -581,12 +598,14 @@ void Task_SendTritium(void *p_arg){ state = FSM[NEUTRAL_DRIVE]; prevState = FSM[NEUTRAL_DRIVE]; + #ifndef __TEST_SENDTRITIUM CANbus_Init(MOTORCAN); CANDATA_t driveCmd = { .ID=MOTOR_DRIVE, .idx=0, .data={0.0f, 0.0f}, }; + #endif while(1){ prevState = state; diff --git a/Tests/Test_SendTritium.c b/Tests/Test_SendTritium.c index d6bc6a8c5..da1f6e895 100644 --- a/Tests/Test_SendTritium.c +++ b/Tests/Test_SendTritium.c @@ -2,13 +2,11 @@ #include "Pedals.h" #include "FaultState.h" #include "CANbus.h" -//#include "MotorController.h" +#include "UpdateDisplay.h" #include "ReadCarCAN.h" #include "BSP_UART.h" #include "Tasks.h" -// Test macro for SendTritium -#define __TEST_SENDTRITIUM #include "SendTritium.h" static OS_TCB Task1TCB; @@ -16,7 +14,7 @@ static CPU_STK Task1Stk[DEFAULT_STACK_SIZE]; void stateBuffer(){ OS_ERR err; - OSTimeDlyHMSM(0, 0, 0, FSM_PERIOD + 10, OS_OPT_TIME_HMSM_STRICT, &err); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); assertOSError(OS_UPDATE_VEL_LOC, err); } @@ -31,7 +29,7 @@ void goToForwardDrive(){ //Forward Drive brakePedalPercent = 0; - + velocityObserved = 2; gear = FORWARD_GEAR; stateBuffer(); @@ -75,8 +73,8 @@ void goToRecordVelocity(){ // Record Velocity cruiseEnable = true; cruiseSet = true; + velocityObserved = 30; stateBuffer(); - } void goToPoweredCruise(){ @@ -122,6 +120,7 @@ void Task1(void *arg) Pedals_Init(); CANbus_Init(MOTORCAN); Minion_Init(); + UpdateDisplay_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U)OSCfg_TickRate_Hz); regenEnable = ON; @@ -142,7 +141,6 @@ void Task1(void *arg) (OS_ERR*)&err ); //assertOSError(err); - /** * ======= Forward Drive ========== * State Transitions: @@ -155,6 +153,7 @@ void Task1(void *arg) goToForwardDrive(); brakePedalPercent = 15; stateBuffer(); + while(state.name != BRAKE_STATE){} // Forward Drive to Record Velocity printf("\n\rTesting: Forward Drive -> Record Velocity\n\r"); @@ -165,18 +164,21 @@ void Task1(void *arg) stateBuffer(); velocityObserved = 25.0; stateBuffer(); + while(state.name != RECORD_VELOCITY){} // Forward Drive to One Pedal printf("\n\rTesting: Forward Drive -> One Pedal\n\r"); goToForwardDrive(); onePedalEnable = true; stateBuffer(); + while(state.name != ONEPEDAL){} // Forward Drive to Neutral Drive printf("\n\rTesting: Forward Drive -> Neutral Drive\n\r"); goToForwardDrive(); gear = NEUTRAL_GEAR; stateBuffer(); + while(state.name != NEUTRAL_DRIVE){} // Forward Drive to Reverse Drive printf("\n\rTesting: Forward Drive -> Reverse Drive\n\r"); @@ -186,6 +188,7 @@ void Task1(void *arg) stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != REVERSE_DRIVE){} /** * ======= Neutral Drive ========== @@ -200,6 +203,7 @@ void Task1(void *arg) goToNeutralDrive(); brakePedalPercent = 15; stateBuffer(); + while(state.name != BRAKE_STATE){} // Neutral Drive to Forward Drive printf("\n\rTesting: Neutral Drive -> Forward Drive\n\r"); @@ -207,6 +211,7 @@ void Task1(void *arg) velocityObserved = 5; gear = FORWARD_GEAR; stateBuffer(); + while(state.name != FORWARD_DRIVE){} // Neutral Drive to Reverse Drive printf("\n\rTesting: Neutral Drive -> Reverse Drive\n\r"); @@ -217,6 +222,7 @@ void Task1(void *arg) stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != REVERSE_DRIVE){} /** * ======= Reverse Drive ========== @@ -231,6 +237,7 @@ void Task1(void *arg) goToReverseDrive(); brakePedalPercent = 15; stateBuffer(); + while(state.name != BRAKE_STATE){} // Reverse Drive to Neutral Drive printf("\n\rTesting: Reverse Drive -> Neutral Drive\n\r"); @@ -238,6 +245,7 @@ void Task1(void *arg) velocityObserved = 35; gear = NEUTRAL_GEAR; stateBuffer(); + while(state.name != NEUTRAL_DRIVE){} // Reverse Drive to Forward Drive printf("\n\rTesting: Reverse Drive -> Forward Drive\n\r"); @@ -247,6 +255,7 @@ void Task1(void *arg) stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != FORWARD_DRIVE){} /** * ======= Record Velocity ========== @@ -260,12 +269,14 @@ void Task1(void *arg) goToRecordVelocity(); brakePedalPercent = 15; stateBuffer(); + while(state.name != BRAKE_STATE){} // Record Velocity to Neutral Drive - printf("\n\rTesting: Record Velocity -> Brake\n\r"); + printf("\n\rTesting: Record Velocity -> Neutral Drive\n\r"); goToRecordVelocity(); gear = NEUTRAL_GEAR; stateBuffer(); + while(state.name != NEUTRAL_DRIVE){} // Record Velocity to Reverse Drive printf("\n\rTesting: Record Velocity -> Reverse Drive\n\r"); @@ -275,18 +286,21 @@ void Task1(void *arg) stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != REVERSE_DRIVE){} // Record Velocity to One Pedal Drive printf("\n\rTesting: Record Velocity -> One Pedal Drive\n\r"); goToRecordVelocity(); onePedalEnable = true; stateBuffer(); + while(state.name != ONEPEDAL){} // Record Velocity to Forward Normal Drive printf("\n\rTesting: Record Velocity -> Forward Drive\n\r"); goToRecordVelocity(); cruiseEnable = false; stateBuffer(); + while(state.name != FORWARD_DRIVE){} // Record Velocity to Powered Cruise printf("\n\rTesting: Record Velocity -> Powered Cruise\n\r"); @@ -294,6 +308,7 @@ void Task1(void *arg) cruiseEnable = true; cruiseSet = false; stateBuffer(); + while(state.name != POWERED_CRUISE){} /** * ======= Powered Cruise ========== @@ -307,12 +322,14 @@ void Task1(void *arg) goToPoweredCruise(); brakePedalPercent = 15; stateBuffer(); + while(state.name != BRAKE_STATE){} // Powered Cruise to Neutral Drive printf("\n\rTesting: Powered Cruise -> Neutral Drive\n\r"); goToPoweredCruise(); gear = NEUTRAL_GEAR; stateBuffer(); + while(state.name != NEUTRAL_DRIVE){} // Powered Cruise to Reverse Drive printf("\n\rTesting: Powered Cruise -> Reverse Drive\n\r"); @@ -322,37 +339,44 @@ void Task1(void *arg) stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != REVERSE_DRIVE){} // Powered Cruise to One Pedal Drive printf("\n\rTesting: Powered Cruise -> One Pedal Drive\n\r"); goToPoweredCruise(); onePedalEnable = true; stateBuffer(); + while(state.name != ONEPEDAL){} // Powered Cruise to Forward Drive printf("\n\rTesting: Powered Cruise -> Forward Drive\n\r"); goToPoweredCruise(); cruiseEnable = false; stateBuffer(); + while(state.name != FORWARD_DRIVE){} // Powered Cruise to Record Velocity printf("\n\rTesting: Powered Cruise -> Record Velocity\n\r"); goToPoweredCruise(); cruiseSet = true; stateBuffer(); + while(state.name != RECORD_VELOCITY){} // Powered Cruise to Accelerate Cruise printf("\n\rTesting: Powered Cruise -> Accelerate Cruise\n\r"); goToPoweredCruise(); accelPedalPercent = 10; stateBuffer(); + while(state.name != ACCELERATE_CRUISE){} // Powered Cruise to Coasting Cruise printf("\n\rTesting: Powered Cruise -> Coasting Cruise\n\r"); goToPoweredCruise(); + accelPedalPercent = 0; velocityObserved = 40; cruiseVelSetpoint = 30; stateBuffer(); + while(state.name != COASTING_CRUISE){} /** * ======= Coasting Cruise ========== @@ -367,12 +391,14 @@ void Task1(void *arg) goToCoastingCruise(); brakePedalPercent = 15; stateBuffer(); + while(state.name != BRAKE_STATE){} // Coasting Cruise to Neutral Drive printf("\n\rTesting: Coasting Cruise -> Neutral Drive\n\r"); goToCoastingCruise(); gear = NEUTRAL_GEAR; stateBuffer(); + while(state.name != NEUTRAL_DRIVE){} // Coasting Cruise to Reverse Drive printf("\n\rTesting: Coasting Cruise -> Reverse Drive\n\r"); @@ -382,18 +408,21 @@ void Task1(void *arg) stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != REVERSE_DRIVE){} // Coasting Cruise to One Pedal Drive printf("\n\rTesting: Coasting Cruise -> One Pedal Drive\n\r"); goToCoastingCruise(); onePedalEnable = true; stateBuffer(); + while(state.name != ONEPEDAL){} // Coasting Cruise to Forward Drive printf("\n\rTesting: Coasting Cruise -> Forward Drive\n\r"); goToCoastingCruise(); cruiseEnable = false; stateBuffer(); + while(state.name != FORWARD_DRIVE){} // Coasting Cruise to Record Velocity printf("\n\rTesting: Coasting Cruise -> Record Velocity\n\r"); @@ -401,19 +430,23 @@ void Task1(void *arg) cruiseSet = true; velocityObserved = 25.0; stateBuffer(); + while(state.name != RECORD_VELOCITY){} // Coasting Cruise to Accelerate Cruise printf("\n\rTesting: Coasting Cruise -> Accelerate Cruise\n\r"); goToCoastingCruise(); accelPedalPercent = 10; stateBuffer(); + while(state.name != ACCELERATE_CRUISE){} // Coasting Cruise to Powered Cruise - printf("\n\rTesting: Powered Cruise -> Coasting Cruise\n\r"); - goToPoweredCruise(); + printf("\n\rTesting: Coasting Cruise -> Powered Cruise\n\r"); + goToCoastingCruise(); + accelPedalPercent = 0; velocityObserved = 29; cruiseVelSetpoint = 30; stateBuffer(); + while(state.name != POWERED_CRUISE){} /** * ======= Accelerate Cruise State ========== @@ -424,49 +457,56 @@ void Task1(void *arg) // Accelerate Cruise to Brake State printf("\n\rTesting: Accelerate Cruise -> Brake\n\r"); - goToOnePedalDrive(); + goToAccelerateCruise(); brakePedalPercent = 15; stateBuffer(); + while(state.name != BRAKE_STATE){} // Accelerate Cruise to Neutral Drive - printf("\n\rTesting: Accelerate Cruise -> Nuetral Drive\n\r"); - goToOnePedalDrive(); + printf("\n\rTesting: Accelerate Cruise -> Neutral Drive\n\r"); + goToAccelerateCruise(); gear = NEUTRAL_GEAR; stateBuffer(); + while(state.name != NEUTRAL_DRIVE){} // Accelerate Cruise to Reverse Drive printf("\n\rTesting: Accelerate Cruise -> Reverse Drive\n\r"); - goToOnePedalDrive(); + goToAccelerateCruise(); gear = REVERSE_GEAR; velocityObserved = 35; stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != REVERSE_DRIVE){} // Accelerate Cruise to One Pedal Drive printf("\n\rTesting: Accelerate Cruise -> One Pedal Drive\n\r"); - goToOnePedalDrive(); + goToAccelerateCruise(); onePedalEnable = true; stateBuffer(); + while(state.name != ONEPEDAL){} - // Accelerate Cruise to Normal Drive - printf("\n\rTesting: Accelerate Cruise -> Forward Normal Drive\n\r"); - goToOnePedalDrive(); + // Accelerate Cruise to Forward Drive + printf("\n\rTesting: Accelerate Cruise -> Forward Drive\n\r"); + goToAccelerateCruise(); cruiseEnable = false; stateBuffer(); + while(state.name != FORWARD_DRIVE){} // Accelerate Cruise to Record Velocity printf("\n\rTesting: Accelerate Cruise -> Record Velocity\n\r"); - goToOnePedalDrive(); + goToAccelerateCruise(); cruiseSet = true; velocityObserved = 25.0; stateBuffer(); + while(state.name != RECORD_VELOCITY){} // Accelerate Cruise to Coasting Cruise printf("\n\rTesting: Accelerate Cruise -> Coasting Cruise\n\r"); - goToCoastingCruise(); + goToAccelerateCruise(); accelPedalPercent = 0; stateBuffer(); + while(state.name != COASTING_CRUISE){} /** * ======= One Pedal Drive ========== @@ -481,26 +521,33 @@ void Task1(void *arg) goToOnePedalDrive(); brakePedalPercent = 15; stateBuffer(); + while(state.name != BRAKE_STATE){} // One Pedal Drive to Neutral Drive printf("\n\rTesting: One Pedal Drive -> Neutral Drive\n\r"); + goToOnePedalDrive(); gear = NEUTRAL_GEAR; stateBuffer(); + while(state.name != NEUTRAL_DRIVE){} // One Pedal Drive to Reverse Drive printf("\n\rTesting: One Pedal Drive -> Reverse Drive\n\r"); - gear = NEUTRAL_GEAR; + goToOnePedalDrive(); + gear = REVERSE_GEAR; velocityObserved = 35; stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != REVERSE_DRIVE){} // One Pedal Drive to Record Velocity printf("\n\rTesting: One Pedal Drive -> Record Velocity\n\r"); + goToOnePedalDrive(); cruiseSet = true; cruiseEnable = true; velocityObserved = 25.0; stateBuffer(); + while(state.name != RECORD_VELOCITY){} /** * ======= Brake State ========== @@ -515,6 +562,7 @@ void Task1(void *arg) brakePedalPercent = 1; gear = FORWARD_GEAR; stateBuffer(); + while(state.name != FORWARD_DRIVE){} // Brake State to Neutral Drive printf("\n\rTesting: Brake -> Neutral Drive\n\r"); @@ -522,6 +570,7 @@ void Task1(void *arg) brakePedalPercent = 1; gear = NEUTRAL_GEAR; stateBuffer(); + while(state.name != NEUTRAL_DRIVE){} // Brake State to Reverse Drive printf("\n\rTesting: Brake -> Reverse Drive\n\r"); @@ -532,8 +581,12 @@ void Task1(void *arg) stateBuffer(); velocityObserved = 5; stateBuffer(); + while(state.name != REVERSE_DRIVE){} + OS_TaskSuspend(&SendTritium_TCB, &err); + assertOSError(OS_MAIN_LOC, err); while (1){ + printf("\n\r\n\rSUCCESS! ALL TESTS PASSED\n\r\n\r"); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); assertOSError(OS_MAIN_LOC, err); } From b5c269cc1073e036d9f3b72f97d35d2a5422dae1 Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 21 Jan 2023 11:08:29 -0600 Subject: [PATCH 040/141] fixed SendTritium test float printing --- Apps/Src/SendTritium.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index 7ec815bab..242b31d08 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -157,6 +157,13 @@ static void getName(char* nameStr, uint8_t stateNameNum){ return; } +static void print_float(float f) { + int n = (int) f; + f -= n; + f *= (10 << 2); + printf("%d.%d\n\r", n, (int) f); +} + static void dumpInfo(){ printf("-------------------\n\r"); char stateName[20]; @@ -168,9 +175,9 @@ static void dumpInfo(){ printf("brakePedalPercent: %d\n\r", brakePedalPercent); printf("accelPedalPercent: %d\n\r", accelPedalPercent); printf("gear: %d\n\r", (uint8_t)gear); - printf("currentSetpoint: %4.2f\n\r", currentSetpoint); - printf("velocitySetpoint: %4.2f\n\r", velocitySetpoint); - printf("velocityObserved: %4.2f\n\r", velocityObserved); + printf("currentSetpoint: "); print_float(currentSetpoint); + printf("velocitySetpoint: "); print_float(velocitySetpoint); + printf("velocityObserved: "); print_float(velocityObserved); printf("-------------------\n\r"); } #endif From 0aa302a79e1b704e10ec97753564a54b4d264655 Mon Sep 17 00:00:00 2001 From: diyarajon Date: Sat, 21 Jan 2023 22:15:30 +0000 Subject: [PATCH 041/141] fixed can msg construction --- Apps/Src/SendTritium.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index 242b31d08..6bfa30b60 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -630,7 +630,7 @@ void Task_SendTritium(void *p_arg){ #else if(MOTOR_MSG_COUNTER_THRESHOLD == motorMsgCounter){ driveCmd.data[0] = currentSetpoint; - driveCmd.data[1] = velocitySetpoint; + driveCmd.data[4] = velocitySetpoint; CANbus_Send(driveCmd, CAN_NON_BLOCKING, MOTORCAN); motorMsgCounter = 0; }else{ From 729a1a21a1ea376eb4f7af407fd6981dfc840265 Mon Sep 17 00:00:00 2001 From: ishdeshpa Date: Sat, 28 Jan 2023 20:32:45 +0000 Subject: [PATCH 042/141] fixed can message memory accesses for reading and sending to tritium fixed cruise velocity setpoint to work with rpm instead of m/s --- Apps/Inc/ReadTritium.h | 4 ++-- Apps/Src/ReadTritium.c | 15 ++++++++----- Apps/Src/SendTritium.c | 51 +++++++++++++++++++++++++----------------- Config/Inc/config.h | 2 +- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index 7d4791934..0debbe0cf 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -34,8 +34,8 @@ typedef enum{ */ tritium_error_code_t MotorController_getTritiumError(void); -uint32_t Motor_RPM_Get(); -uint32_t Motor_Velocity_Get(); +float Motor_RPM_Get(); +float Motor_Velocity_Get(); void MotorController_Restart(); #endif \ No newline at end of file diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index d01615cc2..c20ec1b9d 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -12,8 +12,8 @@ uint16_t Motor_FaultBitmap = T_NONE; -static uint32_t Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read -static uint32_t Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read +static float Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read +static float Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read /** * @brief Returns highest priority tritium error code @@ -82,11 +82,14 @@ void Task_ReadTritium(void *p_arg){ } case VELOCITY:{ + memcpy(&Motor_RPM, &dataBuf.data[0], sizeof(float)); + memcpy(&Motor_Velocity, &dataBuf.data[4], sizeof(float)); + //Motor RPM is in bytes 0-3 - Motor_RPM = *((uint32_t*)(&dataBuf.data[0])); + Motor_RPM = *((float*)(&dataBuf.data[0])); //Car Velocity (in m/s) is in bytes 4-7 - Motor_Velocity = *((uint32_t*)(&dataBuf.data[4])); + Motor_Velocity = *((float*)(&dataBuf.data[4])); uint32_t Car_Velocity = Motor_Velocity; Car_Velocity = ((Car_Velocity * 100) * 3600); //Converting from m/s to m/h, using fixed point factor of 100 @@ -117,10 +120,10 @@ void MotorController_Restart(void){ } -uint32_t Motor_RPM_Get(){ //getter function for motor RPM +float Motor_RPM_Get(){ //getter function for motor RPM return Motor_RPM; } -uint32_t Motor_Velocity_Get(){ //getter function for motor velocity +float Motor_Velocity_Get(){ //getter function for motor velocity return Motor_Velocity; } \ No newline at end of file diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index 6bfa30b60..d7fcfcda4 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -27,8 +27,9 @@ // Macros #define MAX_VELOCITY 20000.0f // rpm (unobtainable value) -#define MIN_CRUISE_VELOCITY 20.0f // m/s -#define MAX_GEARSWITCH_VELOCITY 8.0f // m/s + +#define MIN_CRUISE_VELOCITY mpsToRpm(20.0f) // rpm +#define MAX_GEARSWITCH_VELOCITY mpsToRpm(8.0f) // rpm #define BRAKE_PEDAL_THRESHOLD 5 // percent #define ACCEL_PEDAL_THRESHOLD 10 // percent @@ -117,6 +118,21 @@ static const TritiumState_t FSM[9] = { static TritiumState_t prevState; // Previous state STATIC(TritiumState_t) state; // Current state +// Helper Functions + +/** + * @brief Converts integer percentage to float percentage + * @param percent integer percentage from 0-100 + * @returns float percentage from 0.0-1.0 +*/ +extern const float pedalToPercent[]; +static float percentToFloat(uint8_t percent){ + if(percent > 100){ + return 1.0f; + } + return pedalToPercent[percent]; +} + /** * @brief Dumps info to UART during testing */ @@ -249,25 +265,10 @@ static void readInputs(){ cruiseEnablePrevious = cruiseEnableButton; // Get observed velocity - velocityObserved = Motor_Velocity_Get(); + velocityObserved = Motor_RPM_Get(); } #endif -// Helper Functions - -/** - * @brief Converts integer percentage to float percentage - * @param percent integer percentage from 0-100 - * @returns float percentage from 0.0-1.0 -*/ -extern const float pedalToPercent[]; -static float percentToFloat(uint8_t percent){ - if(percent > 100){ - return 1.0f; - } - return pedalToPercent[percent]; -} - /** * @brief Linearly map range of integers to another range of integers. * in_min to in_max is mapped to out_min to out_max. @@ -285,6 +286,14 @@ static uint8_t map(uint8_t input, uint8_t in_min, uint8_t in_max, uint8_t out_mi else return ((out_max - in_max) * (input - in_min))/(out_min - in_min) + out_min; } +/** + * @brief Meters per second to rpm conversion + * @param velocity_mps velocity in meters per second + * @returns rpm +*/ +inline static float mpsToRpm(float velocity_mps){ + return (velocity_mps * 60) / WHEEL_CIRCUMFERENCE; +} // State Handlers & Deciders @@ -629,8 +638,8 @@ void Task_SendTritium(void *p_arg){ dumpInfo(); #else if(MOTOR_MSG_COUNTER_THRESHOLD == motorMsgCounter){ - driveCmd.data[0] = currentSetpoint; - driveCmd.data[4] = velocitySetpoint; + memcpy(&driveCmd.data[0], ¤tSetpoint, sizeof(float)); + memcpy(&driveCmd.data[4], &velocitySetpoint, sizeof(float)); CANbus_Send(driveCmd, CAN_NON_BLOCKING, MOTORCAN); motorMsgCounter = 0; }else{ @@ -638,6 +647,8 @@ void Task_SendTritium(void *p_arg){ } #endif + + // Delay of MOTOR_MSG_PERIOD ms OSTimeDlyHMSM(0, 0, 0, MOTOR_MSG_PERIOD, OS_OPT_TIME_HMSM_STRICT, &err); if (err != OS_ERR_NONE){ diff --git a/Config/Inc/config.h b/Config/Inc/config.h index a60c4476b..00b93c713 100644 --- a/Config/Inc/config.h +++ b/Config/Inc/config.h @@ -11,7 +11,7 @@ typedef enum {OFF = 0, ON} State; // Wheel diameter in meters -#define WHEEL_DIAMETER 0.5504f +#define WHEEL_CIRCUMFERENCE 3.35145104 // m #define PRECHARGE_MOTOR_DELAY 7 // 7 Seconds #define PRECHARGE_ARRAY_DELAY 2 // 2 Seconds From 608231280f9a53a11e46d35845ab698eba3615b6 Mon Sep 17 00:00:00 2001 From: Ishan Deshpande Date: Fri, 17 Mar 2023 23:56:56 -0500 Subject: [PATCH 043/141] fixed map function and removed magic number usage, also fixed scope macro (#298) --- Apps/Src/SendTritium.c | 57 +++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index d7fcfcda4..dba23f323 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -37,24 +37,29 @@ #define ONEPEDAL_BRAKE_THRESHOLD 25 // percent #define ONEPEDAL_NEUTRAL_THRESHOLD 35 // percent +#define PEDAL_MIN 0 // percent +#define PEDAL_MAX 100 // percent +#define CURRENT_SP_MIN 0 // percent +#define CURRENT_SP_MAX 100 // percent + #define GEAR_FAULT_THRESHOLD 3 // number of times gear fault can occur before it is considered a fault #ifndef __TEST_SENDTRITIUM -#define STATIC(def) static def +#define SCOPE static #else -#define STATIC(def) def +#define SCOPE #endif // Inputs -STATIC(bool) cruiseEnable = false; -STATIC(bool) cruiseSet = false; -STATIC(bool) onePedalEnable = false; -STATIC(bool) regenEnable = false; +SCOPE bool cruiseEnable = false; +SCOPE bool cruiseSet = false; +SCOPE bool onePedalEnable = false; +SCOPE bool regenEnable = false; -STATIC(uint8_t) brakePedalPercent = 0; -STATIC(uint8_t) accelPedalPercent = 0; +SCOPE uint8_t brakePedalPercent = 0; +SCOPE uint8_t accelPedalPercent = 0; -STATIC(Gear_t) gear = NEUTRAL_GEAR; +SCOPE Gear_t gear = NEUTRAL_GEAR; // Outputs float currentSetpoint = 0; @@ -62,7 +67,7 @@ float velocitySetpoint = 0; float cruiseVelSetpoint = 0; // Current observed velocity -STATIC(float) velocityObserved = 0; +SCOPE float velocityObserved = 0; #ifndef __TEST_SENDTRITIUM // Counter for sending setpoints to motor @@ -116,7 +121,7 @@ static const TritiumState_t FSM[9] = { }; static TritiumState_t prevState; // Previous state -STATIC(TritiumState_t) state; // Current state +SCOPE TritiumState_t state; // Current state // Helper Functions @@ -280,10 +285,22 @@ static void readInputs(){ * @returns integer value from out_min to out_max */ static uint8_t map(uint8_t input, uint8_t in_min, uint8_t in_max, uint8_t out_min, uint8_t out_max){ - if(in_max >= in_min) in_max = in_min; - if(input <= in_min) return out_min; - else if(input >= in_max) return out_max; - else return ((out_max - in_max) * (input - in_min))/(out_min - in_min) + out_min; + if(in_min >= in_max) in_max = in_min; // The minimum of the input range should never be greater than the maximum of the input range + + if(input <= in_min){ + // Lower bound the input to the minimum possible output + return out_min; + } else if(input >= in_max){ + // Upper bound the input to the maximum output + return out_max; + } else{ + // Linear mapping between ranges + uint8_t offset_in = input - in_min; // If input went from A -> B, it now goes from 0 -> B-A + uint8_t in_range = in_max - in_min; // Input range + uint8_t out_range = out_max - out_min; // Output range + uint8_t offset_out = out_min; + return (offset_in * out_range)/in_range + offset_out; // slope = out_range/in_range. y=mx+b so output=slope*offset_in+offset_out + } } /** @@ -308,7 +325,7 @@ static void ForwardDriveHandler(){ UpdateDisplay_SetGear(DISP_FORWARD); } velocitySetpoint = MAX_VELOCITY; - currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, 100, 0, 100)); + currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); } /** @@ -368,7 +385,7 @@ static void ReverseDriveHandler(){ UpdateDisplay_SetGear(DISP_REVERSE); } velocitySetpoint = -MAX_VELOCITY; - currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, 100, 0, 100)); + currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); cruiseEnable = false; onePedalEnable = false; } @@ -495,7 +512,7 @@ static void CoastingCruiseDecider(){ */ static void AccelerateCruiseHandler(){ velocitySetpoint = MAX_VELOCITY; - currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, 100, 0, 100)); + currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); } /** @@ -535,7 +552,7 @@ static void OnePedalDriveHandler(){ if(accelPedalPercent <= ONEPEDAL_BRAKE_THRESHOLD){ // Regen brake: Map 0 -> brake to 100 -> 0 velocitySetpoint = 0; - currentSetpoint = percentToFloat(map(accelPedalPercent, 0, ONEPEDAL_BRAKE_THRESHOLD, 100, 0)); + currentSetpoint = percentToFloat(map(accelPedalPercent, PEDAL_MIN, ONEPEDAL_BRAKE_THRESHOLD, CURRENT_SP_MAX, CURRENT_SP_MIN)); Minion_Write_Output(BRAKELIGHT, true, &minion_err); UpdateDisplay_SetRegenState(DISP_ACTIVE); }else if(ONEPEDAL_BRAKE_THRESHOLD < accelPedalPercent && accelPedalPercent <= ONEPEDAL_NEUTRAL_THRESHOLD){ @@ -547,7 +564,7 @@ static void OnePedalDriveHandler(){ }else if(ONEPEDAL_NEUTRAL_THRESHOLD < accelPedalPercent){ // Accelerate: Map neutral -> 100 to 0 -> 100 velocitySetpoint = MAX_VELOCITY; - currentSetpoint = percentToFloat(map(accelPedalPercent, ONEPEDAL_NEUTRAL_THRESHOLD, 100, 0, 100)); + currentSetpoint = percentToFloat(map(accelPedalPercent, ONEPEDAL_NEUTRAL_THRESHOLD, PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); Minion_Write_Output(BRAKELIGHT, false, &minion_err); UpdateDisplay_SetRegenState(DISP_ENABLED); } From a0cb500674aea6a631d02febf61b4882895d803e Mon Sep 17 00:00:00 2001 From: "Sidharth N. Babu" Date: Sat, 25 Mar 2023 15:16:56 -0500 Subject: [PATCH 044/141] bye bye old sim --- BSP/Simulator/.README.md.swp | Bin 12288 -> 0 bytes BSP/Simulator/Hardware/CAN.py | 75 ---- BSP/Simulator/Hardware/Contactor.py | 35 -- BSP/Simulator/Hardware/Display.py | 73 ---- BSP/Simulator/Hardware/Lights.py | 58 --- BSP/Simulator/Hardware/MotorConErrMessages.py | 57 --- BSP/Simulator/Hardware/MotorController.py | 219 ----------- BSP/Simulator/Hardware/MotorMessage.py | 27 -- BSP/Simulator/Hardware/Pedals.py | 37 -- BSP/Simulator/Hardware/PreCharge.py | 29 -- BSP/Simulator/Hardware/ShiftRegister.py | 164 --------- BSP/Simulator/Hardware/Switches.py | 105 ------ BSP/Simulator/Hardware/UART.py | 43 --- BSP/Simulator/Hardware/simulate.py | 341 ------------------ BSP/Simulator/Makefile | 78 ---- BSP/Simulator/README.md | 32 -- BSP/Simulator/Src/BSP_ADC.c | 101 ------ BSP/Simulator/Src/BSP_CAN.c | 167 --------- BSP/Simulator/Src/BSP_GPIO.c | 96 ----- BSP/Simulator/Src/BSP_SPI.c | 85 ----- BSP/Simulator/Src/BSP_UART.c | 119 ------ 21 files changed, 1941 deletions(-) delete mode 100644 BSP/Simulator/.README.md.swp delete mode 100755 BSP/Simulator/Hardware/CAN.py delete mode 100755 BSP/Simulator/Hardware/Contactor.py delete mode 100755 BSP/Simulator/Hardware/Display.py delete mode 100755 BSP/Simulator/Hardware/Lights.py delete mode 100644 BSP/Simulator/Hardware/MotorConErrMessages.py delete mode 100755 BSP/Simulator/Hardware/MotorController.py delete mode 100755 BSP/Simulator/Hardware/MotorMessage.py delete mode 100755 BSP/Simulator/Hardware/Pedals.py delete mode 100755 BSP/Simulator/Hardware/PreCharge.py delete mode 100644 BSP/Simulator/Hardware/ShiftRegister.py delete mode 100755 BSP/Simulator/Hardware/Switches.py delete mode 100755 BSP/Simulator/Hardware/UART.py delete mode 100755 BSP/Simulator/Hardware/simulate.py delete mode 100644 BSP/Simulator/Makefile delete mode 100644 BSP/Simulator/README.md delete mode 100644 BSP/Simulator/Src/BSP_ADC.c delete mode 100755 BSP/Simulator/Src/BSP_CAN.c delete mode 100644 BSP/Simulator/Src/BSP_GPIO.c delete mode 100644 BSP/Simulator/Src/BSP_SPI.c delete mode 100644 BSP/Simulator/Src/BSP_UART.c diff --git a/BSP/Simulator/.README.md.swp b/BSP/Simulator/.README.md.swp deleted file mode 100644 index 33f6305dca6e7df14c861f88582aa44c3d19c093..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2%Z}Vc6oxA-B5nah5NuB_A~Q|5JCleoiWHs^h%GF52i|}z;Q>HMtXT0M+Z_f*fkie%DoaP*U9LJl|9AeXO?!0q*7|i? zjm|1uFDUi(AMd_@^yrTIrcg@fJd@%7x@6v9y>wM(O*weu_0=ZX;Z^r!;&9`gt>I-; zdTVkwd~17ixSbVsuD!9tt*dKSu3wFcED(o-lN|Nm2`;rHj2`U>$S;&a4F#0kX9 zi2Khe^&{dt#J7ksf)RHSKOa--C&YckONir$U!PU#7sN@#3B)Ui$ummTh)u-zPb>8q z;y2Xr143$fQ|bv;tutlXnKE1A5Zxv4Gf z?(W_jMkDP~8{_*$8Q@uEtfwpM+nXC}cP^b?inXU9`*>*CnS2t(rX179v}d`ZQWxyl zPS|2ZPxtA}N0rS=Pp1bf7d|<&eDN$Ys`C+Tvu_IN(h`>wc_Xu6%$;bP=~2$At$9P& zWt>v4cP+C#)p<^@QptX5>^@c2c#eH$%3iNeah}Edn7Ah5NSCCm3Qw`7-b-oRt!^f! zjEN)TQ>y9_R$+32WZ6V}#`ugK5Lvnv?>IXlfJ)5N(X5rG&PCKdqPxF%gpj@6&0Q4R ziMWR0mVA~oLeL#!kx5$|hB>cSGAf z_Prj&ah{MycfpqiTDnJi?9m4)D$b3QW+w(}nLeyR&8Zd0zzR)yOSsY&?Q7PUMOjL1 zXJrgo+Z*R7bL0%zPy3S9GHD4K^Aw?d4MX4t?2+mTQ)#^P2X*Ij8Zo12t4lX#YdIkU zk3_T%1U5mHLR%_*`{ug1v1zW1$#V}sjb}(j&U57=bqZHAPpKOzmx9N6vB}-GJ?|~0 z-dFD8aOmLin2~mmBRFV?>OO#b+;9@l(C6WDpQdRBuR$o>v(q`bsiSRcM0ZRLKOlRf z5vAI?M1#66q7@@~0LySG$VHS}yfsX$k=V46otp@pta3{30? z=<)+uvz3(rjO}p0QT(?)93Uecz22A2-f-+UCU4tSNQv24c74;tMYTO;NzxO?#S$%SMZ63qs}gUuTa@ zgv+Ia(!hlpmzo-G7XOUkuW~NN&Sbynyvuq}+D2B^GcXpLO8$R4QmD&~ybeeg_G~I> z@+h^IJJY8^z&SYj5TZtAHTS70&qo(tqou|7Rk4j_5yfS~$@0Tn*ex0O{icZzC9^OF z_GFQXdgxxb+wbFCW!sc~xgp;0qs9B`)VV2!lOZ?Z3Fqh?_Pd-!jP4{U!laoB<_ z$Aeyx;dYZdQy@h)#^z;kc8kIQv93^poagw04Jc>C1H0Ew%tKwNi_ML_iQ~D(Ss`km ULB|K&)2&8zv4%Q&@XEdV6Pn43*#H0l diff --git a/BSP/Simulator/Hardware/CAN.py b/BSP/Simulator/Hardware/CAN.py deleted file mode 100755 index 4fec23370..000000000 --- a/BSP/Simulator/Hardware/CAN.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os -import fcntl - -# Path of file -file = "BSP/Simulator/Hardware/Data/CAN.csv" - - -def read(): - """Reads CAN1 bus - Returns: - list: [ID, Message, Length] - """ - # Creates file if it doesn't exist - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, "w"): - pass - message = [] - try: - with open(file, "r") as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX) - csvreader = csv.reader(csvfile) - for row in csvreader: - message.append(row) - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN) - try: - return [message[0][0], message[0][1]] - except IndexError: - return ["", ""] - except Exception: - return ["", ""] - - -def write(id, msg): - """Writes the msg and id to CAN1 - Format: id, msg, msg_length - Doesn't return anything - """ - - # Creates file if it doesn't exist - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, "w"): - pass - - lines = [] - # Grab the current CAN data - try: - with open(file, "r") as csv: - fcntl.flock(csv.fileno(), fcntl.LOCK_EX) - lines = csv.readlines() - except Exception: - pass - - # If the file hasn't been initialzed yet, set the two entries to empty - length = len(lines) - if length < 2: - for i in range(length, 2): - lines.append("\n") - - # Write back the CAN data, modifying the specified one - CANtext = "%s,%s,%d" % (id, msg, round((len(msg) - 2) / 2.0 + 0.1)) - # CANtext = (id + ', ' + msg ', ' + (str)(len(msg))) - with open(file, "w") as csv: - for (i, line) in enumerate(lines): - if i == 0: - csv.write(CANtext) - csv.write("\n") - else: - csv.write(line) - - fcntl.flock(csv.fileno(), fcntl.LOCK_UN) \ No newline at end of file diff --git a/BSP/Simulator/Hardware/Contactor.py b/BSP/Simulator/Hardware/Contactor.py deleted file mode 100755 index cfee95285..000000000 --- a/BSP/Simulator/Hardware/Contactor.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os -import fcntl - -file = "BSP/Simulator/Hardware/Data/GPIO.csv" - -ARRAY_PIN = 1 -MOTOR_PIN = 2 - - -def read(): - """Reads contactor file and returns 1 (on) or 0 (off) - Returns: - list: [motor_state, array_state] - """ - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, "w"): - pass - - states = [] - with open(file, "r") as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX) # Lock file before reading - csvreader = csv.reader(csvfile) - for row in csvreader: - states.append(row) - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN) - try: - states = int(states[2][0]) - except IndexError: - states = 0 - - return [(states >> MOTOR_PIN) & 0x01, (states >> ARRAY_PIN) & 0x01] diff --git a/BSP/Simulator/Hardware/Display.py b/BSP/Simulator/Hardware/Display.py deleted file mode 100755 index 64464d39f..000000000 --- a/BSP/Simulator/Hardware/Display.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os -import fcntl -import struct - -# Path of file -file = "BSP/Simulator/Hardware/Data/UART.csv" - -# Data -data = { - "speed": 0, - "cruise_control_en": 0, - "cruise_control_set": 0, - "regen_en": 0, - "CAN_err": 0, -} - - -def get_display(): - """Getter function for the display keys - - Returns: - list: list of dictionary keys - """ - return data.keys() - - -def read(): - """Reads the UART line - - Returns: - dict: dictionary with filled in values - """ - global data - # Creates file if it doesn't exist - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, "w"): - pass - uart = list() - with open(file, "r") as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX) - csvreader = csv.reader(csvfile) - for row in csvreader: - uart.append(row) - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN) - if len(uart): - uart = uart[0][0] - speed_str = uart[0:8] - - try: - speed_arr = [ - int(uart[0:2], 16), - int(uart[2:4], 16), - int(uart[4:6], 16), - int(uart[6:8], 16), - ] - (speed,) = struct.unpack( - "> 3) & 1 - data["cruise_control_set"] = (flags >> 2) & 1 - data["regen_en"] = (flags >> 1) & 1 - data["CAN_err"] = (flags) & 1 - except Exception: - pass - return data diff --git a/BSP/Simulator/Hardware/Lights.py b/BSP/Simulator/Hardware/Lights.py deleted file mode 100755 index 156a5c5b4..000000000 --- a/BSP/Simulator/Hardware/Lights.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os -import fcntl - -from ShiftRegister import reg - -# Path of file -file = "BSP/Simulator/Hardware/Data/GPIO.csv" - -# Names of lights -lights = [ - "A_CNCTR", - "M_CNCTR", - "CTRL_FAULT", - "LEFT_BLINK", - "RIGHT_BLINK", - "Headlight_ON", - "BPS_FAULT", - "BPS_PWR", - "BrakeLight", - "RSVD_LED", -] - - -def get_lights(): - return lights - - -def read(): - """Reads lights states - - Returns: - int: bit string of light states - """ - # Creates file if it doesn't exist - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, "w"): - pass - # Minion Board First - lights = reg.REGISTER_DATA["GPIOB"] - - states = [] - with open(file, "r") as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX) - csvreader = csv.reader(csvfile) - for row in csvreader: - states.append(row) - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN) - try: - states = int(states[2][0]) - except IndexError: - states = 0 - - lights += (states & 0x80) << 1 # Adds BrakeLight to lights - return lights diff --git a/BSP/Simulator/Hardware/MotorConErrMessages.py b/BSP/Simulator/Hardware/MotorConErrMessages.py deleted file mode 100644 index 306d7f684..000000000 --- a/BSP/Simulator/Hardware/MotorConErrMessages.py +++ /dev/null @@ -1,57 +0,0 @@ -#We open and write to CSV file to simulate CAN read/write. This will put the info in it we need for CAN stuff -#Once this CSV file has the info needed (the values in the flags representing different errors) -#we can run the Test_MotorConErrorMessages.c file and see if the outputs are what we expected, it will use info from the CSV file - -#lines that account for info needed in CSV file -#uint32_t length = BSP_CAN_Read(CAN_2, &id, data); - -#@brief Reads the message on the specified CAN line -#@param id pointer to integer to store the -# message ID that was read -#@param data pointer to integer array to store -# the message in bytes -#@return number of bytes read (0 if unsuccessful) - -#uint8_t BSP_CAN_Read(CAN_t bus, uint32_t* id, uint8_t* data) { -# FILE* fp = fopen(FILE_NAME, "r"); -# if (!fp) { -# printf("CAN not available\n\r"); -# return 0;} - -#write to CAN_2 so this info is here for data: data[8] = {0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x44}; -#write to CAN_2 so this info is here for data: data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x44}; -#write to CAN_2 so this info is here for data: data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40}; -#write to CAN_2 so this info is here for data: data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40}; -#write to CAN_2 so this info is here for data: data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -#write to csv file by hand if BSP functions in c don't read it correctly, but otherwise, BSP functions should read csv files normally -#will the call to BSP_CAN_Read from the Read_MotorController function in MotorController.c read the csv data right? We'll see - -import os.path -import csv -from MotorController import read, write -#import functions that read and write to CAN, is this needed? - -CANFile =open('BSP/Simulator/Hardware/Data/CAN.csv', 'w') #open the file -#CANFile="MotorCon.csv" - -# create the csv writer -CANWriter = csv.writer(CANFile) - -#This section should create the data that BSP_CAN_Read will use for motor messages -# write the initial data to CSV file -#CAN_3 reads line 2, we use this CAN line -#can either rewrite lines in one csv file, or make multiple csv files. Will figure out rewrite later, how to get CAN to read?? - -write(1, 17301572) #all flags -write(1, 524356) #overspeed off -write(1, 524352) -write(1, 64) -write(1, 0) - -# close the file -CANFile.close() - - - - diff --git a/BSP/Simulator/Hardware/MotorController.py b/BSP/Simulator/Hardware/MotorController.py deleted file mode 100755 index 93a41cd2f..000000000 --- a/BSP/Simulator/Hardware/MotorController.py +++ /dev/null @@ -1,219 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os -import fcntl -import CAN -import math - -# Path of file -file = "BSP/Simulator/Hardware/Data/CAN.csv" - - -def sendTouC(): - """Simulates motors sending CAN messages back to the uC - - Returns: - CAN ID of the last message sent - """ - - currentID = CarState.motor_info[CarState.infoIdx] - - if currentID == CarState.VELOCITY_ID: - tx_message = int(CarState.CURRENT_VELOCITY) - tx_message = (tx_message << 32) + int( - (60 * CarState.CURRENT_VELOCITY) / (math.pi * 2 * CarState.radius) - ) - - elif currentID == CarState.MOTOR_BUS_ID: - tx_message = int(CarState.ABSOLUTE_CURRENT) - tx_message = (tx_message << 32) + int(CarState.BUS_VOLTAGE) - - elif currentID == CarState.MOTOR_PHASE_CURRENT_ID: - tx_message = int(CarState.PHASE_C_CUR) - tx_message = (tx_message << 32) + int(CarState.PHASE_B_CUR) - - elif currentID == CarState.MOTOR_VOLTAGE_VECTOR_ID: - tx_message = int(CarState.V_REAL) - tx_message = (tx_message << 32) + int(CarState.V_IMAGINE) - - elif currentID == CarState.MOTOR_CURRENT_VECTOR_ID: - tx_message = int(CarState.I_REAL) - tx_message = (tx_message << 32) + int(CarState.I_IMAGINE) - - elif currentID == CarState.MOTOR_BACKEMF_ID: - tx_message = int(CarState.REAL_COMP) - tx_message = (tx_message << 32) + int(CarState.NEUTRAL_MOTOR) - - elif currentID == CarState.MOTOR_TEMP_ID: - tx_message = int(CarState.PHASEC_TEMP) - tx_message = (tx_message << 32) + int(CarState.INTERNAL_TEMP) - - write(currentID, tx_message) - CarState.infoIdx = (CarState.infoIdx + 1) % 7 # increment index - CarState.last_message = [hex(currentID), hex(tx_message)] - return CarState.last_message - - -def read(): - """Reads last message from CAN2 bus - - Returns: - list: [ID, Message] - """ - return CarState.last_message - - -def write(id_, message): - """Writes message to CAN2 - - Args: - id_ (int): ID of message to be sent - message (int): contents of message to be sent - """ - CAN1 = CAN.read() - with open(file, "w") as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX) - csvwriter = csv.writer(csvfile) - csvwriter.writerow(CAN1) - csvwriter.writerow([hex(id_), hex(message), len(hex(message)[2:]) // 2]) - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN) - - -def confirm_drive(): - """Acts as the motor controller confirming - that the proper message is received periodically. - If the message is received, the motor speed is changed - accordingly. If it is not received, the motor speed stays constant. - - Returns: - tuple: desired and current velocities to display - """ - try: - id_, message, _ = read() - id_ = int(id_, 16) - message = int(message, 16) - if id_ == CarState.MOTOR_DRIVE_ID: - # Read the message and separate - desired_current = (message >> 32) & 0xFFFFFFFF - desired_velocity = message & 0xFFFFFFFF - toggle_torque( - desired_velocity - ) # enable torque control mode if desired_velocity is an extremely large number - # update max available current value - if CarState.mode != 1: - CarState.CURRENT_SETPOINT = CarState.MAX_CURRENT * ( - desired_current / 100.0 - ) - update_velocity(desired_velocity) - # Write the current velocity value - tx_message = int(CarState.CURRENT_VELOCITY) << 32 + int( - CarState.CURRENT_VELOCITY - ) - write(CarState.VELOCITY_ID, tx_message) - return desired_velocity, CarState.CURRENT_VELOCITY - else: - return CarState.CURRENT_VELOCITY, CarState.CURRENT_VELOCITY - except ValueError: - return CarState.CURRENT_VELOCITY, CarState.CURRENT_VELOCITY - - -def toggle_torque(velocity): - if velocity > 1000: - CarState.mode = 1 - else: - CarState.mode = 0 - - -def torque_control(pedalPercent): - # following code will only execute if motor is in torque control mode - if CarState.mode == 1: - CarState.CURRENT_SETPOINT = ( - pedalPercent * CarState.MAX_CURRENT - ) # param will be a value from 0.0 to 1.0 - CarState.velocity_increase = CarState.CURRENT_SETPOINT # update rate - - -def update_velocity(v): - """Acts as the motor controller increasing - the speed of the motor - - Args: - v (float): desired velocity received by the Controls system - """ - - if CarState.CURRENT_VELOCITY < v: - CarState.CURRENT_VELOCITY += CarState.velocity_increase - elif CarState.CURRENT_VELOCITY > v: - CarState.CURRENT_VELOCITY -= 0.5 - - -# Class that holds the global constants and variables of the car state -class CarState: - # Relevant IDs - MOTOR_DRIVE_ID = 0x221 - VELOCITY_ID = 0x243 - MOTOR_POWER_ID = 0x222 - MOTOR_BUS_ID = 0x242 - MOTOR_PHASE_CURRENT_ID = 0x244 - MOTOR_VOLTAGE_VECTOR_ID = 0x245 - MOTOR_CURRENT_VECTOR_ID = 0x246 - MOTOR_BACKEMF_ID = 0x247 - MOTOR_TEMP_ID = 0x24B - - motor_info = [ - MOTOR_BUS_ID, - VELOCITY_ID, - MOTOR_PHASE_CURRENT_ID, - MOTOR_VOLTAGE_VECTOR_ID, - MOTOR_CURRENT_VECTOR_ID, - MOTOR_BACKEMF_ID, - MOTOR_TEMP_ID, - ] - - # Last message - last_message = None - - # Index - infoIdx = 0 - - radius = 21.67 # in inches - - # State values - CURRENT_VELOCITY = 0 - - BUS_VOLTAGE = 5 - - # Phase Currents - PHASE_C_CUR = 1 - PHASE_B_CUR = 1 - - # Voltage Vectors - V_REAL = 0 - V_IMAGINE = 0 - - # Current Vectors - I_REAL = 0 - I_IMAGINE = 0 - - # Motor BackEMF components - REAL_COMP = 0 - NEUTRAL_MOTOR = 0 - - # Temperature - PHASEC_TEMP = 0 - INTERNAL_TEMP = 0 - - mode = 0 # 0 = Velocity control mode, 1 = Torque control mode - - velocity_increase = ( - 0.5 # how much CURRENT_VELOCITY is increased by in update_velocity() - ) - - CURRENT_SETPOINT = 0.0 # set by user via MOTOR_DRIVE commands - - MAX_CURRENT = ( - 1.0 # max available current, this is a percent of the Absolute bus current - ) - - ABSOLUTE_CURRENT = 5.0 # physical limitation diff --git a/BSP/Simulator/Hardware/MotorMessage.py b/BSP/Simulator/Hardware/MotorMessage.py deleted file mode 100755 index 69d681f6d..000000000 --- a/BSP/Simulator/Hardware/MotorMessage.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os - -from CAN import write - -SAFE = 1 -UNSAFE = 0 - -def sendMotorDisable(message): - """ Simulates BPS by sending a message over CAN1 - saying whether or not it is safe to turn on the motor. - Sends the MOTOR_DISABLE command with disable/enable argument. - message==1 means that it is safe to turn on the motor, - message==0 means that the motor should be turned off, - and all other messages are ignored. - """ - - MDCommand = hex(266) - - write(MDCommand, hex(message)) - - - - - diff --git a/BSP/Simulator/Hardware/Pedals.py b/BSP/Simulator/Hardware/Pedals.py deleted file mode 100755 index 2a179ccca..000000000 --- a/BSP/Simulator/Hardware/Pedals.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import os -import csv -import fcntl - -# Path of file -file = "BSP/Simulator/Hardware/Data/Pedals.csv" - - -def set_pedals(accel_pos, brake_pos): - """Sets the accelerator and brake pedals to the - specified position between zero and one - - Args: - accel_pos (float): the position of the accelerator pedal - brake_pos (float): the position of the brake pedal - """ - # Create the file if it doesn't exist yet - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, 'w'): - pass - accel_value = int(float(accel_pos) * 4096) # ADC conversion - brake_value = int(float(brake_pos) * 4096) # ADC conversion - # The slider goes from 0.0 to 1.0, but we want to cap the ADC value at 4095 - if accel_value == 4096: - accel_value = 4095 - if brake_value == 4096: - brake_value = 4095 - - states = [accel_value, brake_value] - with open(file, "w") as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX) - csvreader = csv.writer(csvfile) - csvreader.writerow(states) - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN) diff --git a/BSP/Simulator/Hardware/PreCharge.py b/BSP/Simulator/Hardware/PreCharge.py deleted file mode 100755 index e3973066d..000000000 --- a/BSP/Simulator/Hardware/PreCharge.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import os -import csv -import fcntl - -file = "BSP/Simulator/Hardware/Data/GPIO.csv"; - -def read(): - os.makedirs(os.path.dirname(file), exist_ok = True); - if not os.path.exists(file): - open(file, 'w') - with open(file, 'w'): - pass - - with open(file, 'r') as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX); - try: - csvreader = csv.reader(csvfile); - next(csvreader) # skip first line - next(csvreader) # skip second line - charges = next(csvreader); - except StopIteration: - charges = [0]; - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN); - states = [0, 0] - states[0] = (int(charges[0]) % 2) - states[1] = ((int(charges[0])>>3) % 2) - return states diff --git a/BSP/Simulator/Hardware/ShiftRegister.py b/BSP/Simulator/Hardware/ShiftRegister.py deleted file mode 100644 index 8a889921e..000000000 --- a/BSP/Simulator/Hardware/ShiftRegister.py +++ /dev/null @@ -1,164 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os -import fcntl - -# Path of file -file = "BSP/Simulator/Hardware/Data/SPI.csv" - - -class ShiftRegister: - OPCODE = 0b0100000 - REGISTER_DATA = { - "IODIRA": 0xFF, - "IODIRB": 0xFF, - "IPOLA": 0x00, - "IPOLB": 0x00, - "GPINTENA": 0x00, - "GPINTENB": 0x00, - "DEFVALA": 0x00, - "DEFVALB": 0x00, - "INTCONA": 0x00, - "INTCONB": 0x00, - "IOCON": 0x80, - "GPPUA": 0x00, - "GPPUB": 0x00, - "INTFA": 0x00, - "INTFB": 0x00, - "INTCAPA": 0x00, - "INTCAPB": 0x00, - "GPIOA": 0x00, - "GPIOB": 0x00, - "OLATA": 0x00, - "OLATB": 0x00, - } - # Addresses with IOCON.BANK = 1 - REGISTER_ADDR_1 = { - 0x00: "IODIRA", - 0x10: "IODIRB", - 0x01: "IPOLA", - 0x11: "IPOLB", - 0x02: "GPINTENA", - 0x12: "GPINTENB", - 0x03: "DEFVALA", - 0x13: "DEFVALB", - 0x04: "INTCONA", - 0x14: "INTCONB", - 0x05: "IOCON", - 0x15: "IOCON", - 0x06: "GPPUA", - 0x16: "GPPUB", - 0x07: "INTFA", - 0x17: "INTFB", - 0x08: "INTCAPA", - 0x18: "INTCAPB", - 0x09: "GPIOA", - 0x19: "GPIOB", - 0x0A: "OLATA", - 0x1A: "OLATB", - } - # Addresses with IOCON.BANK = 0 - REGISTER_ADDR_0 = { - 0x00: "IODIRA", - 0x01: "IODIRB", - 0x02: "IPOLA", - 0x03: "IPOLB", - 0x04: "GPINTENA", - 0x05: "GPINTENB", - 0x06: "DEFVALA", - 0x07: "DEFVALB", - 0x08: "INTCONA", - 0x09: "INTCONB", - 0x0A: "IOCON", - 0x0B: "IOCON", - 0x0C: "GPPUA", - 0x0D: "GPPUB", - 0x0E: "INTFA", - 0x0F: "INTFB", - 0x10: "INTCAPA", - 0x11: "INTCAPB", - 0x12: "GPIOA", - 0x13: "GPIOB", - 0x14: "OLATA", - 0x15: "OLATB", - } - - REGISTER_ADDR = [REGISTER_ADDR_0, REGISTER_ADDR_1] - - def write_register(self, register_addr, data): - register = self.REGISTER_ADDR[(self.REGISTER_DATA["IOCON"] & 0x80) >> 7][ - register_addr - ] - if register[0:-1] == "GPIO": - # Make sure only inputs are written - io = self.REGISTER_DATA[f"IODIR{register[-1]}"] - oldData = self.REGISTER_DATA[f"GPIO{register[-1]}"] - newData = 0 - for i in range(8): - if (io >> i) & 0x01 == 1: - newData += data & (0x01 << i) - else: - newData += oldData & (0x01 << i) - self.REGISTER_DATA[f"GPIO{register[-1]}"] = newData - else: - self.REGISTER_DATA[register] = data - - def read_register(self, register_addr): - return self.REGISTER_DATA[ - self.REGISTER_ADDR[(self.REGISTER_DATA["IOCON"] & 0x80) >> 7][register_addr] - ] - - -# Global register -reg = ShiftRegister() - - -def read_spi(): - # Creates file if it doesn't exist - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, "w"): - pass - data = None - message = None - with open(file, "r") as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX) - csvreader = csv.reader(csvfile) - try: - message = bin(int(next(csvreader)[0], 16))[2:] - diff = 24 - len(message) - message = "0" * diff + message # ZEXT - except StopIteration: - message = None - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN) - if message: - # Check proper opcode - if int(message[0:7], 2) == reg.OPCODE: - addr = int(message[8:16], 2) - data = int(message[16:], 2) - if int(message[7], 2) == 0: - # Write - reg.write_register(addr, data) - # Clear CSV - with open(file, "w"): - pass - else: - # Read - try: - data = reg.read_register(addr) - except KeyError: - print("Invalid register access. Make sure to initialize properly") - write_spi(data) - - -def write_spi(data): - with open(file, "w") as csvfile: - fcntl.flock(csvfile.fileno(), fcntl.LOCK_EX) - csvreader = csv.writer(csvfile) - csvreader.writerow([hex(data)[2:]]) - fcntl.flock(csvfile.fileno(), fcntl.LOCK_UN) - - -if __name__ == "__main__": - read_spi() diff --git a/BSP/Simulator/Hardware/Switches.py b/BSP/Simulator/Hardware/Switches.py deleted file mode 100755 index b8e80ca13..000000000 --- a/BSP/Simulator/Hardware/Switches.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os -import fcntl -import tkinter as tk -from ShiftRegister import reg - -# Path of file -file = "BSP/Simulator/Hardware/Data/GPIO.csv" - -# Names of switches -switches = ["CRUZ_ST", "CRUZ_EN", "HZD_SQ", "FR_SW", "Headlight_SW", "LEFT_SW", "RIGHT_SW", "REGEN", "IGN_1", "IGN_2","REV_SW"] - - -def get_switches(): - return switches - - -def toggle(switch, gui): - """Toggles a specified switch state - Args: - switch (string): name of the switch to toggle - gui (tk.Button list): Button object list - """ - states = read() - for i, sw in enumerate(switches): - if sw == switch: - states ^= 1< 8: - revState = (states & 1<<10)>>10 - ignStates = states & 3<<8 - writeGPIO(ignStates) - reg.REGISTER_DATA["GPIOB"] = reg.REGISTER_DATA["GPIOB"]|revState<<7 - reg.REGISTER_DATA["GPIOA"]=states & 0x0FF - else: - writeGPIO(0) - reg.REGISTER_DATA["GPIOB"] = reg.REGISTER_DATA["GPIOB"] & 0x7F - reg.REGISTER_DATA["GPIOA"]=states - - -def read(): - """Reads switch states - - Returns: - int: bit string of switch states - """ - # should be updated to also pull GPIO for Ignition - gpioStates = readGPIO() - states = reg.REGISTER_DATA["GPIOA"] - revState = (reg.REGISTER_DATA["GPIOB"] & 0x80)>>7 - states = states|revState<<10 - states = states|gpioStates<<8 - return states - -def writeGPIO(ignStates): - # Creates file if it doesn't exist - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, 'w'): - pass - - lines = [] - # Grab the current GPIO data - with open(file, "r") as csv: - fcntl.flock(csv.fileno(), fcntl.LOCK_EX) - lines = csv.readlines() - - #If the file hasn't been initialzed yet, set the two entries to empty - length = len(lines) - if length < 4: - for i in range(length,2): - lines.append('\n') - - - with open(file, "w") as csv: - for (i, line) in enumerate(lines): - if i == 0: - csv.write(str(ignStates>>8)) - csv.write('\n') - else: - csv.write(line) - - fcntl.flock(csv.fileno(), fcntl.LOCK_UN) - -def readGPIO(): - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, 'w'): - pass - - lines = [] - # Grab the current GPIO data - with open(file, "r") as csv: - fcntl.flock(csv.fileno(), fcntl.LOCK_EX) - lines = csv.readlines() - return int(lines[0]) diff --git a/BSP/Simulator/Hardware/UART.py b/BSP/Simulator/Hardware/UART.py deleted file mode 100755 index 6ab8eebeb..000000000 --- a/BSP/Simulator/Hardware/UART.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import csv -import os -import fcntl - -# path to the file -file = "BSP/Simulator/Hardware/Data/UART.csv" - - -def write(msg): - """ Writes the message to UART_2 - Doesn't return anything - """ - - # Creates file if it doesn't exist - os.makedirs(os.path.dirname(file), exist_ok=True) - if not os.path.exists(file): - with open(file, 'w'): - pass - - lines = [] - # Grab the current UART data - with open(file, "r") as csv: - fcntl.flock(csv.fileno(), fcntl.LOCK_EX) - lines = csv.readlines() - - # If the file hasn't been initialzed yet, set the two entries to empty - length = len(lines) - if length < 2: - for i in range(length,2): - lines.append('\n') - - # Write back the UART data, modifying the specified one - with open(file, "w") as csv: - for (i, line) in enumerate(lines): - if i == 1: - csv.write(msg) - csv.write('\n') - else: - csv.write(line) - - fcntl.flock(csv.fileno(), fcntl.LOCK_UN) diff --git a/BSP/Simulator/Hardware/simulate.py b/BSP/Simulator/Hardware/simulate.py deleted file mode 100755 index 5fbc94a11..000000000 --- a/BSP/Simulator/Hardware/simulate.py +++ /dev/null @@ -1,341 +0,0 @@ -# Copyright (c) 2020 UT Longhorn Racing Solar - -import os -import tkinter as tk -from functools import partial - -import Switches -import Contactor -import Pedals -import Display -import CAN -import MotorController -import UART -import Lights -import PreCharge -import ShiftRegister -import MotorMessage - - -# Update Frequencies (ms) -SHIFTREG_FREQ = 10 -MOTOR_FREQ = 250 -CAN1_FREQ = 500 -CONTACTOR_FREQ = 500 -DISPLAY_FREQ = 500 -LIGHTS_FREQ = 500 -PRECHARGE_FREQ = 500 -MOTOR_DISABLE_FREQ = 500 - - -def update_contactors(): - """Periodically update the display state of the Motor and Array Contactors""" - global motor_status, array_status - contactors_status = Contactor.read() - motor_status.set(f"Motor Contactor: {contactors_status[0]}") - array_status.set(f"Array Contactor: {contactors_status[1]}") - window.after(CONTACTOR_FREQ, update_contactors) - - -def update_display(): - """Periodically update the display state of display""" - global display_text - display = Display.read() - for i, text in enumerate(display.keys()): - display_text[i].set(f"{text}: {display[text]}") - window.after(DISPLAY_FREQ, update_display) - - -def update_CAN(): - """Periodically update the display state of the CAN bus""" - global id_text, message_text - can = CAN.read() - - id_text.set(f"ID: {can[0]}") - message_text.set(f"Message: {can[1]}") - - window.after(CAN1_FREQ, update_CAN) - - -def update_CAN2(): - """Periodally update the display state of the CAN2 bus""" - global id_text2, message_text2 - can2 = MotorController.sendTouC() - id_text2.set(f"ID: {can2[0]}") - message_text2.set(f"Message: {can2[1]}") - window.after(MOTOR_FREQ, update_CAN2) - - -def update_motor(): - """Periodically update the velocity and display of the motor""" - global desired_velocity_text, current_velocity_text - desired_velocity, current_velocity = MotorController.confirm_drive() - desired_velocity_text.set(f"Desired Velocity: {round(desired_velocity, 3)} m/s") - current_velocity_text.set(f"Current Velocity: {round(current_velocity, 3)} m/s") - MotorController.torque_control(accelerator.get()) - window.after(MOTOR_FREQ, update_motor) - - -def update_precharge(): - """Periodically update the display state of the Motor and Array precharge boards""" - global precharge_motor_status, precharge_array_status - precharge_status = PreCharge.read() - precharge_motor_status.set(f"Motor Precharge: {precharge_status[1]}") - precharge_array_status.set(f"Array Precharge: {precharge_status[0]}") - window.after(PRECHARGE_FREQ, update_precharge) - - -def update_lights(): - """Periodically update the display state of the lights""" - global lights_text - lights_state = Lights.read() - lights = Lights.get_lights() - for i, light in enumerate(lights_text): - light.set(f"{lights[i]}: {(lights_state >> i) & 0x01}") - window.after(LIGHTS_FREQ, update_lights) - - -def update_MotorDisable(): - """Sends MOTOR_DISABLE message when checkbox is checked/unchecked""" - MotorMessage.sendMotorDisable(chargingBool.get()) - window.after(MOTOR_DISABLE_FREQ, update_MotorDisable) - - -def update_shift(): - ShiftRegister.read_spi() - window.after(SHIFTREG_FREQ, update_shift) - - -# Sets up the display environment variable -if os.environ.get("DISPLAY", "") == "": - os.environ.__setitem__("DISPLAY", ":0") - -# Sets up window -window = tk.Tk() -window.rowconfigure([0, 1], minsize=200, weight=1) -window.columnconfigure([0, 1, 2, 3, 4, 5], minsize=200, weight=1) - -# Sets up frames -button_frame = tk.LabelFrame(master=window, text="Switches") -button_frame_rows = [0, 1, 2, 3] -button_frame_columns = [0, 1, 2] -button_frame.rowconfigure(button_frame_rows, minsize=50, weight=1) -button_frame.columnconfigure(button_frame_columns, minsize=100, weight=1) -button_frame.grid(row=0, column=0, sticky="nsew") - -pedal_frame = tk.LabelFrame(master=window, text="Pedals") -pedal_frame.rowconfigure([0], minsize=50, weight=1) -pedal_frame.columnconfigure([0, 1], minsize=100, weight=1) -pedal_frame.grid(row=0, column=1, sticky="nsew") - -display_frame = tk.LabelFrame(master=window, text="Display") -display_frame_rows = [0, 1, 2, 3, 4] -display_frame_columns = [0] -display_frame.rowconfigure(display_frame_rows, minsize=50, weight=1) -display_frame.columnconfigure(display_frame_columns, minsize=100, weight=1) -display_frame.grid(row=0, column=2, sticky="nsew") - -cans_frame = tk.Frame(master=window) -cans_frame_rows = [0, 1] -cans_frame_columns = [0] -cans_frame.rowconfigure(cans_frame_rows, minsize=50, weight=1) -cans_frame.columnconfigure(cans_frame_columns, minsize=100, weight=1) -cans_frame.grid(row=1, column=0, sticky="nsew") - -can_frame = tk.LabelFrame(master=cans_frame, text="CAN") -can_frame_rows = [0, 1] -can_frame_columns = [0] -can_frame.rowconfigure(can_frame_rows, minsize=50, weight=1) -can_frame.columnconfigure(can_frame_columns, minsize=100, weight=1) -can_frame.grid(row=0, column=0, sticky="nsew") - -can2_frame = tk.LabelFrame(master=cans_frame, text="CAN2") -can2_frame_rows = [0, 1] -can2_frame_columns = [0] -can2_frame.rowconfigure(can2_frame_rows, minsize=50, weight=1) -can2_frame.columnconfigure(can2_frame_columns, minsize=100, weight=1) -can2_frame.grid(row=1, column=0, sticky="nsew") - -CAN_messages_frame = tk.LabelFrame(master=window, text="CAN System Messages") -CAN_messages_frame_rows = [0, 1] -CAN_messages_frame_columns = [0] -CAN_messages_frame.rowconfigure(CAN_messages_frame_rows, minsize=20, weight=1) -CAN_messages_frame.columnconfigure(CAN_messages_frame_columns, minsize=20, weight=1) -CAN_messages_frame.grid(row=0, column=4, sticky="nsew") - -motor_frame = tk.LabelFrame(master=window, text="Motor") -motor_frame_rows = [0, 1] -motor_frame_columns = [0] -motor_frame.rowconfigure(motor_frame_rows, minsize=50, weight=1) -motor_frame.columnconfigure(motor_frame_columns, minsize=100, weight=1) -motor_frame.grid(row=1, column=1, sticky="nsew") - -contactor_frame = tk.LabelFrame(master=window, text="Contactors") -contactor_frame_rows = [0, 1] -contactor_frame_columns = [0] -contactor_frame.rowconfigure(contactor_frame_rows, minsize=50, weight=1) -contactor_frame.columnconfigure(contactor_frame_columns, minsize=50, weight=1) -contactor_frame.grid(row=1, column=2, sticky="nsew") - -messages_frame = tk.LabelFrame(master=window, text="Controls System Messages") -messages_frame_rows = [0, 1] -messages_frame_columns = [0] -messages_frame.rowconfigure(messages_frame_rows, minsize=20, weight=1) -messages_frame.columnconfigure(messages_frame_columns, minsize=20, weight=1) -messages_frame.grid(row=0, column=3, sticky="nsew") - -precharge_frame = tk.LabelFrame(master=window, text="PreCharge") -precharge_frame_rows = [0, 1] -precharge_frame_columns = [0] -precharge_frame.rowconfigure(precharge_frame_rows, minsize=50, weight=1) -precharge_frame.columnconfigure(precharge_frame_columns, minsize=50, weight=1) -precharge_frame.grid(row=1, column=3, sticky="nsew") - -lights_frame = tk.LabelFrame(master=window, text="Lights") -lights_frame_rows = [0, 1, 2, 3, 4] -lights_frame_columns = [0, 1] -lights_frame.rowconfigure(lights_frame_rows, minsize=50, weight=1) -lights_frame.columnconfigure(lights_frame_columns, minsize=50, weight=1) -lights_frame.grid(row=1, column=4, sticky="nsew") - - -charging_frame = tk.LabelFrame(master=window, text="Charging") -charging_frame_rows = [0] -charging_frame_columns = [0] -charging_frame.rowconfigure(charging_frame_rows, minsize=50, weight=0) -charging_frame.columnconfigure(charging_frame_columns, minsize=100, weight=0) -charging_frame.grid(row=0, column=5, sticky="nsew") - -### Switches ### -buttons = [] -for i, switch in enumerate(Switches.get_switches()): - button = tk.Button(master=button_frame, text=switch) - button.grid( - row=i // len(button_frame_columns), - column=i % len(button_frame_columns), - sticky="nsew", - ) - buttons.append(button) -for i, switch in enumerate(Switches.get_switches()): - buttons[i].config(command=partial(Switches.toggle, switch, buttons)) - -### Lights ### -lights_text = list() -for i, light in enumerate(Lights.get_lights()): - light_text = tk.StringVar(value=f"{light}: ") - light = tk.Label(master=lights_frame, textvar=light_text) - light.grid( - row=i // len(lights_frame_columns), - column=i % len(lights_frame_columns), - sticky="nsew", - ) - lights_text.append(light_text) - -### Contactors ### -motor_status = tk.StringVar(value="Motor Contactor: ") -motor_ = tk.Label(master=contactor_frame, textvariable=motor_status) -motor_.grid(row=0, column=0, sticky="nsew") -array_status = tk.StringVar(value="Array Contactor: ") -array_txt = tk.Label(master=contactor_frame, textvariable=array_status) -array_txt.grid(row=1, column=0, sticky="nsew") - - -### Pedals ### -accelerator = tk.Scale( - pedal_frame, from_=1, to=0, resolution=0.001, label="accelerator" -) -accelerator.grid(row=0, column=0, sticky="nsew") -brake = tk.Scale(pedal_frame, from_=1, to=0, resolution=0.001, label="brake") -brake.grid(row=0, column=1, sticky="nsew") - -accelerator.configure(command=lambda pos: Pedals.set_pedals(pos, brake.get())) -brake.configure(command=lambda pos: Pedals.set_pedals(accelerator.get(), pos)) - -### Display ### -display_text = list() -for i, label in enumerate(Display.get_display()): - text = tk.StringVar(value=label) - display_text.append(text) - cell = tk.Label(master=display_frame, textvariable=text) - cell.grid( - row=i // len(display_frame_columns), - column=i % len(display_frame_columns), - sticky="nsew", - ) - -### CAN ### -id_text = tk.StringVar(value="ID: ") -id_ = tk.Label(master=can_frame, textvariable=id_text) -id_.grid(row=0, column=0, sticky="nsew") -message_text = tk.StringVar(value="Message: ") -message = tk.Label(master=can_frame, textvariable=message_text) -message.grid(row=1, column=0, sticky="nsew") - -### CAN2 ### -id_text2 = tk.StringVar(value="ID: ") -id2_ = tk.Label(master=can2_frame, textvariable=id_text2) -id2_.grid(row=0, column=0, sticky="nsew") -message_text2 = tk.StringVar(value="Message: ") -message2 = tk.Label(master=can2_frame, textvariable=message_text2) -message2.grid(row=1, column=0, sticky="nsew") - -### CAN messages input ### -can_id_input = tk.Entry(master=CAN_messages_frame) -can_id_input.grid(row=0, column=0) -can_msg_input = tk.Entry(master=CAN_messages_frame) -can_msg_input.grid(row=1, column=0) -can_button = tk.Button( - master=CAN_messages_frame, - text="Send", - command=lambda: CAN.write(can_id_input.get(), can_msg_input.get()), -) -can_button.grid(row=2, column=0) - -### Motor ### -desired_velocity_text = tk.StringVar(value="Desired Velocity: ") -desired_velocity = tk.Label(master=motor_frame, textvariable=desired_velocity_text) -desired_velocity.grid(row=0, column=0, sticky="nsew") -current_velocity_text = tk.StringVar(value="Current Velocity: ") -current_velocity = tk.Label(master=motor_frame, textvariable=current_velocity_text) -current_velocity.grid(row=1, column=0, sticky="nsew") - -### Precharge ### -precharge_motor_status = tk.StringVar(value="Motor Precharge: ") -precharge_motor_ = tk.Label(master=precharge_frame, textvariable=precharge_motor_status) -precharge_motor_.grid(row=0, column=0, sticky="nsew") -precharge_array_status = tk.StringVar(value="Array Precharge: ") -precharge_array_txt = tk.Label( - master=precharge_frame, textvariable=precharge_array_status -) -precharge_array_txt.grid(row=1, column=0, sticky="nsew") - -### UART messages input ### -uart_input = tk.Entry(master=messages_frame) -uart_input.grid(row=0, column=0) -uart_button = tk.Button( - master=messages_frame, text="Send", command=lambda: UART.write(uart_input.get()) -) -uart_button.grid(row=1, column=0) - -### Charging Checkbox ### -chargingBool = tk.BooleanVar() -chargingBool.set(0) -charging_checkbox = tk.Checkbutton( - master=charging_frame, - text="Charging? Check if Yes", - command=update_MotorDisable, - variable=chargingBool, -) -charging_checkbox.grid(row=0, sticky="nsew") - -# Sets up periodic updates -can_frame.after(CAN1_FREQ, update_CAN) -can2_frame.after(MOTOR_FREQ, update_CAN2) -contactor_frame.after(CONTACTOR_FREQ, update_contactors) -display_frame.after(DISPLAY_FREQ, update_display) -motor_frame.after(MOTOR_FREQ, update_motor) -lights_frame.after(LIGHTS_FREQ, update_lights) -precharge_frame.after(PRECHARGE_FREQ, update_precharge) -charging_frame.after(MOTOR_DISABLE_FREQ, update_MotorDisable) -window.after(SHIFTREG_FREQ, update_shift) -window.mainloop() diff --git a/BSP/Simulator/Makefile b/BSP/Simulator/Makefile deleted file mode 100644 index 2a8eb34d2..000000000 --- a/BSP/Simulator/Makefile +++ /dev/null @@ -1,78 +0,0 @@ -###################################### -# Target -###################################### -TARGET = controls-simulator.out -TARGET_PATH = ../.. - -###################################### -# GCC -###################################### -CC = gcc - -###################################### -# Source -###################################### -SRC = $(wildcard Src/*.c) # BSP code - -SRC += \ -$(wildcard ../../Drivers/Src/*.c) # Driver code - -ifneq ($(TEST), none) -TEST_FILE := Test_$(TEST).c -SRC += \ -$(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) \ -$(wildcard ../../Tests/$(TEST_FILE)) # Apps (not main) -else -SRC += $(wildcard ../../Apps/Src/*.c) # Apps (with main) -endif - -SRC += \ -$(wildcard ../../RTOS/uCOS-III-Simulator/uC-CPU/*.c) \ -$(wildcard ../../RTOS/uCOS-III-Simulator/uC-CPU/Posix/GNU/*.c) \ -$(wildcard ../../RTOS/uCOS-III-Simulator/uC-LIB/*.c) \ -$(wildcard ../../RTOS/uCOS-III-Simulator/uCOS-III/Source/*.c) \ -$(wildcard ../../RTOS/uCOS-III-Simulator/uCOS-III/Ports/POSIX/GNU/*.c) # RTOS - -###################################### -# Objects -###################################### -BUILD_DIR = ../../Objects -OBJ = $(addprefix $(BUILD_DIR)/,$(notdir $(SRC:.c=.o))) # Create object file list -vpath %.c $(sort $(dir $(SRC))) # In case files aren't found - -###################################### -# Flags -###################################### -INC_DIR = \ --I../../Apps/Inc \ --I../../Drivers/Inc \ --I../../BSP/Inc \ --I../../Config/Inc \ --I../../RTOS/uCOS-III-Simulator/uC-CPU \ --I../../RTOS/uCOS-III-Simulator/uC-CPU/Posix/GNU \ --I../../RTOS/uCOS-III-Simulator/uC-LIB \ --I../../RTOS/uCOS-III-Simulator/uCOS-III/Source \ --I../../RTOS/uCOS-III-Simulator/uCOS-III/Ports/POSIX/GNU \ - -LIB = -lm -lpthread # Standard libraries used - -FLAGS = -Wall -g -std=c11 $(INC_DIR) - -###################################### -# Defines -###################################### -DEF = -D_XOPEN_SOURCE=600 -DSIMULATOR - -###################################### -# Build -###################################### -all: $(TARGET_PATH)/$(TARGET) - -$(TARGET_PATH)/$(TARGET): $(OBJ) $(BUILD_DIR) - $(CC) -o $@ $(OBJ) $(FLAGS) $(LIB) - -$(BUILD_DIR)/%.o: %.c $(BUILD_DIR) - $(CC) -c -o $@ $< $(FLAGS) $(DEF) - -$(BUILD_DIR): - mkdir $@ diff --git a/BSP/Simulator/README.md b/BSP/Simulator/README.md deleted file mode 100644 index cc51e9a85..000000000 --- a/BSP/Simulator/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Simulator -This simulator uses a tkinter GUI to allow us to interact with the simulated car - -## Setup -The Controls system can be developed and tested using either Linux or WSL, and there are some differences in the setup - -### Common -Run the following command in the terminal to install tkinter - -```sudo apt-get install python3-tk``` - -Also, make sure you are running with python3.6+ (python3.8 is recommended) - -### Linux -There should not be any additional steps to take for Linux since the DISPLAY environment variable should be set properly - -### WSL -There are a few extra steps to take for WSL, and a few more if you are running WSL2 (until the issues are fixed, hopefully). We will start with the common steps for both. Run the following command - -```sudo apt-get install x11-apps``` - -Then, install [VcXsrv](https://sourceforge.net/projects/vcxsrv/), which is an Xserver for Windows. You will have to run **XLaunch** before running the simulator each time. It will run in the system tray. - -#### WSL2 -Since WSL2 is so new, there are a few features that have not properly been transferred over. In order for the GUI to work for WSL2, there are a few extra steps. - -1. Add a launch parameter to XLaunch - - Find the file location of XLaunch.exe, Right Click and press **Properties**, in the **Target** field add ``` -ac``` after the closing double quotes -2. Allow VcXsrv through the Windows Firewall - - Launch **Firewall & network protection**, click **Allow an app through firewall**, check both public and private boxes for VcXsrv windows xserver -3. Set the DISPLAY environment variable - - Add the following line to your ```~/.bashrc```: ```export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0``` diff --git a/BSP/Simulator/Src/BSP_ADC.c b/BSP/Simulator/Src/BSP_ADC.c deleted file mode 100644 index bbb43b62f..000000000 --- a/BSP/Simulator/Src/BSP_ADC.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (c) 2020 UT Longhorn Racing Solar */ - -/** - * C file that reads the raw ADC data from the CSV file, - * converts it back to a distance pressed (percentage for now), and stores both. - * We should be able to request both the raw ADC data, - * the distance (percentage for now) and millivolts from this library. - */ - -// NOTE: ADC precision is 12 bits (4096), range 3.3V -// I'm assuming 3.3V corresponds to a 100% pressed pedal - -#include "BSP_ADC.h" - -#define FILE_NAME DATA_PATH(PEDALS_CSV) - -/** - * @brief Confirms that the CSV file - * has been created and prints and - * error message if not - * @param pedal the pedal to initialize the ADC for - * (not used for the simulator) - * @return None - */ -void BSP_ADC_Init(void) { - // Checking if file exists - if(access(FILE_NAME, F_OK) != 0){ - // File doesn't exist if true - perror(PEDALS_CSV); - exit(EXIT_FAILURE); - } -} - -/** - * @brief Helper function which returns a - * millivoltage based on the raw ADC value - * compared to the 3.3 volt range of the - * pedals' potentiometers - * @param rawADCvalue ADC data value before conversion - * @return millivolts - */ -static int16_t convert_ADC_to_Voltage(int16_t rawADCValue){ - return ((int32_t)rawADCValue)*ADC_RANGE_MILLIVOLTS >> ADC_PRECISION_BITS; -} - -/** - * @brief Helper function that reads all of the ADC values - * from a file with raw values provided - * by the ADC and stores all values in local - * array of max capacity 10 - * @param rawADCValues pointer to array that contains the ADC values in the array - * @return None - */ -static void read_ADC_Values(int16_t *rawADCValues) { - // Opening file in read mode - FILE *filePointer = fopen(FILE_NAME, "r"); - // Lock file - int fno = fileno(filePointer); - flock(fno, LOCK_EX); - for(int i = 0; i < MAX_CHANNELS; i++){ - // If the file doesn't contain any more values, stop early - if (fscanf(filePointer,"%hd,", &(rawADCValues[i])) <= 0) break; - } - // Closing the file - flock(fno, LOCK_UN); - fclose(filePointer); -} - -/** - * @brief Reads the raw ADC value of the specified device - * @param hardwareDevice pedal enum that represents the specific device - * @return Raw ADC value without conversion - */ -int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice){ - // Array we'll use to get all the values from csv file - int16_t rawADCValues[MAX_CHANNELS]; - // Reading all values and storing them in an int array - read_ADC_Values(rawADCValues); - // Checking if hardwareDevice is out of bounds - if(hardwareDevice > NUMBER_OF_CHANNELS - 1 || hardwareDevice < 0){ - //throwing an error - fprintf(stderr, "Argument passed doesn't exit in ADC file\n"); - exit(EXIT_SUCCESS); - } - int16_t rawADCValue = rawADCValues[hardwareDevice]; - // Returning the specified value by indexOfValue - return rawADCValue; -} - -/** - * @brief Reads raw ADC data for the specified device and converts - * that value into millivolts - * @param hardwareDevice pedal enum that represents the specific device - * @return ADC value in millivolts - */ -int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice){ - // Getting rawADCValue at the specified index - int16_t rawADCValue = BSP_ADC_Get_Value(hardwareDevice); - // Converting the rawADCValue to millivolts and returning it - return convert_ADC_to_Voltage(rawADCValue); -} diff --git a/BSP/Simulator/Src/BSP_CAN.c b/BSP/Simulator/Src/BSP_CAN.c deleted file mode 100755 index ab71b537b..000000000 --- a/BSP/Simulator/Src/BSP_CAN.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright (c) 2020 UT Longhorn Racing Solar */ - -/** - * Source file for the library to interact - * with both CAN lines in the car - */ - -#include "BSP_CAN.h" -#include "os.h" - -#define FILE_NAME DATA_PATH(CAN_CSV) - -static callback_t txEvent; -static callback_t rxEvent; - -/** - * @brief Confirms that the CSV file - * has been created and throws - * an error if not - * @param bus the CAN line to initialize - * (not used for simulator) - * @return None - */ -void BSP_CAN_Init(CAN_t bus, callback_t txHandler, callback_t rxHandler) { - txEvent=txHandler; //bind the handler functions - rxEvent=rxHandler; - if (access(FILE_NAME, F_OK) != 0) { - // File doesn't exist if true - perror(CAN_CSV); - exit(EXIT_FAILURE); - } -} - -/** - * @brief Writes the id, message, and length - * of the message to the proper - * bus line in the CSV file - * @param bus the proper CAN line to write to - * defined by the CAN_t enum - * @param id the hex ID for the message to be sent - * @param data pointer to the array containing the message - * @param len length of the message in bytes - * @return number of bytes transmitted (0 if unsuccessful) - */ -ErrorStatus BSP_CAN_Write(CAN_t bus, uint32_t id, uint8_t* data, uint8_t len) { - // Get current values in CSV - FILE* fp = fopen(FILE_NAME, "r"); - if (!fp) { - printf("CAN not available\n\r"); - return 0; - } - - // Lock file - int fno = fileno(fp); - flock(fno, LOCK_EX); - - if (len > 8 || bus >= NUM_CAN) { - flock(fno, LOCK_UN); - fclose(fp); - return 0; - } - - char currentCAN[NUM_CAN][128]; - char csv[128]; - for (uint8_t i = 0; fgets(csv, 128, fp); i++) { - strcpy(currentCAN[i], csv); - } - - // Close file - flock(fno, LOCK_UN); - fclose(fp); - - // Open to write - fp = fopen(FILE_NAME, "w"); - - // Lock file - fno = fileno(fp); - flock(fno, LOCK_EX); - - // Write ID & Data - for (uint8_t i = 0; i < NUM_CAN; i++) { - if (bus == i) { - fprintf(fp, "0x%.3x,0x", id); - for (uint8_t i = 0; i < len; i++) { - fprintf(fp, "%.2x", data[i]); - } - fprintf(fp, ",%d\n", len); - } else { - fprintf(fp, "%s", currentCAN[i]); - } - } - - // Close file - fsync(fno); - flock(fno, LOCK_UN); - fclose(fp); - txEvent(); - //post to recieve queue semaphore here? - rxEvent(); - return len; -} - -/** - * @brief Reads the message currently on the - * specified CAN line in the CSV file - * @param bus the proper CAN line to write to - * defined by the CAN_t enum - * @param id pointer to integer to store the - * message ID that was read - * @param data pointer to integer array to store - * the message in bytes - * @return number of bytes read (0 if unsuccessful) - */ -ErrorStatus BSP_CAN_Read(CAN_t bus, uint32_t* id, uint8_t* data) { - FILE* fp = fopen(FILE_NAME, "r"); - if (!fp) { - printf("CAN not available\n\r"); - return 0; - } - - // Lock file - int fno = fileno(fp); - flock(fno, LOCK_EX); - - char currentCAN[NUM_CAN][256]; - char csv[256]; - uint8_t actualNumCan = 0; - for (; fgets(csv, 256, fp); actualNumCan++) { - strcpy(currentCAN[actualNumCan], csv); - } - // Count how many CAN lines are actually in the csv file - if (actualNumCan > NUM_CAN) actualNumCan = NUM_CAN; - - // Read values - uint64_t fullData; - uint8_t len = 0; - sscanf(currentCAN[bus], "%x,%lx,%hhd", id, &fullData, &len); - - // Split hex data into bytes - for (uint8_t i = 0; i < len; i++) { - data[i] = (fullData >> (8 * (len-i-1))) & 0xFF; - } - - // Clear entries from file - freopen(FILE_NAME, "w", fp); - - // Rewrite unread entries - // Write newline for read entry and any entry that should be there but isn't - uint8_t index = 0; - for (; index < actualNumCan; index++) { - if (bus == index) { - fprintf(fp, "\n"); - } else if (currentCAN[index][0] != '\n') { - fprintf(fp, "%s", currentCAN[index]); - } - } - for (; index < NUM_CAN; index++) { - fprintf(fp, "\n"); - } - - // Close file - fsync(fno); - flock(fno, LOCK_UN); - fclose(fp); - rxEvent(); - return len; -} diff --git a/BSP/Simulator/Src/BSP_GPIO.c b/BSP/Simulator/Src/BSP_GPIO.c deleted file mode 100644 index 895938f1f..000000000 --- a/BSP/Simulator/Src/BSP_GPIO.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (c) 2020 UT Longhorn Racing Solar */ - -/** - * Source file to mimic GPIO port communication - */ - -#include "BSP_GPIO.h" - -#define FILE_NAME DATA_PATH(GPIO_CSV) - -/** - * @brief Confirms that the CSV file - * has been created and throws - * an error if not - * @param port to initialize - * @param mask - pins - * @param direction - input or output - * @return None - */ -void BSP_GPIO_Init(port_t port, uint16_t mask, direction_t direction) { - if (access(FILE_NAME, F_OK) != 0) { - // File doesn't exist if true - perror(GPIO_CSV); - exit(EXIT_FAILURE); - } -} - -/** - * @brief Reads value of the line of - * the CSV file - * @param port to read - * @return data of the port - */ -uint16_t BSP_GPIO_Read(port_t port) { - FILE* fp = fopen(FILE_NAME, "r"); - if (!fp) { - printf("GPIO not available\n\r"); - return 0; - } - - // Lock file - int fno = fileno(fp); - flock(fno, LOCK_EX); - - uint16_t csvContents[NUM_PORTS] = {0}; - - int tok; - for (int i = 0; i < NUM_PORTS && fscanf(fp, "%d", &tok); i++) { - csvContents[i] = tok; - } - - // Unlock file - flock(fno, LOCK_UN); - fclose(fp); - - return csvContents[port]; -} - -/** - * @brief Writes data to a line in CSV fle - * @param port to write to - * @param data to write - * @return None - */ -void BSP_GPIO_Write(port_t port, uint16_t data) { - FILE* fp = fopen(FILE_NAME, "r"); - if (!fp) { - perror("GPIO not available\n\r"); - exit(EXIT_FAILURE); - } - - // Lock file - int fno = fileno(fp); - flock(fno, LOCK_EX); - - int csvContents[NUM_PORTS] = {0}; - - for(int i = 0; i < NUM_PORTS; i++){ - int tok; - if (fscanf(fp, "%d", &tok) != EOF) { - csvContents[i] = tok; - } - } - - csvContents[port] = data; - - freopen(FILE_NAME, "w", fp); - - for(int i = 0; i < NUM_PORTS; i++){ - fprintf(fp, "%d\n", csvContents[i]); - } - - // Unlock file - flock(fno, LOCK_UN); - fclose(fp); -} \ No newline at end of file diff --git a/BSP/Simulator/Src/BSP_SPI.c b/BSP/Simulator/Src/BSP_SPI.c deleted file mode 100644 index 4054bae33..000000000 --- a/BSP/Simulator/Src/BSP_SPI.c +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (c) 2020 UT Longhorn Racing Solar */ - -/** - * Source file for the library to interact - * over SPI with minion board(s) - */ - -#include "BSP_SPI.h" - -#define FILE_NAME DATA_PATH(SPI_CSV) - -/** - * @brief Activates SPI to use IOCON.BANK = 1 - * @param None - * @return None - */ -void BSP_SPI_Init(void) { - if (access(FILE_NAME, F_OK) != 0) { - // File doesn't exist if true - perror(CAN_CSV); - exit(EXIT_FAILURE); - } -} - -/** - * @brief Writes a message to the SPI CSV file - * @param txBuf data to transmit - * @param txLen length of the data packet - * @return None - */ -void BSP_SPI_Write(uint8_t* txBuf, uint8_t txLen) { - FILE* fp = fopen(FILE_NAME, "w"); - if (!fp) { - printf("SPI not available\n\r"); - return; - } - - // Lock file - int fno = fileno(fp); - flock(fno, LOCK_EX); - - // Build integer - uint32_t data = 0; - for (uint8_t i = 0; i < txLen; i++) { - data += txBuf[i] << (8 * (txLen-i-1)); - } - fprintf(fp, "%x", data); - - // CLose file - flock(fno, LOCK_UN); - fclose(fp); -} - -/** - * @brief Receives a message through SPI - * @param rxBuf buffer to store the received data - * @param rxLen length of the buffer - * @return None - */ -void BSP_SPI_Read(uint8_t* rxBuf, uint8_t rxLen) { - FILE* fp = fopen(FILE_NAME, "r"); - if (!fp) { - printf("SPI not available\n\r"); - return; - } - - // Lock file - int fno = fileno(fp); - flock(fno, LOCK_EX); - - // Read file - char csv[128]; - uint32_t fullData; - fgets(csv, 128, fp); - sscanf(csv, "%x", &fullData); - - // Split hex data into bytes - for (uint8_t i = 0; i < rxLen; i++) { - rxBuf[i] = (fullData >> (8 * (rxLen-i-1))) & 0xFF; - } - - // Close file - flock(fno, LOCK_UN); - fclose(fp); -} diff --git a/BSP/Simulator/Src/BSP_UART.c b/BSP/Simulator/Src/BSP_UART.c deleted file mode 100644 index 17a2369ba..000000000 --- a/BSP/Simulator/Src/BSP_UART.c +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright (c) 2020 UT Longhorn Racing Solar */ - -/** - * Source file to mimic UART communication - * that will be used to communicate with the - * Gecko display board - */ - -#include "BSP_UART.h" - -#define FILE_NAME DATA_PATH(UART_CSV) -#define RX_SIZE 64 -#define TX_SIZE 128 - -/** - * @brief Confirms that the CSV file - * has been created and throws - * an error if not - * @param None - * @return None - */ -void BSP_UART_Init(UART_t uart) { - if (access(FILE_NAME, F_OK) != 0) { - // File doesn't exist if true - perror(UART_CSV); - exit(EXIT_FAILURE); - } -} - -/** - * @brief Reads a specific line of the CSV file - * based on the UART device selected to - * get the information from. - * @pre str should be at least 128bytes long. - * @param uart device selected - * @param str pointer to buffer string - * @return number of bytes that was read - */ -uint32_t BSP_UART_Read(UART_t uart, char* str) { - FILE* fp = fopen(FILE_NAME, "r"); - if (!fp) { - printf("UART not available\n\r"); - return 0; - } - - // Lock file - int fno = fileno(fp); - flock(fno, LOCK_EX); - - // Get raw CSV strings - char csv[NUM_UART][RX_SIZE]; - for (int i=0; fgets(csv[i], RX_SIZE, fp); i++); - - // Put string into return buffer - strcpy(str, csv[uart]); - - // Unlock file - flock(fno, LOCK_UN); - fclose(fp); - - return strlen(str); -} - -/** - * @brief Writes a string to the CSV file in the - * line respective to the UART device selected - * to write information to. - * @param uart device selected - * @param str pointer to buffer with data to send. - * @param len size of buffer - * @return number of bytes that were sent - */ -uint32_t BSP_UART_Write(UART_t uart, char* str, uint32_t len) { - // Get current values in CSV - FILE* fp = fopen(FILE_NAME, "r"); - if (!fp) { - printf("UART not available\n\r"); - return 0; - } - - // Lock file - int fno = fileno(fp); - flock(fno, LOCK_EX); - - // Copying current contents - char currentUART[NUM_UART][TX_SIZE]; - char csv[TX_SIZE]; - - for(uint8_t i = 0; fgets(csv, TX_SIZE, fp); i++){ - strcpy(currentUART[i], csv); - } - - // Close file - flock(fno, LOCK_UN); - fclose(fp); - - // Open to write - fp = fopen(FILE_NAME, "w"); - - // Lock file - fno = fileno(fp); - flock(fno, LOCK_EX); - - // Write to the file - for(uint8_t i = 0; i < NUM_UART; i++){ - if(uart == i){ - fprintf(fp, "%s\n", str); - }else{ - fprintf(fp, "%s", currentUART[i]); - } - //fputc('\n', fp); - } - - // Unlock file - flock(fno, LOCK_UN); - fclose(fp); - - return strlen(str); -} From 46078edb38d5fe2020ccf2b1f43b084f8263ad49 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 1 Apr 2023 22:05:28 +0000 Subject: [PATCH 045/141] Changed Fault State, added exception struct, general assertion function, and rewrote OS assert. Created variable mailbox and mutex and moved semaphore to fault state. --- Apps/Inc/Tasks.h | 22 +++-- Apps/Src/FaultState.c | 201 +++++++++++++++++++++++++++--------------- Apps/Src/Tasks.c | 23 +++-- Apps/Src/main.c | 2 +- 4 files changed, 156 insertions(+), 92 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index a25abf967..9c952b6b6 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -99,11 +99,6 @@ extern CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; */ extern OS_Q CANBus_MsgQ; -/** - * Semaphores - */ -extern OS_SEM FaultState_Sem4; - /** * Global Variables @@ -157,12 +152,27 @@ typedef enum{ extern fault_bitmap_t FaultBitmap; extern os_error_loc_t OSErrLocBitmap; +/** + * Fault Exception Struct +*/ +typedef struct{ + uint8_t prio; + const char* message; + void* callback; +} exception_t; + /** * @brief Assert Error if OS function call fails * @param OS_err_loc Where OS error occured (driver level) * @param err OS Error that occurred */ -void _assertOSError(uint16_t OS_err_loc, OS_ERR err); //TODO: This should be changed to enforce only enum usage +void _assertOSError(uint16_t OS_err_loc, OS_ERR err); + +/** + * @brief Assert Error if non OS function call fails + * @param err non OS Error that occurred + */ +void _assertExceptionError(exception_t); #if DEBUG == 1 #define assertOSError(OS_err_loc,err) \ diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 2814fb65b..7cc888df5 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -13,6 +13,35 @@ static bool fromThread = false; //whether fault was tripped from thread extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. +/** + * Semaphores + */ +extern OS_SEM FaultState_Sem4; + +/** + * Mutex + */ +extern OS_MUTEX FaultState_Mutex; + +// current exception is initialized +exception_t currException = {-1, NULL, NULL}; + +void _assertError(exception_t exception){ + OS_ERR err; + CPU_TS ticks; + + OSMutexPend(&FaultState_Mutex, 0, OS_OPT_POST_NONE, &ticks, &err); + assertOSError(OS_SEND_CAN_LOC, err); // TODO: need location? + + currException = exception; + + OSMutexPost(&FaultState_Mutex, OS_OPT_POST_NONE, &err); + assertOSError(OS_SEND_CAN_LOC, err); // TODO: need location? + + OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); + assertOSError(OS_SEND_CAN_LOC, err); +} + static void ArrayMotorKill(void) { BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); @@ -36,84 +65,107 @@ static void readBPS_ContactorHandler(void){ } void EnterFaultState(void) { - if(FaultBitmap & FAULT_OS){ + + printf("%s", currException.message); + if(!(currException.callback)){(*(currException.callback));} // custom callback + + switch (currException.prio) + { + case 0: nonrecoverableFaultHandler(); + break; + case 1: + /* code */ + break; + case 2: + /* code */ + break; + case 3: + /* code */ + break; + default: + break; } - else if(FaultBitmap & FAULT_TRITIUM){ //This gets tripped by the ReadTritium thread - tritium_error_code_t TritiumError = MotorController_getTritiumError(); //get error code to segregate based on fault type - if(TritiumError & T_HARDWARE_OVER_CURRENT_ERR){ //Tritium signaled too much current - nonrecoverableFaultHandler(); - } + // if(FaultBitmap & FAULT_OS){ + // nonrecoverableFaultHandler(); + // } + // else if(FaultBitmap & FAULT_TRITIUM){ //This gets tripped by the ReadTritium thread + // tritium_error_code_t TritiumError = MotorController_getTritiumError(); //get error code to segregate based on fault type + + // if(TritiumError & T_HARDWARE_OVER_CURRENT_ERR){ //Tritium signaled too much current + // nonrecoverableFaultHandler(); + // } - if(TritiumError & T_SOFTWARE_OVER_CURRENT_ERR){ - nonrecoverableFaultHandler(); - } + // if(TritiumError & T_SOFTWARE_OVER_CURRENT_ERR){ + // nonrecoverableFaultHandler(); + // } - if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage - nonrecoverableFaultHandler(); - } + // if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage + // nonrecoverableFaultHandler(); + // } - if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error - // Note: separate tripcnt from T_INIT_FAIL - static uint8_t hall_fault_cnt = 0; //trip counter - if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out - nonrecoverableFaultHandler(); - } else { - hall_fault_cnt++; - MotorController_Restart(); //re-initialize motor - return; - } - } - - if(TritiumError & T_CONFIG_READ_ERR){ //Config read error - nonrecoverableFaultHandler(); - } + // if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error + // // Note: separate tripcnt from T_INIT_FAIL + // static uint8_t hall_fault_cnt = 0; //trip counter + // if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out + // nonrecoverableFaultHandler(); + // } else { + // hall_fault_cnt++; + // MotorController_Restart(); //re-initialize motor + // return; + // } + // } + + // if(TritiumError & T_CONFIG_READ_ERR){ //Config read error + // nonrecoverableFaultHandler(); + // } - if(TritiumError & T_DESAT_FAULT_ERR){ //Desaturation fault error - nonrecoverableFaultHandler(); - } - - if(TritiumError & T_MOTOR_OVER_SPEED_ERR){ //Motor over speed error - nonrecoverableFaultHandler(); - } - - if(TritiumError & T_INIT_FAIL){ //motorcontroller fails to restart or initialize - nonrecoverableFaultHandler(); - } - - return; - - /** - * FAULTS NOT HANDLED : - * Watchdog Last Reset Error - Not using any hardware watchdogs. - * - * Under Voltage Lockout Error - Not really much we can do if we're not giving the controller enough voltage, - * and if we miss drive messages as a result, it will shut itself off. - - */ - } - else if(FaultBitmap & FAULT_READBPS){ // Missed BPS Charge enable message - readBPS_ContactorHandler(); - return; - } - else if(FaultBitmap & FAULT_UNREACH){ //unreachable code - nonrecoverableFaultHandler(); - } - else if(FaultBitmap & FAULT_DISPLAY){ - static uint8_t disp_fault_cnt = 0; - if(disp_fault_cnt>3){ - Display_Fault(OSErrLocBitmap, FaultBitmap); - } else { - disp_fault_cnt++; - Display_Reset(); - return; - } - } - if(fromThread){//no recovering if fault state was entered outside of the fault thread - return; - } - while(1){;} + // if(TritiumError & T_DESAT_FAULT_ERR){ //Desaturation fault error + // nonrecoverableFaultHandler(); + // } + + // if(TritiumError & T_MOTOR_OVER_SPEED_ERR){ //Motor over speed error + // nonrecoverableFaultHandler(); + // } + + // if(TritiumError & T_INIT_FAIL){ //motorcontroller fails to restart or initialize + // nonrecoverableFaultHandler(); + // } + + // return; + + // /** + // * FAULTS NOT HANDLED : + // * Watchdog Last Reset Error - Not using any hardware watchdogs. + // * + // * Under Voltage Lockout Error - Not really much we can do if we're not giving the controller enough voltage, + // * and if we miss drive messages as a result, it will shut itself off. + + // */ + // } + // else if(FaultBitmap & FAULT_READBPS){ // Missed BPS Charge enable message + // readBPS_ContactorHandler(); + // return; + // } + // else if(FaultBitmap & FAULT_UNREACH){ //unreachable code + // nonrecoverableFaultHandler(); + // } + // else if(FaultBitmap & FAULT_DISPLAY){ + // static uint8_t disp_fault_cnt = 0; + // if(disp_fault_cnt>3){ + // Display_Fault(OSErrLocBitmap, FaultBitmap); + // } else { + // disp_fault_cnt++; + // Display_Reset(); + // return; + // } + // } + // if(fromThread){//no recovering if fault state was entered outside of the fault thread + // return; + // } + // while(1){;} + } void Task_FaultState(void *p_arg) { @@ -123,12 +175,15 @@ void Task_FaultState(void *p_arg) { FaultBitmap = FAULT_NONE; OSErrLocBitmap = OS_NONE_LOC; + OSMutexCreate(&FaultState_Mutex, "Fault state mutex", &err); + OSSemCreate(&FaultState_Sem4, "Fault State Semaphore", 0, &err); + // Block until fault is signaled by an assert while(1){ OSSemPend(&FaultState_Sem4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); - fromThread = true; + //fromThread = true; EnterFaultState(); - fromThread = false; + //fromThread = false; OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_HMSM_STRICT,&err); } } \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 2405556fa..c84733f5c 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -9,6 +9,7 @@ #include "Minions.h" #include "Pedals.h" + /** * TCBs */ @@ -34,25 +35,23 @@ CPU_STK SendCarCAN_Stk[TASK_SEND_CAR_CAN_STACK_SIZE]; CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; -/** - * Semaphores - */ -OS_SEM FaultState_Sem4; - /** * Global Variables */ -fault_bitmap_t FaultBitmap = FAULT_NONE; -os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; +//fault_bitmap_t FaultBitmap = FAULT_NONE; +//os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; +extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. void _assertOSError(uint16_t OS_err_loc, OS_ERR err) { if (err != OS_ERR_NONE) { - FaultBitmap |= FAULT_OS; - OSErrLocBitmap |= OS_err_loc; + BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); + + BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); + BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); + while(1){;} //nonrecoverable - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); - EnterFaultState(); } -} \ No newline at end of file +} + diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 5bb327b2e..450b29660 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -24,7 +24,7 @@ int main(void) { OS_ERR err; OSInit(&err); - OSSemCreate(&FaultState_Sem4, "Fault State Semaphore", 0, &err); + assertOSError(OS_MAIN_LOC, err); From 33532beb30b7d22592a0304321f734a5982d40b3 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 8 Apr 2023 19:35:28 +0000 Subject: [PATCH 046/141] updated EnterFaultState with prio based switch case. combined ArrayMotorKill with nonreocverableFaultHandler. --- Apps/Src/FaultState.c | 106 ++++-------------------------------------- 1 file changed, 10 insertions(+), 96 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 7cc888df5..24de4a24c 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -42,130 +42,44 @@ void _assertError(exception_t exception){ assertOSError(OS_SEND_CAN_LOC, err); } +static void nonrecoverableFaultHandler(){ + // Turn additional brakelight on to indicate critical error + BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); -static void ArrayMotorKill(void) { + // Array motor kill BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); while(1){;} //nonrecoverable } -static void nonrecoverableFaultHandler(){ - //turn additional brakelight on to indicate critical error - BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); - ArrayMotorKill(); -} - static void readBPS_ContactorHandler(void){ - //kill contactors + // Kill contactors Contactors_Set(ARRAY_CONTACTOR, OFF, true); Contactors_Set(ARRAY_PRECHARGE, OFF, true); - // turn off the array contactor display light + // Turn off the array contactor display light UpdateDisplay_SetArray(false); } void EnterFaultState(void) { printf("%s", currException.message); - if(!(currException.callback)){(*(currException.callback));} // custom callback + if(!(currException.callback)){(*(currException.callback));} // Custom callback switch (currException.prio) { case 0: - nonrecoverableFaultHandler(); - break; + // Things could always be worst case 1: - /* code */ + nonrecoverableFaultHandler(); break; case 2: - /* code */ - break; - case 3: - /* code */ + // Priority level 2 only calls callback break; default: break; } - // if(FaultBitmap & FAULT_OS){ - // nonrecoverableFaultHandler(); - // } - // else if(FaultBitmap & FAULT_TRITIUM){ //This gets tripped by the ReadTritium thread - // tritium_error_code_t TritiumError = MotorController_getTritiumError(); //get error code to segregate based on fault type - - // if(TritiumError & T_HARDWARE_OVER_CURRENT_ERR){ //Tritium signaled too much current - // nonrecoverableFaultHandler(); - // } - - // if(TritiumError & T_SOFTWARE_OVER_CURRENT_ERR){ - // nonrecoverableFaultHandler(); - // } - - // if(TritiumError & T_DC_BUS_OVERVOLT_ERR){ //DC bus overvoltage - // nonrecoverableFaultHandler(); - // } - - // if(TritiumError & T_HALL_SENSOR_ERR){ //hall effect error - // // Note: separate tripcnt from T_INIT_FAIL - // static uint8_t hall_fault_cnt = 0; //trip counter - // if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out - // nonrecoverableFaultHandler(); - // } else { - // hall_fault_cnt++; - // MotorController_Restart(); //re-initialize motor - // return; - // } - // } - - // if(TritiumError & T_CONFIG_READ_ERR){ //Config read error - // nonrecoverableFaultHandler(); - // } - - // if(TritiumError & T_DESAT_FAULT_ERR){ //Desaturation fault error - // nonrecoverableFaultHandler(); - // } - - // if(TritiumError & T_MOTOR_OVER_SPEED_ERR){ //Motor over speed error - // nonrecoverableFaultHandler(); - // } - - // if(TritiumError & T_INIT_FAIL){ //motorcontroller fails to restart or initialize - // nonrecoverableFaultHandler(); - // } - - // return; - - // /** - // * FAULTS NOT HANDLED : - // * Watchdog Last Reset Error - Not using any hardware watchdogs. - // * - // * Under Voltage Lockout Error - Not really much we can do if we're not giving the controller enough voltage, - // * and if we miss drive messages as a result, it will shut itself off. - - // */ - // } - // else if(FaultBitmap & FAULT_READBPS){ // Missed BPS Charge enable message - // readBPS_ContactorHandler(); - // return; - // } - // else if(FaultBitmap & FAULT_UNREACH){ //unreachable code - // nonrecoverableFaultHandler(); - // } - // else if(FaultBitmap & FAULT_DISPLAY){ - // static uint8_t disp_fault_cnt = 0; - // if(disp_fault_cnt>3){ - // Display_Fault(OSErrLocBitmap, FaultBitmap); - // } else { - // disp_fault_cnt++; - // Display_Reset(); - // return; - // } - // } - // if(fromThread){//no recovering if fault state was entered outside of the fault thread - // return; - // } - // while(1){;} - } void Task_FaultState(void *p_arg) { From 80243c8e5829a783c0d11afcd4627cc60b3d1e16 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 8 Apr 2023 20:32:56 +0000 Subject: [PATCH 047/141] wrote callback functions for priority 2 --- Apps/Src/FaultState.c | 10 ---------- Apps/Src/ReadCarCAN.c | 28 +++++++++++----------------- Apps/Src/ReadTritium.c | 4 +--- Apps/Src/UpdateDisplay.c | 23 +++++++++++++++++++---- 4 files changed, 31 insertions(+), 34 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 24de4a24c..8d8df122d 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -8,8 +8,6 @@ #include "UpdateDisplay.h" #include "ReadTritium.h" -#define RESTART_THRESHOLD 3 - static bool fromThread = false; //whether fault was tripped from thread extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. @@ -52,14 +50,6 @@ static void nonrecoverableFaultHandler(){ while(1){;} //nonrecoverable } -static void readBPS_ContactorHandler(void){ - // Kill contactors - Contactors_Set(ARRAY_CONTACTOR, OFF, true); - Contactors_Set(ARRAY_PRECHARGE, OFF, true); - - // Turn off the array contactor display light - UpdateDisplay_SetArray(false); -} void EnterFaultState(void) { diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index c6493c7bf..f1fef1e9d 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -65,26 +65,24 @@ static void updateSaturation(int8_t chargeMessage){ } // helper function to disable charging -// Turns off contactors by setting fault bitmap and signaling fault state +// Turns off contactors by signaling fault state static inline void chargingDisable(void) { OS_ERR err; // mark regen as disabled chargeEnable = false; - //kill contactors - Contactors_Set(ARRAY_CONTACTOR, false, true); - Contactors_Set(ARRAY_PRECHARGE, false, true); - - // mark regen as disabled - chargeEnable = false; + // kill contactors + exception_t readBPSError = {2, "read BPS error", callback_readBPSError}; + _assertError(readBPSError); +} - // Set fault bitmap - FaultBitmap |= FAULT_READBPS; - - // Signal fault state to kill contactors at its earliest convenience - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); - assertOSError(OS_READ_CAN_LOC,err); +static void callback_readBPSError(void){ + // Kill contactors + Contactors_Set(ARRAY_CONTACTOR, OFF, true); + Contactors_Set(ARRAY_PRECHARGE, OFF, true); + // Turn off the array contactor display light + UpdateDisplay_SetArray(false); } // helper function to call if charging should be enabled @@ -143,10 +141,6 @@ static void arrayRestart(void *p_tmr, void *p_arg){ * @param p_arg pointer to the argument passed by timer */ void canWatchTimerCallback (void *p_tmr, void *p_arg){ - - // mark regen as disabled - chargeEnable= false; - chargingDisable(); } diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index c20ec1b9d..aba1e81d7 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -37,9 +37,7 @@ tritium_error_code_t MotorController_getTritiumError(void){ static void assertTritiumError(uint16_t motor_err){ OS_ERR err; if(motor_err != T_NONE){ - FaultBitmap |= FAULT_TRITIUM; - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); - assertOSError(0, err); + } } diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 409b8e34c..e9b247f5c 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -25,6 +25,9 @@ #define FIFO_NAME disp_fifo #include "fifo.h" +// For fault handling +#define RESTART_THRESHOLD 3 + disp_fifo_t msg_queue; static OS_SEM DisplayQ_Sem4; // counting semaphore for queue message availability @@ -74,13 +77,25 @@ static void assertUpdateDisplayError(UpdateDisplayError_t err){ OS_ERR os_err; if(err != UPDATEDISPLAY_ERR_NONE){ - FaultBitmap |= FAULT_DISPLAY; - - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &os_err); - assertOSError(OS_DISPLAY_LOC, os_err); + exception_t displayError = {2, "display error", &callback_displayError}; + _assertError(displayError); } } +/** + * @brief Error handler callback function. Gets called by fault state if err is present. + */ +static void callback_displayError(void){ + static uint8_t disp_fault_cnt = 0; // If faults > three times total, Display_Fault is called + if(disp_fault_cnt>RESTART_THRESHOLD){ + Display_Fault(OSErrLocBitmap, FaultBitmap); + } else { + disp_fault_cnt++; + Display_Reset(); + return; + } +} + UpdateDisplayError_t UpdateDisplay_Init(){ OS_ERR err; disp_fifo_renew(&msg_queue); From 5b450ff72798b5f09ded9f24963a03b025b2e562 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 8 Apr 2023 21:26:27 +0000 Subject: [PATCH 048/141] wrote assert function for tritium --- Apps/Src/ReadTritium.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index aba1e81d7..c76247e07 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -9,6 +9,7 @@ //status limit flag masks #define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor 6 #define MAX_CAN_LEN 8 +#define RESTART_THRESHOLD 3 // Number of times to try restart hall sensor uint16_t Motor_FaultBitmap = T_NONE; @@ -37,10 +38,28 @@ tritium_error_code_t MotorController_getTritiumError(void){ static void assertTritiumError(uint16_t motor_err){ OS_ERR err; if(motor_err != T_NONE){ - + if(motor_err != T_HALL_SENSOR_ERR){ + exception_t notHallError = {1, "this is not hall sensor error", NULL}; + _assertError(notHallError); + }else{ + exception_t hallErrorPrio2 = {2, "hall sensor error prio 2", callback_hallError}; + _assertError(hallErrorPrio2); + } } } +static void callback_hallError(void){ + static uint8_t hall_fault_cnt = 0; //trip counter + if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out + exception_t hallErrorPrio1 = {1, "hall sensor error prio 2", NULL}; + _assertError(hallErrorPrio1); + } else { + hall_fault_cnt++; + MotorController_Restart(); //re-initialize motor + return; + } +} + /* OBJECTIVES: Objective 1: From c3af4b27ed3b510efd2a20dd8f0b6f470511dfe3 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 8 Apr 2023 22:29:56 +0000 Subject: [PATCH 049/141] fixed function pointer implementation, added h files, unused variables --- Apps/Inc/FaultState.h | 5 +++++ Apps/Inc/Tasks.h | 2 +- Apps/Src/FaultState.c | 12 +++++------- Apps/Src/ReadCarCAN.c | 19 +++++++++---------- Apps/Src/ReadTritium.c | 27 +++++++++++++++------------ Apps/Src/Tasks.c | 4 ++-- Apps/Src/UpdateDisplay.c | 26 +++++++++++++------------- Drivers/Src/Display.c | 25 ++++++++++++++++++------- 8 files changed, 68 insertions(+), 52 deletions(-) diff --git a/Apps/Inc/FaultState.h b/Apps/Inc/FaultState.h index a845f7281..518160001 100644 --- a/Apps/Inc/FaultState.h +++ b/Apps/Inc/FaultState.h @@ -1,6 +1,11 @@ #ifndef __FAULT_STATE_H #define __FAULT_STATE_H +#include "Tasks.h" + void EnterFaultState(void); +void _assertError(exception_t exception); + + #endif \ No newline at end of file diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 9c952b6b6..68cc9bd61 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -158,7 +158,7 @@ extern os_error_loc_t OSErrLocBitmap; typedef struct{ uint8_t prio; const char* message; - void* callback; + volatile void (*callback)(); } exception_t; /** diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 8d8df122d..ef9b4d7a3 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -8,18 +8,17 @@ #include "UpdateDisplay.h" #include "ReadTritium.h" -static bool fromThread = false; //whether fault was tripped from thread extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. /** * Semaphores */ -extern OS_SEM FaultState_Sem4; +OS_SEM FaultState_Sem4; /** * Mutex */ -extern OS_MUTEX FaultState_Mutex; +OS_MUTEX FaultState_Mutex; // current exception is initialized exception_t currException = {-1, NULL, NULL}; @@ -54,7 +53,9 @@ static void nonrecoverableFaultHandler(){ void EnterFaultState(void) { printf("%s", currException.message); - if(!(currException.callback)){(*(currException.callback));} // Custom callback + if(!(currException.callback)){ + currException.callback(); + } // Custom callback switch (currException.prio) { @@ -76,9 +77,6 @@ void Task_FaultState(void *p_arg) { OS_ERR err; CPU_TS ts; - FaultBitmap = FAULT_NONE; - OSErrLocBitmap = OS_NONE_LOC; - OSMutexCreate(&FaultState_Mutex, "Fault state mutex", &err); OSSemCreate(&FaultState_Sem4, "Fault State Semaphore", 0, &err); diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index f1fef1e9d..0fded02c7 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -64,10 +64,18 @@ static void updateSaturation(int8_t chargeMessage){ chargeMsgSaturation = newSaturation; } +static void callback_readBPSError(void){ + // Kill contactors + Contactors_Set(ARRAY_CONTACTOR, OFF, true); + Contactors_Set(ARRAY_PRECHARGE, OFF, true); + + // Turn off the array contactor display light + UpdateDisplay_SetArray(false); +} + // helper function to disable charging // Turns off contactors by signaling fault state static inline void chargingDisable(void) { - OS_ERR err; // mark regen as disabled chargeEnable = false; @@ -76,15 +84,6 @@ static inline void chargingDisable(void) { _assertError(readBPSError); } -static void callback_readBPSError(void){ - // Kill contactors - Contactors_Set(ARRAY_CONTACTOR, OFF, true); - Contactors_Set(ARRAY_PRECHARGE, OFF, true); - - // Turn off the array contactor display light - UpdateDisplay_SetArray(false); -} - // helper function to call if charging should be enabled static inline void chargingEnable(void) { OS_ERR err; diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index c76247e07..cd083c4f7 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -4,6 +4,7 @@ #include "CAN_Queue.h" #include "CANbus.h" #include "UpdateDisplay.h" +#include "FaultState.h" #include //status limit flag masks @@ -30,13 +31,25 @@ tritium_error_code_t MotorController_getTritiumError(void){ return T_NONE; } + +static void callback_hallError(void){ + static uint8_t hall_fault_cnt = 0; //trip counter + if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out + exception_t hallErrorPrio1 = {1, "hall sensor error prio 2", NULL}; + _assertError(hallErrorPrio1); + } else { + hall_fault_cnt++; + MotorController_Restart(); //re-initialize motor + return; + } +} + /** * @brief Assert Error if Tritium sends error. When Fault Bitmap is set, * and semaphore is posted, Fault state will run. * @param motor_err Bitmap which has motor error codes */ static void assertTritiumError(uint16_t motor_err){ - OS_ERR err; if(motor_err != T_NONE){ if(motor_err != T_HALL_SENSOR_ERR){ exception_t notHallError = {1, "this is not hall sensor error", NULL}; @@ -48,17 +61,7 @@ static void assertTritiumError(uint16_t motor_err){ } } -static void callback_hallError(void){ - static uint8_t hall_fault_cnt = 0; //trip counter - if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out - exception_t hallErrorPrio1 = {1, "hall sensor error prio 2", NULL}; - _assertError(hallErrorPrio1); - } else { - hall_fault_cnt++; - MotorController_Restart(); //re-initialize motor - return; - } -} + /* OBJECTIVES: diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index c84733f5c..7e1fa1aad 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -38,8 +38,8 @@ CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; /** * Global Variables */ -//fault_bitmap_t FaultBitmap = FAULT_NONE; -//os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; +fault_bitmap_t FaultBitmap = FAULT_NONE; +os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. void _assertOSError(uint16_t OS_err_loc, OS_ERR err) diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index e9b247f5c..94964c0c2 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -13,6 +13,7 @@ */ #include "UpdateDisplay.h" #include "Minions.h" +#include "FaultState.h" #include /** @@ -70,22 +71,10 @@ const char* compStrings[15]= { "faulterr" }; -/** - * @brief Error handler for any UpdateDisplay errors. Call this after any display application function. - */ -static void assertUpdateDisplayError(UpdateDisplayError_t err){ - OS_ERR os_err; - - if(err != UPDATEDISPLAY_ERR_NONE){ - exception_t displayError = {2, "display error", &callback_displayError}; - _assertError(displayError); - } -} - /** * @brief Error handler callback function. Gets called by fault state if err is present. */ -static void callback_displayError(void){ +static void callback_updateDisplayError(void){ static uint8_t disp_fault_cnt = 0; // If faults > three times total, Display_Fault is called if(disp_fault_cnt>RESTART_THRESHOLD){ Display_Fault(OSErrLocBitmap, FaultBitmap); @@ -96,6 +85,17 @@ static void callback_displayError(void){ } } +/** + * @brief Error handler for any UpdateDisplay errors. Call this after any display application function. + */ +static void assertUpdateDisplayError(UpdateDisplayError_t err){ + if(err != UPDATEDISPLAY_ERR_NONE){ + exception_t updateDisplayError = {2, "update display error", &callback_updateDisplayError}; + _assertError(updateDisplayError); + } +} + + UpdateDisplayError_t UpdateDisplay_Init(){ OS_ERR err; disp_fifo_renew(&msg_queue); diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 09f795103..19efc1654 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -14,6 +14,7 @@ #include "Display.h" #include "bsp.h" // for writing to UART #include "Tasks.h" // for os and fault error codes +#include "FaultState.h" #define DISP_OUT UART_3 #define MAX_MSG_LEN 32 @@ -23,6 +24,9 @@ // Operational commands have no attribute and no operator, just a command and >= 0 arguments #define isOpCmd(cmd) (cmd.op == NULL && cmd.attr == NULL) +#define RESTART_THRESHOLD 3 // number of times to restart before fault + + static const char *TERMINATOR = "\xff\xff\xff"; DisplayError_t Display_Init(){ @@ -114,13 +118,20 @@ DisplayError_t Display_Fault(os_error_loc_t osErrCode, fault_bitmap_t faultCode) return DISPLAY_ERR_NONE; } -void assertDisplayError(DisplayError_t err){ - OS_ERR os_err; +static void callback_displayError(void){ + static uint8_t disp_fault_cnt = 0; // If faults > three times total, Display_Fault is called + if(disp_fault_cnt>RESTART_THRESHOLD){ + Display_Fault(OSErrLocBitmap, FaultBitmap); + } else { + disp_fault_cnt++; + Display_Reset(); + return; + } +} +void assertDisplayError(DisplayError_t err){ if (err != DISPLAY_ERR_NONE){ - FaultBitmap |= FAULT_DISPLAY; - - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &os_err); - assertOSError(OS_DISPLAY_LOC, os_err); + exception_t displayError = {2, "display error", &callback_displayError}; + _assertError(displayError); } -} \ No newline at end of file +} From 0ad4813bae8983811bc41166bb836c402feffa6a Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 1 May 2023 19:53:32 +0000 Subject: [PATCH 050/141] Moved Faultstate mutex post, fixed a conditional for callbacks, added a macro for initializing CurrException --- Apps/Src/FaultState.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index ef9b4d7a3..330680457 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -10,6 +10,11 @@ extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. +/** + * Macros for initializing the exception +*/ +#define NEW_EXCEPTION(exception_name) exception_t exception_name = {.prio=-1,.message=NULL,.callback=NULL} + /** * Semaphores */ @@ -21,7 +26,7 @@ OS_SEM FaultState_Sem4; OS_MUTEX FaultState_Mutex; // current exception is initialized -exception_t currException = {-1, NULL, NULL}; +NEW_EXCEPTION(currException); void _assertError(exception_t exception){ OS_ERR err; @@ -32,9 +37,6 @@ void _assertError(exception_t exception){ currException = exception; - OSMutexPost(&FaultState_Mutex, OS_OPT_POST_NONE, &err); - assertOSError(OS_SEND_CAN_LOC, err); // TODO: need location? - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); assertOSError(OS_SEND_CAN_LOC, err); } @@ -53,7 +55,7 @@ static void nonrecoverableFaultHandler(){ void EnterFaultState(void) { printf("%s", currException.message); - if(!(currException.callback)){ + if(currException.callback != NULL){ currException.callback(); } // Custom callback @@ -85,6 +87,8 @@ void Task_FaultState(void *p_arg) { OSSemPend(&FaultState_Sem4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); //fromThread = true; EnterFaultState(); + OSMutexPost(&FaultState_Mutex, OS_OPT_POST_NONE, &err); + assertOSError(OS_SEND_CAN_LOC, err); // We've finished handling the error and can post the mutex now // TODO: need location? //fromThread = false; OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_HMSM_STRICT,&err); } From 9f549dc6e00a04c0c6663aaed07d6c25af1f3951 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 4 Jun 2023 17:46:55 +0000 Subject: [PATCH 051/141] Renamed _assertError to assertExceptionError, had the exception callback take void for arguments, changed the hall sensor callback to use if statements instead of making a new exception inside the callback. --- Apps/Inc/FaultState.h | 7 ++++++- Apps/Inc/Tasks.h | 14 ++++++-------- Apps/Src/FaultState.c | 17 ++++++++++------- Apps/Src/ReadCarCAN.c | 5 +++-- Apps/Src/ReadTritium.c | 33 +++++++++++++++------------------ Apps/Src/UpdateDisplay.c | 2 +- Drivers/Src/Display.c | 2 +- 7 files changed, 42 insertions(+), 38 deletions(-) diff --git a/Apps/Inc/FaultState.h b/Apps/Inc/FaultState.h index 518160001..1c730f85c 100644 --- a/Apps/Inc/FaultState.h +++ b/Apps/Inc/FaultState.h @@ -5,7 +5,12 @@ void EnterFaultState(void); -void _assertError(exception_t exception); +/** + * @brief Assert Error if non OS function call fails + * @param exception non OS Error that occurred + */ +void assertExceptionError(exception_t exception); + #endif \ No newline at end of file diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 68cc9bd61..d218615e3 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -129,7 +129,8 @@ typedef enum{ OS_MAIN_LOC = 0x200, OS_CANDRIVER_LOC = 0x400, OS_MOTOR_CONNECTION_LOC = 0x800, - OS_DISPLAY_LOC = 0x1000 + OS_DISPLAY_LOC = 0x1000, + OS_FAULT_STATE_LOC = 0x2000 } os_error_loc_t; /** @@ -154,11 +155,14 @@ extern os_error_loc_t OSErrLocBitmap; /** * Fault Exception Struct + * Created by different tasks and passed to fault thread by asserting errors + * Priority: 1 for nonrecoverable fault, 2 for callback only + * Callback function will run first regardless of priority */ typedef struct{ uint8_t prio; const char* message; - volatile void (*callback)(); + volatile void (*callback)(void); } exception_t; /** @@ -168,12 +172,6 @@ typedef struct{ */ void _assertOSError(uint16_t OS_err_loc, OS_ERR err); -/** - * @brief Assert Error if non OS function call fails - * @param err non OS Error that occurred - */ -void _assertExceptionError(exception_t); - #if DEBUG == 1 #define assertOSError(OS_err_loc,err) \ if (err != OS_ERR_NONE) { \ diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 330680457..ed59b39c2 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -28,17 +28,21 @@ OS_MUTEX FaultState_Mutex; // current exception is initialized NEW_EXCEPTION(currException); -void _assertError(exception_t exception){ +/** + * @brief Assert Error if non OS function call fails + * @param exception non OS Error that occurred + */ +void assertExceptionError(exception_t exception){ OS_ERR err; CPU_TS ticks; OSMutexPend(&FaultState_Mutex, 0, OS_OPT_POST_NONE, &ticks, &err); - assertOSError(OS_SEND_CAN_LOC, err); // TODO: need location? + assertOSError(OS_FAULT_STATE_LOC, err); currException = exception; OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); - assertOSError(OS_SEND_CAN_LOC, err); + assertOSError(OS_FAULT_STATE_LOC, err); } static void nonrecoverableFaultHandler(){ @@ -62,7 +66,8 @@ void EnterFaultState(void) { switch (currException.prio) { case 0: - // Things could always be worst + // Things could always be worse + // (Reserved for future cases of greater severity) case 1: nonrecoverableFaultHandler(); break; @@ -85,11 +90,9 @@ void Task_FaultState(void *p_arg) { // Block until fault is signaled by an assert while(1){ OSSemPend(&FaultState_Sem4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); - //fromThread = true; EnterFaultState(); OSMutexPost(&FaultState_Mutex, OS_OPT_POST_NONE, &err); - assertOSError(OS_SEND_CAN_LOC, err); // We've finished handling the error and can post the mutex now // TODO: need location? - //fromThread = false; + assertOSError(OS_FAULT_STATE_LOC, err); // We've finished handling the error and can post the mutex now OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_HMSM_STRICT,&err); } } \ No newline at end of file diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 0fded02c7..064c0c39b 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -64,6 +64,7 @@ static void updateSaturation(int8_t chargeMessage){ chargeMsgSaturation = newSaturation; } +// exception struct callback for charging disable, kills contactors and turns of display static void callback_readBPSError(void){ // Kill contactors Contactors_Set(ARRAY_CONTACTOR, OFF, true); @@ -80,8 +81,8 @@ static inline void chargingDisable(void) { chargeEnable = false; // kill contactors - exception_t readBPSError = {2, "read BPS error", callback_readBPSError}; - _assertError(readBPSError); + exception_t readBPSError = {.prio=2, .message="read BPS error", .callback=callback_readBPSError}; + assertExceptionError(readBPSError); } // helper function to call if charging should be enabled diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index cd083c4f7..2d6ab8d15 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -10,7 +10,7 @@ //status limit flag masks #define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor 6 #define MAX_CAN_LEN 8 -#define RESTART_THRESHOLD 3 // Number of times to try restart hall sensor +#define RESTART_THRESHOLD 3 // Number of times to try restarting the hall sensor uint16_t Motor_FaultBitmap = T_NONE; @@ -32,31 +32,28 @@ tritium_error_code_t MotorController_getTritiumError(void){ } -static void callback_hallError(void){ - static uint8_t hall_fault_cnt = 0; //trip counter - if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out - exception_t hallErrorPrio1 = {1, "hall sensor error prio 2", NULL}; - _assertError(hallErrorPrio1); - } else { - hall_fault_cnt++; - MotorController_Restart(); //re-initialize motor - return; - } -} /** - * @brief Assert Error if Tritium sends error. When Fault Bitmap is set, - * and semaphore is posted, Fault state will run. + * @brief Assert Error if Tritium sends error. + * When asserted, Fault state's exception will be set and the fault thread will run + * Asserts an error that either restarts the hall sensor or enters a nonrecoverable fault * @param motor_err Bitmap which has motor error codes */ static void assertTritiumError(uint16_t motor_err){ + static uint8_t hall_fault_cnt = 0; //trip counter if(motor_err != T_NONE){ if(motor_err != T_HALL_SENSOR_ERR){ - exception_t notHallError = {1, "this is not hall sensor error", NULL}; - _assertError(notHallError); + exception_t notHallError = {1, "this is Tritium, not-hall-sensor error", NULL}; + assertExceptionError(notHallError); }else{ - exception_t hallErrorPrio2 = {2, "hall sensor error prio 2", callback_hallError}; - _assertError(hallErrorPrio2); + if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out + exception_t hallErrorPrio1 = {1, "hall sensor errors have exceeded restart threshold", NULL}; + assertExceptionError(hallErrorPrio1); // Fail out by entering nonrecoverable fault + } else { + hall_fault_cnt++; + MotorController_Restart(); //re-initialize motor + return; + } } } } diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 94964c0c2..a3571baa3 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -91,7 +91,7 @@ static void callback_updateDisplayError(void){ static void assertUpdateDisplayError(UpdateDisplayError_t err){ if(err != UPDATEDISPLAY_ERR_NONE){ exception_t updateDisplayError = {2, "update display error", &callback_updateDisplayError}; - _assertError(updateDisplayError); + assertExceptionError(updateDisplayError); } } diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 19efc1654..8ac2775c5 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -132,6 +132,6 @@ static void callback_displayError(void){ void assertDisplayError(DisplayError_t err){ if (err != DISPLAY_ERR_NONE){ exception_t displayError = {2, "display error", &callback_displayError}; - _assertError(displayError); + assertExceptionError(displayError); } } From 8cf305269ff1f3584115d94833bf5b126e0da76d Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 5 Jun 2023 04:00:57 +0000 Subject: [PATCH 052/141] Fixed a couple more merge conflicts. --- Apps/Src/ReadCarCAN.c | 3 +-- Drivers/Src/Display.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 70ce1a268..875e7e51d 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -7,6 +7,7 @@ #include "Minions.h" #include "Minions.h" #include "os_cfg_app.h" +#include "Display.h" // Saturation threshold is halfway between 0 and max saturation value (half of summation from one to the number of positions) #define SATURATION_THRESHOLD (((SAT_BUF_LENGTH + 1) * SAT_BUF_LENGTH) / 4) @@ -82,7 +83,6 @@ static void callback_disableContactors(void){ // helper function to disable charging // Turns off contactors by signaling fault state static inline void chargingDisable(void) { - OS_ERR err; // mark regen as disabled chargeEnable = false; @@ -207,7 +207,6 @@ void Task_ReadCarCAN(void *p_arg) case BPS_TRIP: { // BPS has a fault and we need to enter fault state (probably) if(dataBuf.data[0] == 1){ // If buffer contains 1 for a BPS trip, we should enter a nonrecoverable fault - OS_ERR err; Display_Evac(SOC, SBPV); // Display evacuation message diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 8ac2775c5..ebabb647e 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -118,6 +118,26 @@ DisplayError_t Display_Fault(os_error_loc_t osErrCode, fault_bitmap_t faultCode) return DISPLAY_ERR_NONE; } +DisplayError_t Display_Evac(uint8_t SOC_percent, uint32_t supp_mv){ + BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); // Terminates any in progress command + + char evacPage[7] = "page 3"; + BSP_UART_Write(DISP_OUT, evacPage, strlen(evacPage)); + BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); + + char soc[13]; + sprintf(soc, "%s%d", "soc.val=", (int)SOC_percent); + BSP_UART_Write(DISP_OUT, soc, strlen(soc)); + BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); + + char supp[18]; + sprintf(supp, "%s%d", "supp.val=", (int)supp_mv); + BSP_UART_Write(DISP_OUT, supp, strlen(supp)); + BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); + + return DISPLAY_ERR_NONE; +} + static void callback_displayError(void){ static uint8_t disp_fault_cnt = 0; // If faults > three times total, Display_Fault is called if(disp_fault_cnt>RESTART_THRESHOLD){ From 5ed787d5540e19ceeaa1e516ec2a3e1d003fea46 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 7 Jun 2023 07:22:32 +0000 Subject: [PATCH 053/141] Removed delay in fault state main thread. --- Apps/Src/FaultState.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 653dd9960..67db03701 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -102,6 +102,5 @@ void Task_FaultState(void *p_arg) { EnterFaultState(); OSMutexPost(&FaultState_Mutex, OS_OPT_POST_NONE, &err); assertOSError(OS_FAULT_STATE_LOC, err); // We've finished handling the error and can post the mutex now - OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_HMSM_STRICT,&err); } } \ No newline at end of file From 789a067d746e0ea16a2a2ab6282b98c3979cad45 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Fri, 9 Jun 2023 05:54:33 +0000 Subject: [PATCH 054/141] Created test file for the updated fault state with exception levels with priority levels. Wrote test for exception priorities 1 and 2 in an isolated environment apart from other application tasks. --- Tests/Test_FaultThread_Exceptions.c | 255 ++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 Tests/Test_FaultThread_Exceptions.c diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c new file mode 100644 index 000000000..30fe9066a --- /dev/null +++ b/Tests/Test_FaultThread_Exceptions.c @@ -0,0 +1,255 @@ +/** + * Test file for fault state exceptions + * + * This file tests fault state + * to ensure thrown exceptions are handled correctly + * + * CHANGE THISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + * + * + * + * @file + * @author Nathaniel Delgado (nathaniel.delgado@utexas.edu) + * @brief Tests the fault state exception mechanism + * @version idk + * @date 2023-6-08 + * + * @copyright Copyright (c) 2022 Longhorn Racing Solar + * + */ + +#include "BSP_UART.h" +#include "FaultState.h" +#include "Tasks.h" + + + +/*** Task components ***/ +static OS_TCB ManagerTaskTCB; +static OS_TCB ExceptionTaskTCB; +static CPU_STK ManagerTaskStk; +static CPU_STK ExceptionTaskStk; + +// To do: +// Change all task initializations to be consistent in constant usage if both options work + +// Initializes FaultState +void createFaultState(void) { + OS_ERR err; + + OSTaskCreate( // Create fault task + (OS_TCB*)&FaultState_TCB, + (CPU_CHAR*)"Fault State", + (OS_TASK_PTR)&Task_FaultState, + (void*)NULL, + (OS_PRIO)2, + (CPU_STK*)FaultState_Stk, + (CPU_STK_SIZE)128/10, + (CPU_STK_SIZE)128, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR*)&err + ); + assertOSError(OS_MAIN_LOC,err); + +} + +// Initializes ReadTritium +void createReadTritium(void) { + OS_ERR err; + + OSTaskCreate( + (OS_TCB*)&ReadTritium_TCB, + (CPU_CHAR*)"ReadTritium", + (OS_TASK_PTR)Task_ReadTritium, + (void*)NULL, + (OS_PRIO)3, + (CPU_STK*)ReadTritium_Stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, + (CPU_STK_SIZE)TASK_READ_TRITIUM_STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)0, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR*)&err + ); + assertOSError(OS_MAIN_LOC, err); +} + +// Initializes ReadCarCAN +void createReadCarCAN(void) { + OS_ERR err; + + OSTaskCreate( // Create readCarCAN task + (OS_TCB*)&ReadCarCAN_TCB, + (CPU_CHAR*)"Read Car CAN", + (OS_TASK_PTR)Task_ReadCarCAN, + (void*)NULL, + (OS_PRIO)5, + (CPU_STK*)ReadCarCAN_Stk, + (CPU_STK_SIZE)128/10, + (CPU_STK_SIZE)128, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR*)&err + ); + assertOSError(OS_MAIN_LOC,err); + +} + +// Initializes UpdateDisplay +void createUpdateDisplay(void) { + OS_ERR err; + + OSTaskCreate( + (OS_TCB *)&UpdateDisplay_TCB, + (CPU_CHAR *)"UpdateDisplay_TCB", + (OS_TASK_PTR)Task_UpdateDisplay, + (void *)NULL, + (OS_PRIO)6, + (CPU_STK *)UpdateDisplay_Stk, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE / 10, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR *)&err + ); + assertOSError(OS_MAIN_LOC,err); + +} + +// Creates a task to test exceptions on their own +// callback_function: pass in the callback function to use or NULL for no callbacks +void createExceptionTask(void * callback_function) { + OS_ERR err; + + OSTaskCreate( + (OS_TCB *)&ExceptionTaskTCB, + (CPU_CHAR *)"ExceptionTask", + (OS_TASK_PTR)ExceptionTaskStk, + (void *)callback_function, + (OS_PRIO)7, + (CPU_STK *)ExceptionTaskStk, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE / 10, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR *)&err + ); + assertOSError(OS_MAIN_LOC,err); + +} + +// Callback function for ExceptionTask test exceptions +void exceptionCallback(void) { + printf("\n\rException callback successfully executed."); +} + + +// Creates an exception of priority 1 and 2 to test +// test_callbacks: the callback function to use for the exceptions +void ExceptionTask(void* test_callbacks) { + + + if (test_callbacks == NULL) { + printf("\n\r Testing exceptions without callback functions"); + } else { + printf("\n\r Testing exceptions with callback functions"); + } + // Throw a priority 2 exception + exception_t prio2Exception = {.prio = 2, .message = "\n\rprio2 exception message", .callback = test_callbacks}; + assertExceptionError(prio2Exception); + printf("\n\rPrio 2 test exception with callback has been thrown"); + + // Throw a priority 1 exception + exception_t prio1Exception = {.prio = 1, .message = "\n\rprio1 exception message", .callback = test_callbacks}; + assertExceptionError(prio1Exception); + printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); + +} + +// Test the assertOSError function by pending on a mutex that wasn't created +void OSErrorTask(void* arg) { + OS_ERR err; + OS_MUTEX testMut; + CPU_TS ts; + OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &err); + assertOSError(OS_MAIN_LOC, err); + printf("assertOSError test failed: assertion did not immediately result in an unrecoverable fault"); +} + + +// A high-priority task that manages other tasks and runs the tests +void ManagerTask(void* arg) { + CPU_Init(); + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + OS_ERR err; + + // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 + // Both with and without callback functions + printf("=========== Testing exception priorities 1 and 2 ==========="); + + createExceptionTask(NULL); // Test level 1 & 2 exceptions without callbacks + assertOSError(OS_MAIN_LOC, err); + OSTaskDel(&ExceptionTaskTCB, &err); + assertOSError(OS_MAIN_LOC, err); + + createExceptionTask(exceptionCallback); // Test level 1 & 2 exceptions with callbacks + assertOSError(OS_MAIN_LOC, err); + OSTaskDel(&ExceptionTaskTCB, &err); + assertOSError(OS_MAIN_LOC, err); + + // Test the assertOSError function using the OSErrorTask + printf("=========== Testing OS assert ==========="); + + + + + + +} + +int main() { + OS_ERR err; + OSInit(&err); + assertOSError(OS_MAIN_LOC, err); + + // Create the task manager thread + OSTaskCreate( + (OS_TCB*)&ManagerTaskTCB, + (CPU_CHAR*)"Manager Task", + (OS_TASK_PTR)ManagerTask, + (void*)NULL, + (OS_PRIO)1, + (CPU_STK*)ManagerTaskStk, + (CPU_STK_SIZE)128/10, + (CPU_STK_SIZE)128, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR*)&err + ); + assertOSError(OS_MAIN_LOC,err); + + OSStart(&err); + + while(1) { + + } +} From 4a0abb1da6ee8a67c374e2d468b4c5b718944f6f Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 10 Jun 2023 22:53:33 +0000 Subject: [PATCH 055/141] Added assertOSError test. --- Tests/Test_FaultThread_Exceptions.c | 128 ++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 34 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 30fe9066a..b524eb112 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -34,11 +34,59 @@ /*** Task components ***/ static OS_TCB ManagerTaskTCB; static OS_TCB ExceptionTaskTCB; +static OS_TCB OSErrorTaskTCB; static CPU_STK ManagerTaskStk; static CPU_STK ExceptionTaskStk; +static CPU_STK OSErrorTaskStk; // To do: // Change all task initializations to be consistent in constant usage if both options work +// Use a semaphore instead of doing a full blind wait +// Make a different OS Error function + + +// Callback function for ExceptionTask test exceptions +void exceptionCallback(void) { + printf("\n\rException callback successfully executed."); +} + + +// Creates an exception of priority 1 and 2 to test +// test_callbacks: the callback function to use for the exceptions +void ExceptionTask(void* test_callbacks) { + + + if (test_callbacks == NULL) { + printf("\n\r Testing exceptions without callback functions"); + } else { + printf("\n\r Testing exceptions with callback functions"); + } + // Throw a priority 2 exception + exception_t prio2Exception = {.prio = 2, .message = "\n\rprio2 exception message", .callback = test_callbacks}; + assertExceptionError(prio2Exception); + printf("\n\rPrio 2 test exception with callback has been thrown"); + + // Throw a priority 1 exception + exception_t prio1Exception = {.prio = 1, .message = "\n\rprio1 exception message", .callback = test_callbacks}; + assertExceptionError(prio1Exception); + printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); + + while(1){}; +} + +// Test the assertOSError function by pending on a mutex that wasn't created +void OSErrorTask(void* arg) { + OS_ERR err; + OS_MUTEX testMut; + CPU_TS ts; + OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &err); + assertOSError(OS_MAIN_LOC, err); + printf("assertOSError test failed: assertion did not immediately result in an unrecoverable fault"); + while(1){}; +} + + +// Task creation functions // Initializes FaultState void createFaultState(void) { @@ -139,7 +187,7 @@ void createExceptionTask(void * callback_function) { OSTaskCreate( (OS_TCB *)&ExceptionTaskTCB, (CPU_CHAR *)"ExceptionTask", - (OS_TASK_PTR)ExceptionTaskStk, + (OS_TASK_PTR)ExceptionTask, (void *)callback_function, (OS_PRIO)7, (CPU_STK *)ExceptionTaskStk, @@ -155,43 +203,31 @@ void createExceptionTask(void * callback_function) { } -// Callback function for ExceptionTask test exceptions -void exceptionCallback(void) { - printf("\n\rException callback successfully executed."); -} - - -// Creates an exception of priority 1 and 2 to test -// test_callbacks: the callback function to use for the exceptions -void ExceptionTask(void* test_callbacks) { +// Creates a task to test the assertOSError function +void createOSErrorTask(void) { + OS_ERR err; + + OSTaskCreate( + (OS_TCB *)&OSErrorTaskTCB, + (CPU_CHAR *)"assertOSError Task", + (OS_TASK_PTR)OSErrorTask, + (void *)NULL, + (OS_PRIO)7, + (CPU_STK *)OSErrorTaskStk, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE / 10, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR *)&err + ); + assertOSError(OS_MAIN_LOC,err); +} - if (test_callbacks == NULL) { - printf("\n\r Testing exceptions without callback functions"); - } else { - printf("\n\r Testing exceptions with callback functions"); - } - // Throw a priority 2 exception - exception_t prio2Exception = {.prio = 2, .message = "\n\rprio2 exception message", .callback = test_callbacks}; - assertExceptionError(prio2Exception); - printf("\n\rPrio 2 test exception with callback has been thrown"); - - // Throw a priority 1 exception - exception_t prio1Exception = {.prio = 1, .message = "\n\rprio1 exception message", .callback = test_callbacks}; - assertExceptionError(prio1Exception); - printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); -} -// Test the assertOSError function by pending on a mutex that wasn't created -void OSErrorTask(void* arg) { - OS_ERR err; - OS_MUTEX testMut; - CPU_TS ts; - OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &err); - assertOSError(OS_MAIN_LOC, err); - printf("assertOSError test failed: assertion did not immediately result in an unrecoverable fault"); -} // A high-priority task that manages other tasks and runs the tests @@ -199,24 +235,48 @@ void ManagerTask(void* arg) { CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); OS_ERR err; + BSP_UART_Init(UART_2); + while (1) { // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 // Both with and without callback functions printf("=========== Testing exception priorities 1 and 2 ==========="); createExceptionTask(NULL); // Test level 1 & 2 exceptions without callbacks assertOSError(OS_MAIN_LOC, err); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the task to finish + assertOSError(OS_MAIN_LOC, err); OSTaskDel(&ExceptionTaskTCB, &err); assertOSError(OS_MAIN_LOC, err); createExceptionTask(exceptionCallback); // Test level 1 & 2 exceptions with callbacks assertOSError(OS_MAIN_LOC, err); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + assertOSError(OS_MAIN_LOC, err); OSTaskDel(&ExceptionTaskTCB, &err); assertOSError(OS_MAIN_LOC, err); // Test the assertOSError function using the OSErrorTask printf("=========== Testing OS assert ==========="); + createOSErrorTask(); + assertOSError(OS_MAIN_LOC, err); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + assertOSError(OS_MAIN_LOC, err); + + // Test individual tasks error assertions + // printf("=========== Testing ReadTritium ==========="); + + // createFaultState(); + // assertOSError(OS_MAIN_LOC, err); + // createReadTritium(); + // assertOSError(OS_MAIN_LOC, err); + } + + + + + From 272e6124a1655117cbf20e4471f4a4e8ff08d9d9 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 11 Jun 2023 10:42:25 +0000 Subject: [PATCH 056/141] Attempted to add a Faultstate test for ReadTritium using the FaultThread leader board and motor simulator files. --- MotorSim/Test_motor_FaultThread_Exceptions.c | 104 +++++++++++++++++++ Tests/Test_FaultThread_Exceptions.c | 98 +++++++++++------ 2 files changed, 173 insertions(+), 29 deletions(-) create mode 100644 MotorSim/Test_motor_FaultThread_Exceptions.c diff --git a/MotorSim/Test_motor_FaultThread_Exceptions.c b/MotorSim/Test_motor_FaultThread_Exceptions.c new file mode 100644 index 000000000..d92715983 --- /dev/null +++ b/MotorSim/Test_motor_FaultThread_Exceptions.c @@ -0,0 +1,104 @@ +/** + * XXXXXThis is meant to test the ReadCarCAN module in the controls system, by "pretending" to be BPS. + * + * XXXXXThis testfile is intended to be compiled and run on Renode as the supplementary machine to send CAN messages to the main machine. + * It is designed to send messages on CAN1 (CARCAN) to test ReadCarCAN's fault handling + * Specifically, it sends the BPS trip message so we can check that this message sends the car to Fault State + * +*/ + + +#include "Tasks.h" +#include "CANbus.h" +#include "ReadTritium.h" + +static OS_TCB Task1_TCB; +static CPU_STK Task1_Stk[128]; +#define STACK_SIZE 128 + + + +void Task1(void *p_arg){ + CPU_Init(); + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + OS_ERR err; + CANDATA_t dataBuf = {0}; + CANbus_Init(MOTORCAN, NULL, 0); + uint16_t data = 0; + + CANDATA_t canError = {0}; + canError.ID=MOTOR_STATUS; + + + for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { + do { + ErrorStatus status = CANbus_Read(&dataBuf, true, MOTORCAN); + if (status != SUCCESS) { + printf("CANbus Read error status: %d\n\r", status); + } else { + data = dataBuf.data[0]; + } + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + } while (data != 0x4444); + + uint16_t tritiumError = (0x01<>1; + *((uint16_t*)(&canError.data[4])) = tritiumError; + + // Send error messages to the leader board + if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + } + + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + + } + + + +} + +int main(void){ //startup OS stuff, spawn test task + + OS_ERR err; + OSInit(&err); + if(err != OS_ERR_NONE){ + printf("OS error code %d\n",err); + } + printf("I don't think this will print. Should move UART Init"); + BSP_UART_Init(UART_2); + + + OSTaskCreate( + (OS_TCB*)&Task1_TCB, + (CPU_CHAR*)"Task1", + (OS_TASK_PTR)Task1, + (void*)NULL, + (OS_PRIO)4, + (CPU_STK*)Task1_Stk, + (CPU_STK_SIZE)STACK_SIZE/10, + (CPU_STK_SIZE)STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), + (OS_ERR*)&err + ); + + if (err != OS_ERR_NONE) { + printf("Task error code %d\n", err); + } + OSStart(&err); + if (err != OS_ERR_NONE) { + printf("OS error code %d\n", err); + } + return 0; +} + + + + + + diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index b524eb112..11e5e2eca 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -28,21 +28,37 @@ #include "BSP_UART.h" #include "FaultState.h" #include "Tasks.h" +#include "CANbus.h" /*** Task components ***/ -static OS_TCB ManagerTaskTCB; +static OS_TCB ManagerTask_TCB; static OS_TCB ExceptionTaskTCB; static OS_TCB OSErrorTaskTCB; -static CPU_STK ManagerTaskStk; +static CPU_STK ManagerTask_Stk; static CPU_STK ExceptionTaskStk; static CPU_STK OSErrorTaskStk; +/*** Constants ***/ +#define READY_ID 0x123 + + // To do: // Change all task initializations to be consistent in constant usage if both options work // Use a semaphore instead of doing a full blind wait // Make a different OS Error function +// change bool to semaphore? + +// Assertion function for OS errors +void checkOSError(OS_ERR err) { + if (err != OS_ERR_NONE) { + printf("OS error code %d\n", err); + } else { + printf("\n\rNo error yet"); + } +} + // Callback function for ExceptionTask test exceptions @@ -107,7 +123,7 @@ void createFaultState(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err ); - assertOSError(OS_MAIN_LOC,err); + checkOSError(err); } @@ -130,7 +146,7 @@ void createReadTritium(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err ); - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); } // Initializes ReadCarCAN @@ -152,7 +168,7 @@ void createReadCarCAN(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err ); - assertOSError(OS_MAIN_LOC,err); + checkOSError(err); } @@ -175,7 +191,7 @@ void createUpdateDisplay(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR *)&err ); - assertOSError(OS_MAIN_LOC,err); + checkOSError(err); } @@ -199,7 +215,7 @@ void createExceptionTask(void * callback_function) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR *)&err ); - assertOSError(OS_MAIN_LOC,err); + checkOSError(err); } @@ -222,7 +238,7 @@ void createOSErrorTask(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR *)&err ); - assertOSError(OS_MAIN_LOC,err); + checkOSError(err); } @@ -231,11 +247,14 @@ void createOSErrorTask(void) { // A high-priority task that manages other tasks and runs the tests -void ManagerTask(void* arg) { +void Task_ManagerTask(void* arg) { + printf("\n\rIn manager task"); CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); OS_ERR err; - BSP_UART_Init(UART_2); + CANbus_Init(MOTORCAN, NULL, 0); + + while (1) { // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 @@ -243,34 +262,47 @@ void ManagerTask(void* arg) { printf("=========== Testing exception priorities 1 and 2 ==========="); createExceptionTask(NULL); // Test level 1 & 2 exceptions without callbacks - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the task to finish - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); OSTaskDel(&ExceptionTaskTCB, &err); - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); createExceptionTask(exceptionCallback); // Test level 1 & 2 exceptions with callbacks - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); OSTaskDel(&ExceptionTaskTCB, &err); - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); // Test the assertOSError function using the OSErrorTask printf("=========== Testing OS assert ==========="); createOSErrorTask(); - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - assertOSError(OS_MAIN_LOC, err); + checkOSError(err); // Test individual tasks error assertions - // printf("=========== Testing ReadTritium ==========="); + printf("=========== Testing ReadTritium ==========="); + + CANDATA_t canMessage = {0}; + + createFaultState(); + checkOSError(err); + createReadTritium(); + checkOSError(err); + // Send a message to the motor to tell it to start sending stuff + canMessage.ID = READY_ID; + canMessage.idx = 0; + *(uint16_t*)(&canMessage.data) = 0x4444; + CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + OSTaskDel(&ReadTritium_TCB, &err); + + + - // createFaultState(); - // assertOSError(OS_MAIN_LOC, err); - // createReadTritium(); - // assertOSError(OS_MAIN_LOC, err); } @@ -284,19 +316,22 @@ void ManagerTask(void* arg) { } -int main() { +int main(void) { OS_ERR err; OSInit(&err); - assertOSError(OS_MAIN_LOC, err); + //assertOSError(OS_MAIN_LOC, err); + printf("\n\rThing before BSP UART Init"); + BSP_UART_Init(UART_2); + printf("\n\rThing after bsp uart init"); // Create the task manager thread OSTaskCreate( - (OS_TCB*)&ManagerTaskTCB, + (OS_TCB*)&ManagerTask_TCB, (CPU_CHAR*)"Manager Task", - (OS_TASK_PTR)ManagerTask, + (OS_TASK_PTR)Task_ManagerTask, (void*)NULL, (OS_PRIO)1, - (CPU_STK*)ManagerTaskStk, + (CPU_STK*)ManagerTask_Stk, (CPU_STK_SIZE)128/10, (CPU_STK_SIZE)128, (OS_MSG_QTY)0, @@ -305,11 +340,16 @@ int main() { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err ); - assertOSError(OS_MAIN_LOC,err); + checkOSError(err); OSStart(&err); + checkOSError(err); while(1) { + printf("\n\rInside main while loop wheeeee"); + for (int i = 0; i < 99999; i++){} + printf("\n\rLet's try a time delay too"); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); } } From a88c07cf138d76f9f549e2b80cc53cc3127d080b Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 11 Jun 2023 15:53:00 +0000 Subject: [PATCH 057/141] Added draft of ReadCarCAN Exception test to FaultThread test. --- Tests/Test_FaultThread_Exceptions.c | 115 +++++++++++++++++++--------- 1 file changed, 79 insertions(+), 36 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 11e5e2eca..6f51cd160 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -29,6 +29,8 @@ #include "FaultState.h" #include "Tasks.h" #include "CANbus.h" +#include "ReadTritium.h" +#include "Contactors.h" @@ -49,6 +51,7 @@ static CPU_STK OSErrorTaskStk; // Use a semaphore instead of doing a full blind wait // Make a different OS Error function // change bool to semaphore? +// Do we need to also turn off the motor_precharge contactor in fault state in case it's on? // Assertion function for OS errors void checkOSError(OS_ERR err) { @@ -248,57 +251,97 @@ void createOSErrorTask(void) { // A high-priority task that manages other tasks and runs the tests void Task_ManagerTask(void* arg) { + BSP_UART_Init(UART_2); printf("\n\rIn manager task"); CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); OS_ERR err; CANbus_Init(MOTORCAN, NULL, 0); + ErrorStatus errorCode; while (1) { - // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 - // Both with and without callback functions - printf("=========== Testing exception priorities 1 and 2 ==========="); - - createExceptionTask(NULL); // Test level 1 & 2 exceptions without callbacks - checkOSError(err); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the task to finish - checkOSError(err); - OSTaskDel(&ExceptionTaskTCB, &err); - checkOSError(err); + // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 + // Both with and without callback functions + printf("=========== Testing exception priorities 1 and 2 ==========="); + + createExceptionTask(NULL); // Test level 1 & 2 exceptions without callbacks + checkOSError(err); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the task to finish + checkOSError(err); + OSTaskDel(&ExceptionTaskTCB, &err); + checkOSError(err); + + createExceptionTask(exceptionCallback); // Test level 1 & 2 exceptions with callbacks + checkOSError(err); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + OSTaskDel(&ExceptionTaskTCB, &err); + checkOSError(err); - createExceptionTask(exceptionCallback); // Test level 1 & 2 exceptions with callbacks - checkOSError(err); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - OSTaskDel(&ExceptionTaskTCB, &err); - checkOSError(err); + // Test the assertOSError function using the OSErrorTask + printf("=========== Testing OS assert ==========="); + + createOSErrorTask(); + checkOSError(err); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + + // Test individual tasks error assertions + printf("=========== Testing ReadTritium ==========="); + + CANDATA_t canMessage = {0}; + canMessage.ID = READY_ID; + canMessage.idx = 0; + *(uint16_t*)(&canMessage.data) = 0x4444; + + for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { + createFaultState(); + checkOSError(err); + createReadTritium(); + checkOSError(err); + // Send a message to the motor to tell it to start sending stuff + + CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + OSTaskDel(&ReadTritium_TCB, &err); + OSTaskDel(&FaultState_TCB, &err); + + } + + + printf("=========== Testing ReadCarCAN ==========="); + createFaultState(); + checkOSError(err); + createReadCarCAN(); + checkOSError(err); + CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); + uint16_t canMsgData = 0; + + do { + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + errorCode = CANbus_Read(&canMessage, CAN_BLOCKING, CARCAN); + if (errorCode != SUCCESS) { + continue; + } + canMsgData = *((uint16_t *)canMessage.data[0]); + } while (canMsgData != 0x4444); + + // By now, the BPS Trip message should have been sent + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors + printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors + printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); + printf("\n\rArray contactor: %d", Contactors_Get(ARRAY_CONTACTOR)); + + - // Test the assertOSError function using the OSErrorTask - printf("=========== Testing OS assert ==========="); - createOSErrorTask(); - checkOSError(err); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - // Test individual tasks error assertions - printf("=========== Testing ReadTritium ==========="); - CANDATA_t canMessage = {0}; - createFaultState(); - checkOSError(err); - createReadTritium(); - checkOSError(err); - // Send a message to the motor to tell it to start sending stuff - canMessage.ID = READY_ID; - canMessage.idx = 0; - *(uint16_t*)(&canMessage.data) = 0x4444; - CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish - OSTaskDel(&ReadTritium_TCB, &err); From 7842b7da56670d4170a1ccf68d72eaa0284a8231 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 11 Jun 2023 15:56:10 +0000 Subject: [PATCH 058/141] Fixed build by adding header file and small mistakes. --- Tests/Test_FaultThread_Exceptions.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 6f51cd160..eaba8da38 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -31,6 +31,7 @@ #include "CANbus.h" #include "ReadTritium.h" #include "Contactors.h" +#include "ReadCarCAN.h" @@ -327,7 +328,7 @@ void Task_ManagerTask(void* arg) { if (errorCode != SUCCESS) { continue; } - canMsgData = *((uint16_t *)canMessage.data[0]); + canMsgData = *((uint16_t *)&canMessage.data[0]); } while (canMsgData != 0x4444); // By now, the BPS Trip message should have been sent @@ -336,7 +337,7 @@ void Task_ManagerTask(void* arg) { printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); printf("\n\rArray contactor: %d", Contactors_Get(ARRAY_CONTACTOR)); - + From cd27e54302bb339f672a75b7a1d73a4ceedd10a0 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 11 Jun 2023 19:47:36 +0000 Subject: [PATCH 059/141] printf debug --- CarSim/Test_car-sim.c | 5 ++ CarSim/Test_car_FaultThread_Exceptions.c | 74 ++++++++++++++++++++ MotorSim/Test_motor-sim.c | 5 ++ MotorSim/Test_motor_FaultThread_Exceptions.c | 1 + Tests/Test_FaultThread_Exceptions.c | 27 ++++--- 5 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 CarSim/Test_car-sim.c create mode 100644 CarSim/Test_car_FaultThread_Exceptions.c create mode 100644 MotorSim/Test_motor-sim.c diff --git a/CarSim/Test_car-sim.c b/CarSim/Test_car-sim.c new file mode 100644 index 000000000..aefa1d97d --- /dev/null +++ b/CarSim/Test_car-sim.c @@ -0,0 +1,5 @@ +#include +int main(){ + printf("Hello World"); + return 0; +} \ No newline at end of file diff --git a/CarSim/Test_car_FaultThread_Exceptions.c b/CarSim/Test_car_FaultThread_Exceptions.c new file mode 100644 index 000000000..76c16f0c5 --- /dev/null +++ b/CarSim/Test_car_FaultThread_Exceptions.c @@ -0,0 +1,74 @@ +#include "Tasks.h" +#include "CANbus.h" +#include "BSP_UART.h" +#include "CANConfig.h" + +static OS_TCB Task1_TCB; +static CPU_STK Task1_Stk[128]; + +#define STACK_SIZE 128 + +#define CARCAN_FILTER_SIZE (sizeof carCANFilterList / sizeof(CANId_t)) + + +void Task1(void *p_arg){ + CPU_Init(); + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + CANbus_Init(CARCAN, carCANFilterList, NUM_CARCAN_FILTERS); + + CANDATA_t dataBuf; // A buffer in which we can store the messages we read + + while(1){ + + ErrorStatus status = CANbus_Read(&dataBuf, true, CARCAN); + if (status != SUCCESS) { + printf("CANbus Read error status: %d\n\r", status); + } + + // Print the message ID we receive out + printf("%d\n\r", dataBuf.ID); + + + } + +} + +int main(void){ //initialize things and spawn task + OS_ERR err; + OSInit(&err); + if(err != OS_ERR_NONE){ + printf("OS error code %d\n\r",err); + } + + BSP_UART_Init(UART_2); + + OSTaskCreate( + (OS_TCB*)&Task1_TCB, + (CPU_CHAR*)"Task1", + (OS_TASK_PTR)Task1, + (void*)NULL, + (OS_PRIO)4, + (CPU_STK*)Task1_Stk, + (CPU_STK_SIZE)STACK_SIZE/10, + (CPU_STK_SIZE)STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), + (OS_ERR*)&err + ); + + + if (err != OS_ERR_NONE) { + printf("Task1 error code %d\n\r", err); + } + OSStart(&err); + if (err != OS_ERR_NONE) { + printf("OS error code %d\n\r", err); + } + return 0; + +} + + + diff --git a/MotorSim/Test_motor-sim.c b/MotorSim/Test_motor-sim.c new file mode 100644 index 000000000..aefa1d97d --- /dev/null +++ b/MotorSim/Test_motor-sim.c @@ -0,0 +1,5 @@ +#include +int main(){ + printf("Hello World"); + return 0; +} \ No newline at end of file diff --git a/MotorSim/Test_motor_FaultThread_Exceptions.c b/MotorSim/Test_motor_FaultThread_Exceptions.c index d92715983..61fde9bd5 100644 --- a/MotorSim/Test_motor_FaultThread_Exceptions.c +++ b/MotorSim/Test_motor_FaultThread_Exceptions.c @@ -21,6 +21,7 @@ static CPU_STK Task1_Stk[128]; void Task1(void *p_arg){ CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + printf("\n\rIn Task1"); OS_ERR err; CANDATA_t dataBuf = {0}; CANbus_Init(MOTORCAN, NULL, 0); diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index eaba8da38..97bbe2d83 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -79,17 +79,17 @@ void ExceptionTask(void* test_callbacks) { if (test_callbacks == NULL) { printf("\n\r Testing exceptions without callback functions"); } else { - printf("\n\r Testing exceptions with callback functions"); + //printf("\n\r Testing exceptions with callback functions"); } // Throw a priority 2 exception exception_t prio2Exception = {.prio = 2, .message = "\n\rprio2 exception message", .callback = test_callbacks}; assertExceptionError(prio2Exception); - printf("\n\rPrio 2 test exception with callback has been thrown"); + //printf("\n\rPrio 2 test exception with callback has been thrown"); // Throw a priority 1 exception exception_t prio1Exception = {.prio = 1, .message = "\n\rprio1 exception message", .callback = test_callbacks}; assertExceptionError(prio1Exception); - printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); + //printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); while(1){}; } @@ -101,7 +101,7 @@ void OSErrorTask(void* arg) { CPU_TS ts; OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &err); assertOSError(OS_MAIN_LOC, err); - printf("assertOSError test failed: assertion did not immediately result in an unrecoverable fault"); + //printf("assertOSError test failed: assertion did not immediately result in an unrecoverable fault"); while(1){}; } @@ -252,13 +252,13 @@ void createOSErrorTask(void) { // A high-priority task that manages other tasks and runs the tests void Task_ManagerTask(void* arg) { - BSP_UART_Init(UART_2); - printf("\n\rIn manager task"); CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); OS_ERR err; + printf("%d", __LINE__); CANbus_Init(MOTORCAN, NULL, 0); ErrorStatus errorCode; + printf("\n\rIn manager task"); @@ -282,7 +282,7 @@ void Task_ManagerTask(void* arg) { checkOSError(err); // Test the assertOSError function using the OSErrorTask - printf("=========== Testing OS assert ==========="); + //printf("=========== Testing OS assert ==========="); createOSErrorTask(); checkOSError(err); @@ -290,7 +290,7 @@ void Task_ManagerTask(void* arg) { checkOSError(err); // Test individual tasks error assertions - printf("=========== Testing ReadTritium ==========="); + //printf("=========== Testing ReadTritium ==========="); CANDATA_t canMessage = {0}; canMessage.ID = READY_ID; @@ -338,6 +338,10 @@ void Task_ManagerTask(void* arg) { printf("\n\rArray contactor: %d", Contactors_Get(ARRAY_CONTACTOR)); + printf("=========== Test UpdateDisplay ==========="); + + + @@ -397,3 +401,10 @@ int main(void) { } } + +void HardFault_Handler(void) { + while(1){ + volatile int x = 0; + x += 1; + } +} \ No newline at end of file From 008864784685d5f0abe1f85e7879915d77cacf2c Mon Sep 17 00:00:00 2001 From: ishdeshpa Date: Sun, 11 Jun 2023 20:51:20 +0000 Subject: [PATCH 060/141] printf now working! --- Tests/Test_FaultThread_Exceptions.c | 213 ++++++++++++++-------------- 1 file changed, 105 insertions(+), 108 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 97bbe2d83..e44ba4dd7 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -39,9 +39,10 @@ static OS_TCB ManagerTask_TCB; static OS_TCB ExceptionTaskTCB; static OS_TCB OSErrorTaskTCB; -static CPU_STK ManagerTask_Stk; -static CPU_STK ExceptionTaskStk; -static CPU_STK OSErrorTaskStk; + +static CPU_STK ManagerTask_Stk[DEFAULT_STACK_SIZE]; +static CPU_STK ExceptionTaskStk[DEFAULT_STACK_SIZE]; +static CPU_STK OSErrorTaskStk[DEFAULT_STACK_SIZE]; /*** Constants ***/ #define READY_ID 0x123 @@ -252,126 +253,114 @@ void createOSErrorTask(void) { // A high-priority task that manages other tasks and runs the tests void Task_ManagerTask(void* arg) { + OS_ERR err; CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - OS_ERR err; + OSTimeDlyHMSM(0,0,5,0,OS_OPT_TIME_HMSM_STRICT,&err); + printf("%d", __LINE__); CANbus_Init(MOTORCAN, NULL, 0); - ErrorStatus errorCode; + // ErrorStatus errorCode; printf("\n\rIn manager task"); - - + while (1) { + OSTimeDlyHMSM(0,0,5,0,OS_OPT_TIME_HMSM_STRICT,&err); // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 // Both with and without callback functions - printf("=========== Testing exception priorities 1 and 2 ==========="); + // printf("=========== Testing exception priorities 1 and 2 ==========="); - createExceptionTask(NULL); // Test level 1 & 2 exceptions without callbacks - checkOSError(err); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the task to finish - checkOSError(err); - OSTaskDel(&ExceptionTaskTCB, &err); - checkOSError(err); - - createExceptionTask(exceptionCallback); // Test level 1 & 2 exceptions with callbacks - checkOSError(err); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - OSTaskDel(&ExceptionTaskTCB, &err); - checkOSError(err); - - // Test the assertOSError function using the OSErrorTask - //printf("=========== Testing OS assert ==========="); - - createOSErrorTask(); - checkOSError(err); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - - // Test individual tasks error assertions - //printf("=========== Testing ReadTritium ==========="); - - CANDATA_t canMessage = {0}; - canMessage.ID = READY_ID; - canMessage.idx = 0; - *(uint16_t*)(&canMessage.data) = 0x4444; - - for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { - createFaultState(); - checkOSError(err); - createReadTritium(); - checkOSError(err); - // Send a message to the motor to tell it to start sending stuff - - CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish - OSTaskDel(&ReadTritium_TCB, &err); - OSTaskDel(&FaultState_TCB, &err); - - } - - - printf("=========== Testing ReadCarCAN ==========="); - createFaultState(); - checkOSError(err); - createReadCarCAN(); - checkOSError(err); - CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); - uint16_t canMsgData = 0; - - do { - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - errorCode = CANbus_Read(&canMessage, CAN_BLOCKING, CARCAN); - if (errorCode != SUCCESS) { - continue; - } - canMsgData = *((uint16_t *)&canMessage.data[0]); - } while (canMsgData != 0x4444); - - // By now, the BPS Trip message should have been sent - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors - printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors - printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); - printf("\n\rArray contactor: %d", Contactors_Get(ARRAY_CONTACTOR)); - - - printf("=========== Test UpdateDisplay ==========="); + // createExceptionTask(NULL); // Test level 1 & 2 exceptions without callbacks + // checkOSError(err); + // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the task to finish + // checkOSError(err); + // OSTaskDel(&ExceptionTaskTCB, &err); + // checkOSError(err); + + // createExceptionTask(exceptionCallback); // Test level 1 & 2 exceptions with callbacks + // checkOSError(err); + // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + // checkOSError(err); + // OSTaskDel(&ExceptionTaskTCB, &err); + // checkOSError(err); + + // // Test the assertOSError function using the OSErrorTask + // //printf("=========== Testing OS assert ==========="); + + // createOSErrorTask(); + // checkOSError(err); + // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + // checkOSError(err); + + // // Test individual tasks error assertions + // //printf("=========== Testing ReadTritium ==========="); + + // CANDATA_t canMessage = {0}; + // canMessage.ID = READY_ID; + // canMessage.idx = 0; + // *(uint16_t*)(&canMessage.data) = 0x4444; + + // for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { + // createFaultState(); + // checkOSError(err); + // createReadTritium(); + // checkOSError(err); + // // Send a message to the motor to tell it to start sending stuff + + // CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); + // OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + // OSTaskDel(&ReadTritium_TCB, &err); + // OSTaskDel(&FaultState_TCB, &err); + + // } + + + // printf("=========== Testing ReadCarCAN ==========="); + // createFaultState(); + // checkOSError(err); + // createReadCarCAN(); + // checkOSError(err); + // CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); + // uint16_t canMsgData = 0; + + // do { + // printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + // checkOSError(err); + // errorCode = CANbus_Read(&canMessage, CAN_BLOCKING, CARCAN); + // if (errorCode != SUCCESS) { + // continue; + // } + // canMsgData = *((uint16_t *)&canMessage.data[0]); + // } while (canMsgData != 0x4444); + + // // By now, the BPS Trip message should have been sent + // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors + // printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors + // printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); + // printf("\n\rArray contactor: %d", Contactors_Get(ARRAY_CONTACTOR)); + + + // printf("=========== Test UpdateDisplay ==========="); - - - - - - - - - - } - - - - - - - - - } int main(void) { + __disable_irq(); + OS_ERR err; - OSInit(&err); - //assertOSError(OS_MAIN_LOC, err); - printf("\n\rThing before BSP UART Init"); + // printf("\n\rThing before BSP UART Init"); BSP_UART_Init(UART_2); printf("\n\rThing after bsp uart init"); + OSInit(&err); + + //assertOSError(OS_MAIN_LOC, err); + + // Create the task manager thread OSTaskCreate( (OS_TCB*)&ManagerTask_TCB, @@ -380,14 +369,17 @@ int main(void) { (void*)NULL, (OS_PRIO)1, (CPU_STK*)ManagerTask_Stk, - (CPU_STK_SIZE)128/10, - (CPU_STK_SIZE)128, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE / 10, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE, (OS_MSG_QTY)0, (OS_TICK)NULL, (void*)NULL, (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err ); + + __enable_irq(); + checkOSError(err); OSStart(&err); @@ -403,8 +395,13 @@ int main(void) { } void HardFault_Handler(void) { - while(1){ - volatile int x = 0; - x += 1; - } + __disable_irq(); + __asm("bkpt"); + while(1){} +} + +void UsageFault_Handler(void) { + __disable_irq(); + __asm("bkpt"); + while(1){} } \ No newline at end of file From 82dbcca37e9093eb91562f46958f5201628d1e7c Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 13 Jun 2023 03:49:08 +0000 Subject: [PATCH 061/141] Changed the fault state exception assertion mutex to a binary semaphore since different tasks are setting and handling exceptions (a mutex would have to be posted by the same task that acquired it) --- Apps/Src/FaultState.c | 14 +- MotorSim/Test_motor_FaultThread_Exceptions.c | 9 +- Tests/Test_FaultThread_Exceptions.c | 211 ++++++++++--------- 3 files changed, 118 insertions(+), 116 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 67db03701..8284512c8 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -28,11 +28,7 @@ extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions * Semaphores */ OS_SEM FaultState_Sem4; - -/** - * Mutex - */ -OS_MUTEX FaultState_Mutex; +OS_SEM ExceptionProtection_Sem4; // current exception is initialized NEW_EXCEPTION(currException); @@ -45,7 +41,7 @@ void assertExceptionError(exception_t exception){ OS_ERR err; CPU_TS ticks; - OSMutexPend(&FaultState_Mutex, 0, OS_OPT_POST_NONE, &ticks, &err); + OSSemPend(&ExceptionProtection_Sem4, 0, OS_OPT_POST_NONE, &ticks, &err); assertOSError(OS_FAULT_STATE_LOC, err); currException = exception; @@ -70,7 +66,7 @@ void EnterFaultState(void) { printf("%s", currException.message); if(currException.callback != NULL){ currException.callback(); - } // Custom callback + } // Custom callback switch (currException.prio) { @@ -93,14 +89,14 @@ void Task_FaultState(void *p_arg) { OS_ERR err; CPU_TS ts; - OSMutexCreate(&FaultState_Mutex, "Fault state mutex", &err); + OSSemCreate(&ExceptionProtection_Sem4, "Fault State Exception Protection Semaphore", 1, &err); // To ensure currException won't be replaced too soon OSSemCreate(&FaultState_Sem4, "Fault State Semaphore", 0, &err); // Block until fault is signaled by an assert while(1){ OSSemPend(&FaultState_Sem4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); EnterFaultState(); - OSMutexPost(&FaultState_Mutex, OS_OPT_POST_NONE, &err); + OSSemPost(&ExceptionProtection_Sem4, OS_OPT_POST_NONE, &err); assertOSError(OS_FAULT_STATE_LOC, err); // We've finished handling the error and can post the mutex now } } \ No newline at end of file diff --git a/MotorSim/Test_motor_FaultThread_Exceptions.c b/MotorSim/Test_motor_FaultThread_Exceptions.c index 61fde9bd5..e595ab616 100644 --- a/MotorSim/Test_motor_FaultThread_Exceptions.c +++ b/MotorSim/Test_motor_FaultThread_Exceptions.c @@ -12,10 +12,12 @@ #include "CANbus.h" #include "ReadTritium.h" -static OS_TCB Task1_TCB; -static CPU_STK Task1_Stk[128]; #define STACK_SIZE 128 +static OS_TCB Task1_TCB; +static CPU_STK Task1_Stk[STACK_SIZE]; + + void Task1(void *p_arg){ @@ -38,12 +40,14 @@ void Task1(void *p_arg){ printf("CANbus Read error status: %d\n\r", status); } else { data = dataBuf.data[0]; + printf("\n\rWaiting for start. Read: %d", data); } OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); } while (data != 0x4444); uint16_t tritiumError = (0x01<>1; *((uint16_t*)(&canError.data[4])) = tritiumError; + printf("\n\rNow sending: %d", tritiumError); // Send error messages to the leader board if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart @@ -68,7 +72,6 @@ int main(void){ //startup OS stuff, spawn test task if(err != OS_ERR_NONE){ printf("OS error code %d\n",err); } - printf("I don't think this will print. Should move UART Init"); BSP_UART_Init(UART_2); diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index e44ba4dd7..df406dde3 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -45,7 +45,11 @@ static CPU_STK ExceptionTaskStk[DEFAULT_STACK_SIZE]; static CPU_STK OSErrorTaskStk[DEFAULT_STACK_SIZE]; /*** Constants ***/ -#define READY_ID 0x123 +#define READY_MSG 0x4444 + + +/*** Globals ***/ +OS_SEM Ready_Sema4; // To do: @@ -59,8 +63,6 @@ static CPU_STK OSErrorTaskStk[DEFAULT_STACK_SIZE]; void checkOSError(OS_ERR err) { if (err != OS_ERR_NONE) { printf("OS error code %d\n", err); - } else { - printf("\n\rNo error yet"); } } @@ -75,22 +77,24 @@ void exceptionCallback(void) { // Creates an exception of priority 1 and 2 to test // test_callbacks: the callback function to use for the exceptions void ExceptionTask(void* test_callbacks) { - + OS_ERR err; if (test_callbacks == NULL) { printf("\n\r Testing exceptions without callback functions"); } else { - //printf("\n\r Testing exceptions with callback functions"); + printf("\n\r Testing exceptions with callback functions"); } // Throw a priority 2 exception + printf("\n\rThrowing priority level 2 exception"); exception_t prio2Exception = {.prio = 2, .message = "\n\rprio2 exception message", .callback = test_callbacks}; assertExceptionError(prio2Exception); - //printf("\n\rPrio 2 test exception with callback has been thrown"); // Throw a priority 1 exception + printf("\n\rThrowing priority level 1 exception"); exception_t prio1Exception = {.prio = 1, .message = "\n\rprio1 exception message", .callback = test_callbacks}; + OSSemPost(&Ready_Sema4, OS_OPT_POST_1, &err); // Alert manager task that the test is almost finished assertExceptionError(prio1Exception); - //printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); + printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); while(1){}; } @@ -100,9 +104,11 @@ void OSErrorTask(void* arg) { OS_ERR err; OS_MUTEX testMut; CPU_TS ts; + printf("\n\rasserting an OS error"); OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &err); + OSSemPost(&Ready_Sema4, OS_OPT_POST_1, &err); assertOSError(OS_MAIN_LOC, err); - //printf("assertOSError test failed: assertion did not immediately result in an unrecoverable fault"); + printf("\n\rassertOSError test failed: assertion did not immediately result in an unrecoverable fault"); while(1){}; } @@ -254,94 +260,107 @@ void createOSErrorTask(void) { // A high-priority task that manages other tasks and runs the tests void Task_ManagerTask(void* arg) { OS_ERR err; + CPU_TS ts; CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - OSTimeDlyHMSM(0,0,5,0,OS_OPT_TIME_HMSM_STRICT,&err); - - printf("%d", __LINE__); CANbus_Init(MOTORCAN, NULL, 0); - // ErrorStatus errorCode; - printf("\n\rIn manager task"); + CANbus_Init(CARCAN, NULL, 0); + OSSemCreate(&Ready_Sema4, "Ready Flag Semaphore", 0, &err); + ErrorStatus errorCode; + while (1) { - OSTimeDlyHMSM(0,0,5,0,OS_OPT_TIME_HMSM_STRICT,&err); // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 // Both with and without callback functions - // printf("=========== Testing exception priorities 1 and 2 ==========="); + printf("\n\r=========== Testing exception priorities 1 and 2 ==========="); - // createExceptionTask(NULL); // Test level 1 & 2 exceptions without callbacks - // checkOSError(err); - // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the task to finish - // checkOSError(err); - // OSTaskDel(&ExceptionTaskTCB, &err); - // checkOSError(err); - - // createExceptionTask(exceptionCallback); // Test level 1 & 2 exceptions with callbacks - // checkOSError(err); - // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - // checkOSError(err); - // OSTaskDel(&ExceptionTaskTCB, &err); - // checkOSError(err); - - // // Test the assertOSError function using the OSErrorTask - // //printf("=========== Testing OS assert ==========="); - - // createOSErrorTask(); - // checkOSError(err); - // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - // checkOSError(err); - - // // Test individual tasks error assertions - // //printf("=========== Testing ReadTritium ==========="); - - // CANDATA_t canMessage = {0}; - // canMessage.ID = READY_ID; - // canMessage.idx = 0; - // *(uint16_t*)(&canMessage.data) = 0x4444; - - // for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { - // createFaultState(); - // checkOSError(err); - // createReadTritium(); - // checkOSError(err); - // // Send a message to the motor to tell it to start sending stuff - - // CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); - // OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish - // OSTaskDel(&ReadTritium_TCB, &err); - // OSTaskDel(&FaultState_TCB, &err); - - // } - - - // printf("=========== Testing ReadCarCAN ==========="); - // createFaultState(); - // checkOSError(err); - // createReadCarCAN(); - // checkOSError(err); - // CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); - // uint16_t canMsgData = 0; - - // do { - // printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - // checkOSError(err); - // errorCode = CANbus_Read(&canMessage, CAN_BLOCKING, CARCAN); - // if (errorCode != SUCCESS) { - // continue; - // } - // canMsgData = *((uint16_t *)&canMessage.data[0]); - // } while (canMsgData != 0x4444); - - // // By now, the BPS Trip message should have been sent - // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors - // printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors - // printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); - // printf("\n\rArray contactor: %d", Contactors_Get(ARRAY_CONTACTOR)); - - - // printf("=========== Test UpdateDisplay ==========="); + // Test level 1 & 2 exceptions without callbacks + createExceptionTask(NULL); + checkOSError(err); + createFaultState(); + checkOSError(err); + OSSemPend(&Ready_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); // Wait for task to finish + checkOSError(err); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // extra time for the task finished + checkOSError(err); + OSTaskDel(&ExceptionTaskTCB, &err); + checkOSError(err); + + // Test level 1 & 2 exceptions with callbacks + createExceptionTask(exceptionCallback); + checkOSError(err); + createFaultState(); + checkOSError(err); + OSSemPend(&Ready_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + OSTaskDel(&ExceptionTaskTCB, &err); + checkOSError(err); + + // Test the assertOSError function using the OSErrorTask + printf("\n\r=========== Testing OS assert ==========="); + + createOSErrorTask(); + checkOSError(err); + createFaultState(); + checkOSError(err); + OSSemPend(&Ready_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); + checkOSError(err); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + OSTaskDel(&ExceptionTaskTCB, &err); + + // Test individual tasks error assertions + printf("\n\r=========== Testing ReadTritium ==========="); + + CANDATA_t canMessage = {0}; + canMessage.ID = CARDATA; + canMessage.idx = 0; + *(uint16_t*)(&canMessage.data) = READY_MSG; + + for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { + createFaultState(); + checkOSError(err); + createReadTritium(); + checkOSError(err); + // Send a message to the motor to tell it to start sending stuff + + CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + OSTaskDel(&ReadTritium_TCB, &err); + OSTaskDel(&FaultState_TCB, &err); + + } + + + printf("\n\r=========== Testing ReadCarCAN ==========="); + createFaultState(); + checkOSError(err); + createReadCarCAN(); + checkOSError(err); + CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); + uint16_t canMsgData = 0; + + do { + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + errorCode = CANbus_Read(&canMessage, CAN_BLOCKING, CARCAN); + if (errorCode != SUCCESS) { + continue; + } + canMsgData = *((uint16_t *)&canMessage.data[0]); + } while (canMsgData != 0x4444); + + // By now, the BPS Trip message should have been sent + OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors + printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors + printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); + printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + + + printf("\n\r=========== Test UpdateDisplay ==========="); } @@ -349,12 +368,9 @@ void Task_ManagerTask(void* arg) { } int main(void) { - __disable_irq(); OS_ERR err; - // printf("\n\rThing before BSP UART Init"); BSP_UART_Init(UART_2); - printf("\n\rThing after bsp uart init"); OSInit(&err); @@ -376,9 +392,8 @@ int main(void) { (void*)NULL, (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err - ); + ); - __enable_irq(); checkOSError(err); @@ -393,15 +408,3 @@ int main(void) { } } - -void HardFault_Handler(void) { - __disable_irq(); - __asm("bkpt"); - while(1){} -} - -void UsageFault_Handler(void) { - __disable_irq(); - __asm("bkpt"); - while(1){} -} \ No newline at end of file From 32b1eedb84bac14778d2568ac63cfcb1650a2076 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 13 Jun 2023 06:18:24 +0000 Subject: [PATCH 062/141] Added missing calls to delete tasks for the tests. --- Tests/Test_FaultThread_Exceptions.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index df406dde3..03622c6d3 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -286,6 +286,8 @@ void Task_ManagerTask(void* arg) { checkOSError(err); OSTaskDel(&ExceptionTaskTCB, &err); checkOSError(err); + OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); // Test level 1 & 2 exceptions with callbacks createExceptionTask(exceptionCallback); @@ -297,6 +299,8 @@ void Task_ManagerTask(void* arg) { checkOSError(err); OSTaskDel(&ExceptionTaskTCB, &err); checkOSError(err); + OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); // Test the assertOSError function using the OSErrorTask printf("\n\r=========== Testing OS assert ==========="); @@ -361,7 +365,8 @@ void Task_ManagerTask(void* arg) { printf("\n\r=========== Test UpdateDisplay ==========="); - + // Might be able to test if we UpdateDisplay_Init() and then make the task + // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. } @@ -374,7 +379,7 @@ int main(void) { OSInit(&err); - //assertOSError(OS_MAIN_LOC, err); + checkOSError(err); // Create the task manager thread From 52e9edcc1ae0a4d451bc0002b5e551f8cc887a3e Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 14 Jun 2023 07:54:13 +0000 Subject: [PATCH 063/141] Added a print statement to assertOSError, changed assert functions to only use assertDisplayError and not assertUpdateDisplayError because they really do act the same and we didn't really use assertDisplayError in other apps anynways. --- Apps/Inc/UpdateDisplay.h | 2 +- Apps/Src/Tasks.c | 1 + Apps/Src/UpdateDisplay.c | 66 +++++++++++++--------------------------- 3 files changed, 23 insertions(+), 46 deletions(-) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index c45c496b6..ac3ed56c9 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -4,7 +4,7 @@ * @brief Function prototypes for the display application. * * This contains function prototypes relevant to the UpdateDisplay - * application. Call assertUpdateDisplayError after calling any of the + * application. Call assertDisplayError after calling any of the * functions in this application. * * @author Ishan Deshpande (IshDeshpa) diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 7e1fa1aad..8a0c225fe 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -46,6 +46,7 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) { if (err != OS_ERR_NONE) { + printf("\n\rOS Error code %d", err); BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index a3571baa3..e1db6f143 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -71,30 +71,6 @@ const char* compStrings[15]= { "faulterr" }; -/** - * @brief Error handler callback function. Gets called by fault state if err is present. - */ -static void callback_updateDisplayError(void){ - static uint8_t disp_fault_cnt = 0; // If faults > three times total, Display_Fault is called - if(disp_fault_cnt>RESTART_THRESHOLD){ - Display_Fault(OSErrLocBitmap, FaultBitmap); - } else { - disp_fault_cnt++; - Display_Reset(); - return; - } -} - -/** - * @brief Error handler for any UpdateDisplay errors. Call this after any display application function. - */ -static void assertUpdateDisplayError(UpdateDisplayError_t err){ - if(err != UPDATEDISPLAY_ERR_NONE){ - exception_t updateDisplayError = {2, "update display error", &callback_updateDisplayError}; - assertExceptionError(updateDisplayError); - } -} - UpdateDisplayError_t UpdateDisplay_Init(){ OS_ERR err; @@ -105,7 +81,7 @@ UpdateDisplayError_t UpdateDisplay_Init(){ assertOSError(OS_DISPLAY_LOC, err); UpdateDisplayError_t ret = UpdateDisplay_SetPage(INFO); - assertUpdateDisplayError(ret); + assertDisplayError(ret); return ret; } @@ -133,7 +109,7 @@ static UpdateDisplayError_t UpdateDisplay_PopNext(){ assertOSError(OS_SEND_CAN_LOC, err); if(!result){ - assertUpdateDisplayError(UPDATEDISPLAY_ERR_FIFO_POP); + assertDisplayError(UPDATEDISPLAY_ERR_FIFO_POP); return UPDATEDISPLAY_ERR_FIFO_POP; } @@ -163,7 +139,7 @@ static UpdateDisplayError_t UpdateDisplay_PutNext(DisplayCmd_t cmd){ assertOSError(OS_DISPLAY_LOC, err); } else{ - assertUpdateDisplayError(UPDATEDISPLAY_ERR_FIFO_PUT); + assertDisplayError(UPDATEDISPLAY_ERR_FIFO_PUT); return UPDATEDISPLAY_ERR_FIFO_PUT; } @@ -190,7 +166,7 @@ static UpdateDisplayError_t UpdateDisplay_Refresh(){ }; UpdateDisplayError_t ret = UpdateDisplay_PutNext(refreshCmd); - assertUpdateDisplayError(ret); + assertDisplayError(ret); return ret; } @@ -219,7 +195,7 @@ static UpdateDisplayError_t UpdateDisplay_SetComponent(Component_t comp, uint32_ }; ret = UpdateDisplay_PutNext(visCmd); - assertUpdateDisplayError(ret); + assertDisplayError(ret); return ret; } // For components that have a non-boolean value @@ -236,11 +212,11 @@ static UpdateDisplayError_t UpdateDisplay_SetComponent(Component_t comp, uint32_ }; ret = UpdateDisplay_PutNext(setCmd); - assertUpdateDisplayError(ret); + assertDisplayError(ret); return UpdateDisplay_PutNext(setCmd); } else{ - assertUpdateDisplayError(UPDATEDISPLAY_ERR_PARSE_COMP); + assertDisplayError(UPDATEDISPLAY_ERR_PARSE_COMP); return UPDATEDISPLAY_ERR_PARSE_COMP; } return UPDATEDISPLAY_ERR_NONE; @@ -270,11 +246,11 @@ UpdateDisplayError_t UpdateDisplay_SetSOC(uint8_t percent){ // Integer percentag } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SOC, percent); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastPercent = percent; return ret; @@ -287,11 +263,11 @@ UpdateDisplayError_t UpdateDisplay_SetSBPV(uint32_t mv){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SUPP_BATT, mv/100); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastMv = mv; return ret; @@ -304,7 +280,7 @@ UpdateDisplayError_t UpdateDisplay_SetVelocity(uint32_t mphTenths){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(VELOCITY, mphTenths); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastMphTenths = mphTenths; return ret; @@ -317,7 +293,7 @@ UpdateDisplayError_t UpdateDisplay_SetAccel(uint8_t percent){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ACCEL_METER, percent); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastPercentAccel = percent; return ret; @@ -330,7 +306,7 @@ UpdateDisplayError_t UpdateDisplay_SetArray(bool state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ARRAY, (state)?1:0); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -343,7 +319,7 @@ UpdateDisplayError_t UpdateDisplay_SetMotor(bool state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(MOTOR, (state)?1:0); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -356,11 +332,11 @@ UpdateDisplayError_t UpdateDisplay_SetGear(TriState_t gear){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(GEAR, (uint32_t)gear); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastGear = gear; return ret; @@ -373,11 +349,11 @@ UpdateDisplayError_t UpdateDisplay_SetRegenState(TriState_t state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(REGEN_ST, (uint32_t)state); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -393,7 +369,7 @@ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); + assertDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -405,6 +381,6 @@ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ void Task_UpdateDisplay(void *p_arg) { while (1) { UpdateDisplayError_t err = UpdateDisplay_PopNext(); - assertUpdateDisplayError(err); + assertDisplayError(err); } } \ No newline at end of file From afd4a7f3cabc6d5317c1cf0c7daeb2e10a740bd6 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 14 Jun 2023 08:29:23 +0000 Subject: [PATCH 064/141] Added a bit more to the Fault State tests, even though CAN communication between machines on Renode tests is not working. --- CarSim/Test_car_FaultThread_Exceptions.c | 53 +++++++++++++++++--- MotorSim/Test_motor_FaultThread_Exceptions.c | 28 +++++------ Tests/Test_FaultThread_Exceptions.c | 45 ++++++++++------- 3 files changed, 87 insertions(+), 39 deletions(-) diff --git a/CarSim/Test_car_FaultThread_Exceptions.c b/CarSim/Test_car_FaultThread_Exceptions.c index 76c16f0c5..ea67545d3 100644 --- a/CarSim/Test_car_FaultThread_Exceptions.c +++ b/CarSim/Test_car_FaultThread_Exceptions.c @@ -7,6 +7,7 @@ static OS_TCB Task1_TCB; static CPU_STK Task1_Stk[128]; #define STACK_SIZE 128 +#define READY_MSG 0x4444 #define CARCAN_FILTER_SIZE (sizeof carCANFilterList / sizeof(CANId_t)) @@ -14,23 +15,59 @@ static CPU_STK Task1_Stk[128]; void Task1(void *p_arg){ CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + printf("\n\rAbout to init Canbus"); CANbus_Init(CARCAN, carCANFilterList, NUM_CARCAN_FILTERS); + printf("\n\rCanbus initted?"); + OS_ERR err; CANDATA_t dataBuf; // A buffer in which we can store the messages we read - while(1){ + CANDATA_t chargeMsg; + chargeMsg.ID = CHARGE_ENABLE; + *(uint64_t*)(&chargeMsg.data) = 0; + chargeMsg.idx = 0; + + // Message for BPS Fault + CANDATA_t tripBPSMsg; + tripBPSMsg.ID = BPS_TRIP; + *(uint64_t*)(&tripBPSMsg.data) = 0; + tripBPSMsg.idx = 0; - ErrorStatus status = CANbus_Read(&dataBuf, true, CARCAN); - if (status != SUCCESS) { - printf("CANbus Read error status: %d\n\r", status); - } - // Print the message ID we receive out - printf("%d\n\r", dataBuf.ID); + // Send five charge enable messages so the contactors get flipped on + chargeMsg.data[0] = true; + for(int i = 0; i<5; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\nSent enable chargeMsg %d", i); + } - + // Send five charge disable messages to test prio-2 disable contactor callback + // Fault state should turn off contactors but not enter a nonrecoverable fault + chargeMsg.data[0] = false; + for(int i = 0; i<5; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\nSent disable chargeMsg %d", i); } + // Send a trip message of 1 ( rip) + // Note: trip messages are not usually sent, + // so any trip message (even 0) should be a concern. + // Maybe we should handle them differently? + *(uint64_t*)(&tripBPSMsg.data) = 1; + CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); + printf("\nSent trip message %d", tripBPSMsg.data[0]); + + dataBuf.ID = CARDATA; + *((uint16_t*)(&dataBuf.data[0])) = READY_MSG; + CANbus_Send(dataBuf, CAN_NON_BLOCKING, CARCAN); + + while(1){}; + + + + } int main(void){ //initialize things and spawn task diff --git a/MotorSim/Test_motor_FaultThread_Exceptions.c b/MotorSim/Test_motor_FaultThread_Exceptions.c index e595ab616..9f77ea454 100644 --- a/MotorSim/Test_motor_FaultThread_Exceptions.c +++ b/MotorSim/Test_motor_FaultThread_Exceptions.c @@ -12,7 +12,9 @@ #include "CANbus.h" #include "ReadTritium.h" + #define STACK_SIZE 128 +#define READY_MSG 0x4444 static OS_TCB Task1_TCB; static CPU_STK Task1_Stk[STACK_SIZE]; @@ -34,17 +36,18 @@ void Task1(void *p_arg){ for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { - do { - ErrorStatus status = CANbus_Read(&dataBuf, true, MOTORCAN); - if (status != SUCCESS) { - printf("CANbus Read error status: %d\n\r", status); - } else { - data = dataBuf.data[0]; - printf("\n\rWaiting for start. Read: %d", data); - } - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - } while (data != 0x4444); - + do { + ErrorStatus status = CANbus_Read(&dataBuf, false, MOTORCAN); + if (status != SUCCESS) { + printf("CANbus Read error status: %d\n\r", status); + } else { + data = dataBuf.data[0]; + printf("\n\rWaiting for start. Read: %d", data); + } + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + } while (data != READY_MSG); + + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); uint16_t tritiumError = (0x01<>1; *((uint16_t*)(&canError.data[4])) = tritiumError; printf("\n\rNow sending: %d", tritiumError); @@ -102,7 +105,4 @@ int main(void){ //startup OS stuff, spawn test task } - - - diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 03622c6d3..b0e8dffc6 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -32,6 +32,7 @@ #include "ReadTritium.h" #include "Contactors.h" #include "ReadCarCAN.h" +#include "UpdateDisplay.h" @@ -80,9 +81,9 @@ void ExceptionTask(void* test_callbacks) { OS_ERR err; if (test_callbacks == NULL) { - printf("\n\r Testing exceptions without callback functions"); + printf("\n\rTesting exceptions without callback functions"); } else { - printf("\n\r Testing exceptions with callback functions"); + printf("\n\rTesting exceptions with callback functions"); } // Throw a priority 2 exception printf("\n\rThrowing priority level 2 exception"); @@ -102,12 +103,13 @@ void ExceptionTask(void* test_callbacks) { // Test the assertOSError function by pending on a mutex that wasn't created void OSErrorTask(void* arg) { OS_ERR err; + OS_ERR test_err; OS_MUTEX testMut; CPU_TS ts; printf("\n\rasserting an OS error"); - OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &err); + OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &test_err); OSSemPost(&Ready_Sema4, OS_OPT_POST_1, &err); - assertOSError(OS_MAIN_LOC, err); + assertOSError(OS_MAIN_LOC, test_err); printf("\n\rassertOSError test failed: assertion did not immediately result in an unrecoverable fault"); while(1){}; } @@ -268,7 +270,19 @@ void Task_ManagerTask(void* arg) { OSSemCreate(&Ready_Sema4, "Ready Flag Semaphore", 0, &err); ErrorStatus errorCode; + /*** test */ + + + CANDATA_t testmsg = {0}; + testmsg.ID=MOTOR_STATUS; + testmsg.idx=0; + *((uint16_t*)(&testmsg.data[0])) = 4444; + while (1) { + CANbus_Send(testmsg, CAN_BLOCKING, MOTORCAN); + } + + /****/ while (1) { // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 @@ -313,7 +327,9 @@ void Task_ManagerTask(void* arg) { checkOSError(err); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); - OSTaskDel(&ExceptionTaskTCB, &err); + OSTaskDel(&OSErrorTaskTCB, &err); + checkOSError(err); + OSTaskDel(&FaultState_TCB, &err); // Test individual tasks error assertions printf("\n\r=========== Testing ReadTritium ==========="); @@ -321,17 +337,15 @@ void Task_ManagerTask(void* arg) { CANDATA_t canMessage = {0}; canMessage.ID = CARDATA; canMessage.idx = 0; - *(uint16_t*)(&canMessage.data) = READY_MSG; + *(uint16_t*)(&canMessage.data[0]) = READY_MSG; for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { createFaultState(); - checkOSError(err); createReadTritium(); - checkOSError(err); // Send a message to the motor to tell it to start sending stuff - + printf("\n\rShould be testing Tritium error %d", i); CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish OSTaskDel(&ReadTritium_TCB, &err); OSTaskDel(&FaultState_TCB, &err); @@ -367,6 +381,9 @@ void Task_ManagerTask(void* arg) { printf("\n\r=========== Test UpdateDisplay ==========="); // Might be able to test if we UpdateDisplay_Init() and then make the task // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. + UpdateDisplay_Init(); + createUpdateDisplay(); + createFaultState(); } @@ -405,11 +422,5 @@ int main(void) { OSStart(&err); checkOSError(err); - while(1) { - printf("\n\rInside main while loop wheeeee"); - for (int i = 0; i < 99999; i++){} - printf("\n\rLet's try a time delay too"); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - - } + while(1) {} } From 248bdaea6663019d29831982672772a39b346a81 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 15 Jun 2023 02:16:03 +0000 Subject: [PATCH 065/141] Added Contactors_Init(), made CarSim loop sending messages for testing purposes. --- CarSim/Test_car_FaultThread_Exceptions.c | 37 ++++++++++++++++++++---- Tests/Test_FaultThread_Exceptions.c | 21 +++++++------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/CarSim/Test_car_FaultThread_Exceptions.c b/CarSim/Test_car_FaultThread_Exceptions.c index ea67545d3..e11e816d1 100644 --- a/CarSim/Test_car_FaultThread_Exceptions.c +++ b/CarSim/Test_car_FaultThread_Exceptions.c @@ -1,3 +1,6 @@ + + + #include "Tasks.h" #include "CANbus.h" #include "BSP_UART.h" @@ -9,18 +12,29 @@ static CPU_STK Task1_Stk[128]; #define STACK_SIZE 128 #define READY_MSG 0x4444 -#define CARCAN_FILTER_SIZE (sizeof carCANFilterList / sizeof(CANId_t)) void Task1(void *p_arg){ CPU_Init(); OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); printf("\n\rAbout to init Canbus"); - CANbus_Init(CARCAN, carCANFilterList, NUM_CARCAN_FILTERS); - printf("\n\rCanbus initted?"); + CANbus_Init(CARCAN, NULL, 0); + printf("\n\rCanbus init-ed"); OS_ERR err; CANDATA_t dataBuf; // A buffer in which we can store the messages we read + //uint16_t data = 0; + + // do { + // ErrorStatus status = CANbus_Read(&dataBuf, false, MOTORCAN); + // if (status != SUCCESS) { + // printf("\n\rCANbus Read error status: %d\n\r", status); + // } else { + // data = *((uint16_t*)(&dataBuf.data[0])); + // printf("\n\rWaiting for start. Read: %d", data); + // } + // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + // } while (data != READY_MSG); CANDATA_t chargeMsg; chargeMsg.ID = CHARGE_ENABLE; @@ -33,13 +47,15 @@ void Task1(void *p_arg){ *(uint64_t*)(&tripBPSMsg.data) = 0; tripBPSMsg.idx = 0; + + while (1) { // Send five charge enable messages so the contactors get flipped on chargeMsg.data[0] = true; for(int i = 0; i<5; i++){ CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); printf("\nSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); } // Send five charge disable messages to test prio-2 disable contactor callback @@ -47,11 +63,19 @@ void Task1(void *p_arg){ chargeMsg.data[0] = false; for(int i = 0; i<5; i++){ CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); printf("\nSent disable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); } - // Send a trip message of 1 ( rip) + // Send five more charge enable messages so the contactors get flipped on again + chargeMsg.data[0] = true; + for(int i = 0; i<5; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); + } + + // Send a trip message of 1 (trip) // Note: trip messages are not usually sent, // so any trip message (even 0) should be a concern. // Maybe we should handle them differently? @@ -62,6 +86,7 @@ void Task1(void *p_arg){ dataBuf.ID = CARDATA; *((uint16_t*)(&dataBuf.data[0])) = READY_MSG; CANbus_Send(dataBuf, CAN_NON_BLOCKING, CARCAN); + } while(1){}; diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index b0e8dffc6..8cf04e66c 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -33,6 +33,7 @@ #include "Contactors.h" #include "ReadCarCAN.h" #include "UpdateDisplay.h" +#include "CANConfig.h" @@ -55,10 +56,9 @@ OS_SEM Ready_Sema4; // To do: // Change all task initializations to be consistent in constant usage if both options work -// Use a semaphore instead of doing a full blind wait -// Make a different OS Error function // change bool to semaphore? // Do we need to also turn off the motor_precharge contactor in fault state in case it's on? +// Change ReadCarCAN Exception message so we can distinguish charging disable message vs missed msg // Assertion function for OS errors void checkOSError(OS_ERR err) { @@ -267,20 +267,21 @@ void Task_ManagerTask(void* arg) { OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); CANbus_Init(MOTORCAN, NULL, 0); CANbus_Init(CARCAN, NULL, 0); + Contactors_Init(); OSSemCreate(&Ready_Sema4, "Ready Flag Semaphore", 0, &err); ErrorStatus errorCode; /*** test */ - CANDATA_t testmsg = {0}; - testmsg.ID=MOTOR_STATUS; - testmsg.idx=0; - *((uint16_t*)(&testmsg.data[0])) = 4444; + // CANDATA_t testmsg = {0}; + // testmsg.ID=MOTOR_STATUS; + // testmsg.idx=0; + // *((uint16_t*)(&testmsg.data[0])) = 4444; - while (1) { - CANbus_Send(testmsg, CAN_BLOCKING, MOTORCAN); - } + // while (1) { + // CANbus_Send(testmsg, CAN_BLOCKING, MOTORCAN); + // } /****/ @@ -345,7 +346,7 @@ void Task_ManagerTask(void* arg) { // Send a message to the motor to tell it to start sending stuff printf("\n\rShould be testing Tritium error %d", i); CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish OSTaskDel(&ReadTritium_TCB, &err); OSTaskDel(&FaultState_TCB, &err); From 8ddb0d5c7e6ad28c7aa7c94850f651ec905bad92 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 15 Jun 2023 23:59:41 +0000 Subject: [PATCH 066/141] Addressing review comments: removed macro, volatilequalifier for exception and EnterFaultState in header since they aren't needed. --- Apps/Inc/FaultState.h | 2 -- Apps/Inc/Tasks.h | 2 +- Apps/Src/FaultState.c | 8 ++------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Apps/Inc/FaultState.h b/Apps/Inc/FaultState.h index 1c730f85c..619c1ba54 100644 --- a/Apps/Inc/FaultState.h +++ b/Apps/Inc/FaultState.h @@ -3,8 +3,6 @@ #include "Tasks.h" -void EnterFaultState(void); - /** * @brief Assert Error if non OS function call fails * @param exception non OS Error that occurred diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index f96be2512..3ab187bed 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -163,7 +163,7 @@ extern os_error_loc_t OSErrLocBitmap; typedef struct{ uint8_t prio; const char* message; - volatile void (*callback)(void); + void (*callback)(void); } exception_t; /** diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index 8284512c8..e48912695 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -19,11 +19,6 @@ #include "ReadTritium.h" extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. -/** - * Macros for initializing the exception -*/ -#define NEW_EXCEPTION(exception_name) exception_t exception_name = {.prio=-1,.message=NULL,.callback=NULL} - /** * Semaphores */ @@ -31,7 +26,7 @@ OS_SEM FaultState_Sem4; OS_SEM ExceptionProtection_Sem4; // current exception is initialized -NEW_EXCEPTION(currException); +exception_t currException = {.prio=-1,.message=NULL,.callback=NULL}; /** * @brief Assert Error if non OS function call fails @@ -47,6 +42,7 @@ void assertExceptionError(exception_t exception){ currException = exception; OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); + //printf("\n\rThis should happen after the exception is handled"); assertOSError(OS_FAULT_STATE_LOC, err); } From 3cc2d3406d64d3bdb6603202bf197126c406ac35 Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 17 Jun 2023 12:15:47 -0500 Subject: [PATCH 067/141] Some small things changed while testing --- Apps/Src/FaultState.c | 2 +- Tests/Test_FaultThread_Exceptions.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index e48912695..5a3103956 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -59,7 +59,7 @@ static void nonrecoverableFaultHandler(){ void EnterFaultState(void) { - printf("%s", currException.message); + printf("\r\n%s\r\n", currException.message); if(currException.callback != NULL){ currException.callback(); } // Custom callback diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 8cf04e66c..1bc1736d0 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -352,7 +352,6 @@ void Task_ManagerTask(void* arg) { } - printf("\n\r=========== Testing ReadCarCAN ==========="); createFaultState(); checkOSError(err); @@ -370,7 +369,7 @@ void Task_ManagerTask(void* arg) { continue; } canMsgData = *((uint16_t *)&canMessage.data[0]); - } while (canMsgData != 0x4444); + } while (canMsgData != READY_MSG); // By now, the BPS Trip message should have been sent OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors @@ -378,7 +377,6 @@ void Task_ManagerTask(void* arg) { printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); - printf("\n\r=========== Test UpdateDisplay ==========="); // Might be able to test if we UpdateDisplay_Init() and then make the task // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. From 7313f6d87a961e331b12e5344d9dee3a81798bc1 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 17 Jun 2023 23:33:39 +0000 Subject: [PATCH 068/141] Changed exception prio field to use an enum instead of an int. --- Apps/Inc/Tasks.h | 13 ++++++++++++- Apps/Src/FaultState.c | 8 ++++---- Apps/Src/ReadCarCAN.c | 4 ++-- Apps/Src/ReadTritium.c | 4 ++-- Drivers/Src/Display.c | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 3ab187bed..02ed8974a 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -154,6 +154,17 @@ typedef enum{ extern fault_bitmap_t FaultBitmap; extern os_error_loc_t OSErrLocBitmap; +/** + * Fault Exception Enum + * For the "prio" field of a fault exception struct to determine handling mode + */ +typedef enum { + PRI_RESERVED = 0, // Currently unused, reserved prio of max severity for future use + PRI_NONRECOV = 1, // Kills contactors, turns on lights, and enters a nonrecoverable fault + PRI_RECOV = 2, // Returns to thread (no action besides message and callback) + +} exception_prio_t; + /** * Fault Exception Struct * Created by different tasks and passed to fault thread by asserting errors @@ -161,7 +172,7 @@ extern os_error_loc_t OSErrLocBitmap; * Callback function will run first regardless of priority */ typedef struct{ - uint8_t prio; + exception_prio_t prio; const char* message; void (*callback)(void); } exception_t; diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c index e48912695..a2f24ea03 100644 --- a/Apps/Src/FaultState.c +++ b/Apps/Src/FaultState.c @@ -26,7 +26,7 @@ OS_SEM FaultState_Sem4; OS_SEM ExceptionProtection_Sem4; // current exception is initialized -exception_t currException = {.prio=-1,.message=NULL,.callback=NULL}; +exception_t currException = {.prio=PRI_RECOV,.message=NULL,.callback=NULL}; /** * @brief Assert Error if non OS function call fails @@ -66,13 +66,13 @@ void EnterFaultState(void) { switch (currException.prio) { - case 0: + case PRI_RESERVED: // Things could always be worse // (Reserved for future cases of greater severity) - case 1: + case PRI_NONRECOV: nonrecoverableFaultHandler(); break; - case 2: + case PRI_RECOV: // Priority level 2 only calls callback break; default: diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 875e7e51d..9c85b9593 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -87,7 +87,7 @@ static inline void chargingDisable(void) { chargeEnable = false; // kill contactors - exception_t readBPSError = {.prio=2, .message="read BPS error", .callback=callback_disableContactors}; + exception_t readBPSError = {.prio=PRI_RECOV, .message="read BPS error", .callback=callback_disableContactors}; assertExceptionError(readBPSError); } @@ -212,7 +212,7 @@ void Task_ReadCarCAN(void *p_arg) // Create an exception and assert the error // kill contactors and enter a nonrecoverable fault - exception_t tripBPSError = {.prio=1, .message="BPS has been tripped", .callback=callback_disableContactors}; + exception_t tripBPSError = {.prio=PRI_NONRECOV, .message="BPS has been tripped", .callback=callback_disableContactors}; assertExceptionError(tripBPSError); } } diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 7eaa57bdd..30b428cd3 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -43,11 +43,11 @@ static void assertTritiumError(uint16_t motor_err){ static uint8_t hall_fault_cnt = 0; //trip counter if(motor_err != T_NONE){ if(motor_err != T_HALL_SENSOR_ERR){ - exception_t notHallError = {1, "this is Tritium, not-hall-sensor error", NULL}; + exception_t notHallError = {PRI_NONRECOV, "this is Tritium, not-hall-sensor error", NULL}; assertExceptionError(notHallError); }else{ if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out - exception_t hallErrorPrio1 = {1, "hall sensor errors have exceeded restart threshold", NULL}; + exception_t hallErrorPrio1 = {PRI_NONRECOV, "hall sensor errors have exceeded restart threshold", NULL}; assertExceptionError(hallErrorPrio1); // Fail out by entering nonrecoverable fault } else { hall_fault_cnt++; diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index ebabb647e..1cdbe4bf1 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -151,7 +151,7 @@ static void callback_displayError(void){ void assertDisplayError(DisplayError_t err){ if (err != DISPLAY_ERR_NONE){ - exception_t displayError = {2, "display error", &callback_displayError}; + exception_t displayError = {PRI_RECOV, "display error", &callback_displayError}; assertExceptionError(displayError); } } From b0f84ded1fc3f3f810201ef9af9569e3bbc20c7d Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 20 Jun 2023 21:53:42 +0000 Subject: [PATCH 069/141] Added/updated comments at the tops of the test files explaining what they are supposed to do. --- CarSim/Test_car_FaultThread_Exceptions.c | 20 +++++- MotorSim/Test_motor_FaultThread_Exceptions.c | 18 ++++-- Tests/Test_FaultThread_Exceptions.c | 66 +++++++++----------- 3 files changed, 62 insertions(+), 42 deletions(-) diff --git a/CarSim/Test_car_FaultThread_Exceptions.c b/CarSim/Test_car_FaultThread_Exceptions.c index e11e816d1..945261268 100644 --- a/CarSim/Test_car_FaultThread_Exceptions.c +++ b/CarSim/Test_car_FaultThread_Exceptions.c @@ -1,4 +1,22 @@ - +/** + * This is meant to test exception handling in the ReadTritium module by pretending to be the motor + * + * This testfile is intended to be compiled and run on Renode as the supplementary machine + * to send Tritium error messages to the main machine. + * It is designed to send messages on CAN3 (MOTORCAN) to test ReadTritium and FaultState's error handling. + * Specifically, it goes through each Tritium error and sends it to the leaderboard. + * + * Run this test in conjuction with Test_FaultThread_Exceptions + * + * @file + * @author Madeleine Lee (madeleinercflee@utexas.edu) + * @brief Tests the fault state exception mechanism + * @version + * @date 2023-6-08 + * + * @copyright Copyright (c) 2022 Longhorn Racing Solar + * +*/ #include "Tasks.h" diff --git a/MotorSim/Test_motor_FaultThread_Exceptions.c b/MotorSim/Test_motor_FaultThread_Exceptions.c index 9f77ea454..228754b43 100644 --- a/MotorSim/Test_motor_FaultThread_Exceptions.c +++ b/MotorSim/Test_motor_FaultThread_Exceptions.c @@ -1,9 +1,19 @@ /** - * XXXXXThis is meant to test the ReadCarCAN module in the controls system, by "pretending" to be BPS. + * This is meant to test exception handling in the ReadCarCAN module by pretending to be BPS. * - * XXXXXThis testfile is intended to be compiled and run on Renode as the supplementary machine to send CAN messages to the main machine. - * It is designed to send messages on CAN1 (CARCAN) to test ReadCarCAN's fault handling - * Specifically, it sends the BPS trip message so we can check that this message sends the car to Fault State + * This testfile is intended to be compiled and run on Renode as the supplementary machine to send CAN messages to the main machine. + * It is designed to send messages on CAN1 (CARCAN) to test ReadCarCAN and FaultState's fault handling + * Specifically, it tests the exceptions for disabling charging and handling the BPS trip message + * + * Run this test in conjuction with Test_FaultThread_Exceptions + * + * @file + * @author Madeleine Lee (madeleinercflee@utexas.edu) + * @brief Supplemental testfile for testing the fault state exception mechanism + * @version + * @date 2023-6-08 + * + * @copyright Copyright (c) 2022 Longhorn Racing Solar * */ diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 1bc1736d0..68a964a70 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -1,24 +1,17 @@ /** - * Test file for fault state exceptions - * - * This file tests fault state - * to ensure thrown exceptions are handled correctly - * - * CHANGE THISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - * * + * This file tests the fault state exception struct mechanism + * to ensure thrown exceptions are handled correctly. + * It does this by testing the assertion functions for each priority option + * and creating and faulting tasks using the car and bps sim on Renode + * + * This test is run in conjunction with Test_motor_FaultThread_Exceptions + * and Test_car_FaultThread_Exceptions on Renode * * @file - * @author Nathaniel Delgado (nathaniel.delgado@utexas.edu) + * @author Madeleine Lee (madeleinercflee@utexas.edu) * @brief Tests the fault state exception mechanism - * @version idk + * @version * @date 2023-6-08 * * @copyright Copyright (c) 2022 Longhorn Racing Solar @@ -54,12 +47,6 @@ static CPU_STK OSErrorTaskStk[DEFAULT_STACK_SIZE]; OS_SEM Ready_Sema4; -// To do: -// Change all task initializations to be consistent in constant usage if both options work -// change bool to semaphore? -// Do we need to also turn off the motor_precharge contactor in fault state in case it's on? -// Change ReadCarCAN Exception message so we can distinguish charging disable message vs missed msg - // Assertion function for OS errors void checkOSError(OS_ERR err) { if (err != OS_ERR_NONE) { @@ -87,12 +74,12 @@ void ExceptionTask(void* test_callbacks) { } // Throw a priority 2 exception printf("\n\rThrowing priority level 2 exception"); - exception_t prio2Exception = {.prio = 2, .message = "\n\rprio2 exception message", .callback = test_callbacks}; + exception_t prio2Exception = {.prio = PRI_RECOV, .message = "\n\rprio2 exception message", .callback = test_callbacks}; assertExceptionError(prio2Exception); // Throw a priority 1 exception printf("\n\rThrowing priority level 1 exception"); - exception_t prio1Exception = {.prio = 1, .message = "\n\rprio1 exception message", .callback = test_callbacks}; + exception_t prio1Exception = {.prio = PRI_NONRECOV, .message = "\n\rprio1 exception message", .callback = test_callbacks}; OSSemPost(&Ready_Sema4, OS_OPT_POST_1, &err); // Alert manager task that the test is almost finished assertExceptionError(prio1Exception); printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); @@ -269,7 +256,7 @@ void Task_ManagerTask(void* arg) { CANbus_Init(CARCAN, NULL, 0); Contactors_Init(); OSSemCreate(&Ready_Sema4, "Ready Flag Semaphore", 0, &err); - ErrorStatus errorCode; + //ErrorStatus errorCode; /*** test */ @@ -288,6 +275,8 @@ void Task_ManagerTask(void* arg) { while (1) { // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 // Both with and without callback functions + // Successful if exception message and callback message (if applicable) are printed + // and the fail message is not printed (tasks are stopped when they assert an error) printf("\n\r=========== Testing exception priorities 1 and 2 ==========="); // Test level 1 & 2 exceptions without callbacks @@ -318,6 +307,9 @@ void Task_ManagerTask(void* arg) { checkOSError(err); // Test the assertOSError function using the OSErrorTask + // Creates an OS error by pending on a mutex that isn't created + // Successful if it prints the OS Error code + // and doesn't print the fail message (task is stopped by asserting an error) printf("\n\r=========== Testing OS assert ==========="); createOSErrorTask(); @@ -332,7 +324,8 @@ void Task_ManagerTask(void* arg) { checkOSError(err); OSTaskDel(&FaultState_TCB, &err); - // Test individual tasks error assertions + // Test exceptions in ReadTritium by creating the tasks + // and sending faults using the motor sim on Renode printf("\n\r=========== Testing ReadTritium ==========="); CANDATA_t canMessage = {0}; @@ -352,31 +345,30 @@ void Task_ManagerTask(void* arg) { } + // Tests exceptions in ReadCarCAN by creating the tasks + // and sending messages using the bps sim on Renode printf("\n\r=========== Testing ReadCarCAN ==========="); createFaultState(); checkOSError(err); createReadCarCAN(); checkOSError(err); CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); - uint16_t canMsgData = 0; + //uint16_t canMsgData = 0; - do { + for (int i = 0; i < 20; i++) { printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - errorCode = CANbus_Read(&canMessage, CAN_BLOCKING, CARCAN); - if (errorCode != SUCCESS) { - continue; - } - canMsgData = *((uint16_t *)&canMessage.data[0]); - } while (canMsgData != READY_MSG); + //OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_HMSM_STRICT, &err); + //int x = 0; + //for (int i = 0; i < 9999999; i++){x+=1;} + } // By now, the BPS Trip message should have been sent - OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors + //OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + printf("\n\r=========== Test UpdateDisplay ==========="); // Might be able to test if we UpdateDisplay_Init() and then make the task // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. From b4a8249c0fa6e3c8193c70afcfc36c293fec847b Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 22 Jun 2023 03:41:06 +0000 Subject: [PATCH 070/141] Moved tasks done by the bps-sim and motor-sim on Renode into the main task in the leaderboard test in an attempt to avoid the many issues previously plaguing this endeavor. --- Tests/Test_Driver_CANbus.c | 106 +++++++++ Tests/Test_FaultThread_Exceptions.c | 319 +++++++++++++++++++++++++--- 2 files changed, 397 insertions(+), 28 deletions(-) create mode 100644 Tests/Test_Driver_CANbus.c diff --git a/Tests/Test_Driver_CANbus.c b/Tests/Test_Driver_CANbus.c new file mode 100644 index 000000000..1092755f2 --- /dev/null +++ b/Tests/Test_Driver_CANbus.c @@ -0,0 +1,106 @@ +#include "Tasks.h" +#include "CANbus.h" +#include "BSP_UART.h" +#include "CANConfig.h" + +static OS_TCB Task1_TCB; +static CPU_STK Task1_Stk[128]; + +#define STACK_SIZE 128 + +#define CARCAN_FILTER_SIZE (sizeof carCANFilterList / sizeof(CANId_t)) + +static void assert(bool); + +CANDATA_t dataBuf, resultBuf; +uint64_t data = 0xdeadbeef12345678; + +/* + * NOTE: This test must be run with car CAN in loopback mode + * TODO: automate this, either with arguments to BSP or #define + */ + +void Task1(void *p_arg) { + (void) p_arg; + + CPU_Init(); + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + + CANbus_Init(CARCAN, carCANFilterList, NUM_CARCAN_FILTERS); + + dataBuf.ID = CHARGE_ENABLE; // First, send a value that we want to be able to receive + memcpy(&dataBuf.data, &data, sizeof data); + + assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); + assert(CANbus_Read(&resultBuf, true, CARCAN) == SUCCESS); + assert(memcmp(&dataBuf, &resultBuf, sizeof dataBuf) == 0); // TODO: make sure that all 8 data bytes are copied + + dataBuf.ID = ODOMETER_AMPHOURS; // Now, send a message that we shouldn't receive + assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); + assert(CANbus_Read(&resultBuf, false, CARCAN) == ERROR); // check that no can message is read + + // Now send a bunch of messages that should be ignored, followed by those that shouldn't + for (int i=0; i<10; i++) { + assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); + } + + dataBuf.ID = BPS_TRIP; + assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); + dataBuf.ID = STATE_OF_CHARGE; + assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); + dataBuf.ID = SUPPLEMENTAL_VOLTAGE; + assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); + + // Make sure that only three messages make it through + assert(CANbus_Read(&resultBuf, true, CARCAN) == SUCCESS); + assert(resultBuf.ID == BPS_TRIP); + assert(CANbus_Read(&resultBuf, true, CARCAN) == SUCCESS); + assert(resultBuf.ID == STATE_OF_CHARGE); + assert(CANbus_Read(&resultBuf, true, CARCAN) == SUCCESS); + assert(resultBuf.ID == SUPPLEMENTAL_VOLTAGE); + assert(CANbus_Read(&resultBuf, false, CARCAN) == ERROR); // No more messages + + printf("Success!\r\n"); + for (;;); +} + +int main(void){ //initialize things and spawn task + OS_ERR err; + OSInit(&err); + if(err != OS_ERR_NONE){ + printf("OS error code %d\n\r",err); + } + + BSP_UART_Init(UART_2); + + OSTaskCreate( + (OS_TCB*)&Task1_TCB, + (CPU_CHAR*)"Task1", + (OS_TASK_PTR)Task1, + (void*)NULL, + (OS_PRIO)4, + (CPU_STK*)Task1_Stk, + (CPU_STK_SIZE)STACK_SIZE/10, + (CPU_STK_SIZE)STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), + (OS_ERR*)&err + ); + + + if (err != OS_ERR_NONE) { + printf("Task1 error code %d\n\r", err); + } + OSStart(&err); + if (err != OS_ERR_NONE) { + printf("OS error code %d\n\r", err); + } + return 0; + +} + +static void assert(bool cond) { + if (!cond) __asm("bkpt"); +} \ No newline at end of file diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 68a964a70..8d0c32265 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -28,29 +28,38 @@ #include "UpdateDisplay.h" #include "CANConfig.h" +/*** Constants ***/ +#define READY_MSG 0x4444 +#define STACK_SIZE 128 /*** Task components ***/ static OS_TCB ManagerTask_TCB; static OS_TCB ExceptionTaskTCB; static OS_TCB OSErrorTaskTCB; +//static OS_TCB BPSSim_TCB; +//static OS_TCB MotorSim_TCB; + static CPU_STK ManagerTask_Stk[DEFAULT_STACK_SIZE]; static CPU_STK ExceptionTaskStk[DEFAULT_STACK_SIZE]; static CPU_STK OSErrorTaskStk[DEFAULT_STACK_SIZE]; +//static CPU_STK BPSSim_Stk[STACK_SIZE]; +//static CPU_STK MotorSim_Stk[STACK_SIZE]; + -/*** Constants ***/ -#define READY_MSG 0x4444 /*** Globals ***/ -OS_SEM Ready_Sema4; +OS_SEM TestReady_Sema4; +OS_SEM TestDone_Sema4; // Assertion function for OS errors void checkOSError(OS_ERR err) { if (err != OS_ERR_NONE) { printf("OS error code %d\n", err); + __asm("bkpt"); } } @@ -68,19 +77,19 @@ void ExceptionTask(void* test_callbacks) { OS_ERR err; if (test_callbacks == NULL) { - printf("\n\rTesting exceptions without callback functions"); + printf("\n\n\rTesting exceptions without callback functions"); } else { - printf("\n\rTesting exceptions with callback functions"); + printf("\n\n\rTesting exceptions with callback functions"); } // Throw a priority 2 exception - printf("\n\rThrowing priority level 2 exception"); + printf("\n\n\rThrowing priority level 2 exception"); exception_t prio2Exception = {.prio = PRI_RECOV, .message = "\n\rprio2 exception message", .callback = test_callbacks}; assertExceptionError(prio2Exception); // Throw a priority 1 exception - printf("\n\rThrowing priority level 1 exception"); + printf("\n\n\rThrowing priority level 1 exception"); exception_t prio1Exception = {.prio = PRI_NONRECOV, .message = "\n\rprio1 exception message", .callback = test_callbacks}; - OSSemPost(&Ready_Sema4, OS_OPT_POST_1, &err); // Alert manager task that the test is almost finished + OSSemPost(&TestReady_Sema4, OS_OPT_POST_1, &err); // Alert manager task that the test is almost finished assertExceptionError(prio1Exception); printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); @@ -95,13 +104,134 @@ void OSErrorTask(void* arg) { CPU_TS ts; printf("\n\rasserting an OS error"); OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &test_err); - OSSemPost(&Ready_Sema4, OS_OPT_POST_1, &err); + OSSemPost(&TestReady_Sema4, OS_OPT_POST_1, &err); assertOSError(OS_MAIN_LOC, test_err); printf("\n\rassertOSError test failed: assertion did not immediately result in an unrecoverable fault"); while(1){}; } +/* void MotorSim(void *p_arg){ + printf("\n\rIn MotorSim"); + OS_ERR err; + //CANDATA_t dataBuf = {0}; + //uint16_t data = 0; + + CANDATA_t canError = {0}; + canError.ID=MOTOR_STATUS; + + + for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { + + + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + uint16_t tritiumError = (0x01<>1; + *((uint16_t*)(&canError.data[4])) = tritiumError; + printf("\n\rNow sending: %d", tritiumError); + + // Send error messages to the leader board + if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + } + + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSSemPost(&TestReady_Sema4, OS_OPT_POST_1, &err); // Alert manager task that the test is almost finished + + + } + + + +} + */ + + + +/* + +void BPSSim(void *p_arg){ + + OS_ERR err; + + //CANDATA_t dataBuf; // A buffer in which we can store the messages we read + //uint16_t data = 0; + + // do { + // ErrorStatus status = CANbus_Read(&dataBuf, false, MOTORCAN); + // if (status != SUCCESS) { + // printf("\n\rCANbus Read error status: %d\n\r", status); + // } else { + // data = *((uint16_t*)(&dataBuf.data[0])); + // printf("\n\rWaiting for start. Read: %d", data); + // } + // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + // } while (data != READY_MSG); + + CANDATA_t chargeMsg; + chargeMsg.ID = CHARGE_ENABLE; + *(uint64_t*)(&chargeMsg.data) = 0; + chargeMsg.idx = 0; + + // Message for BPS Fault + CANDATA_t tripBPSMsg; + tripBPSMsg.ID = BPS_TRIP; + *(uint64_t*)(&tripBPSMsg.data) = 0; + tripBPSMsg.idx = 0; + + + + + // Send five charge enable messages so the contactors get flipped on + chargeMsg.data[0] = true; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); + } + + // Send five charge disable messages to test prio-2 disable contactor callback + // Fault state should turn off contactors but not enter a nonrecoverable fault + chargeMsg.data[0] = false; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent disable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); + } + + // Send five more charge enable messages so the contactors get flipped on again + chargeMsg.data[0] = true; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); + } + + // Send a trip message of 1 (trip) + // Note: trip messages are not usually sent, + // so any trip message (even 0) should be a concern. + // Maybe we should handle them differently? + *(uint64_t*)(&tripBPSMsg.data) = 1; + CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); + printf("\nSent trip message %d", tripBPSMsg.data[0]); + + //dataBuf.ID = CARDATA; + *((uint16_t*)(&dataBuf.data[0])) = READY_MSG; + //CANbus_Send(dataBuf, CAN_NON_BLOCKING, CARCAN); + + + while(1){}; +} + */ + + + + + + + // Task creation functions // Initializes FaultState @@ -242,7 +372,59 @@ void createOSErrorTask(void) { } +/* // The bps-sim task moved here as BPSSim for Loopback mode testing +void createBPSSimTask(void) { + OS_ERR err; + OSTaskCreate( + (OS_TCB*)&BPSSim_TCB, + (CPU_CHAR*)"bps-sim", + (OS_TASK_PTR)BPSSim, + (void*)NULL, + (OS_PRIO)4, // May need to change this + (CPU_STK*)BPSSim_Stk, + (CPU_STK_SIZE)STACK_SIZE/10, + (CPU_STK_SIZE)STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), + (OS_ERR*)&err + ); + checkOSError(err); + + + if (err != OS_ERR_NONE) { + printf("bps sim error code %d\n\r", err); + } +} */ + +/* +void createMotorSimTask(void){ + OS_ERR err; + + OSTaskCreate( + (OS_TCB*)&MotorSim_TCB, + (CPU_CHAR*)"Task1", + (OS_TASK_PTR)MotorSim, + (void*)NULL, + (OS_PRIO)4, // May need to change this + (CPU_STK*)MotorSim_Stk, + (CPU_STK_SIZE)STACK_SIZE/10, + (CPU_STK_SIZE)STACK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)NULL, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), + (OS_ERR*)&err + ); + + if (err != OS_ERR_NONE) { + printf("Task error code %d\n", err); + } +} + + */ @@ -255,7 +437,7 @@ void Task_ManagerTask(void* arg) { CANbus_Init(MOTORCAN, NULL, 0); CANbus_Init(CARCAN, NULL, 0); Contactors_Init(); - OSSemCreate(&Ready_Sema4, "Ready Flag Semaphore", 0, &err); + OSSemCreate(&TestReady_Sema4, "Ready Flag Semaphore", 0, &err); //ErrorStatus errorCode; /*** test */ @@ -277,14 +459,14 @@ void Task_ManagerTask(void* arg) { // Both with and without callback functions // Successful if exception message and callback message (if applicable) are printed // and the fail message is not printed (tasks are stopped when they assert an error) - printf("\n\r=========== Testing exception priorities 1 and 2 ==========="); + printf("\n\n\r=========== Testing exception priorities 1 and 2 ==========="); // Test level 1 & 2 exceptions without callbacks createExceptionTask(NULL); checkOSError(err); createFaultState(); checkOSError(err); - OSSemPend(&Ready_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); // Wait for task to finish + OSSemPend(&TestReady_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); // Wait for task to finish checkOSError(err); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // extra time for the task finished checkOSError(err); @@ -298,7 +480,7 @@ void Task_ManagerTask(void* arg) { checkOSError(err); createFaultState(); checkOSError(err); - OSSemPend(&Ready_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); + OSSemPend(&TestReady_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); OSTaskDel(&ExceptionTaskTCB, &err); @@ -310,13 +492,13 @@ void Task_ManagerTask(void* arg) { // Creates an OS error by pending on a mutex that isn't created // Successful if it prints the OS Error code // and doesn't print the fail message (task is stopped by asserting an error) - printf("\n\r=========== Testing OS assert ==========="); + printf("\n\n\r=========== Testing OS assert ==========="); createOSErrorTask(); checkOSError(err); createFaultState(); checkOSError(err); - OSSemPend(&Ready_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); + OSSemPend(&TestReady_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); checkOSError(err); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); @@ -326,22 +508,36 @@ void Task_ManagerTask(void* arg) { // Test exceptions in ReadTritium by creating the tasks // and sending faults using the motor sim on Renode - printf("\n\r=========== Testing ReadTritium ==========="); + printf("\n\n\r=========== Testing ReadTritium ==========="); + + //CANDATA_t dataBuf = {0}; + //uint16_t data = 0; + + CANDATA_t canError = {0}; + canError.ID=MOTOR_STATUS; - CANDATA_t canMessage = {0}; - canMessage.ID = CARDATA; - canMessage.idx = 0; - *(uint16_t*)(&canMessage.data[0]) = READY_MSG; for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { + uint16_t tritiumError = (0x01<>1; // Change to i-1? + *((uint16_t*)(&canError.data[4])) = tritiumError; + createFaultState(); createReadTritium(); - // Send a message to the motor to tell it to start sending stuff + printf("\n\rNow sending: %d", tritiumError); + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish printf("\n\rShould be testing Tritium error %d", i); - CANbus_Send(canMessage, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + } + OSTaskDel(&ReadTritium_TCB, &err); + checkOSError(err); OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); } @@ -351,13 +547,66 @@ void Task_ManagerTask(void* arg) { createFaultState(); checkOSError(err); createReadCarCAN(); + //createBPSSimTask(); checkOSError(err); - CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); + //CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); //uint16_t canMsgData = 0; + + CANDATA_t chargeMsg; + chargeMsg.ID = CHARGE_ENABLE; + *(uint64_t*)(&chargeMsg.data) = 0; + chargeMsg.idx = 0; + + // Message for BPS Fault + CANDATA_t tripBPSMsg; + tripBPSMsg.ID = BPS_TRIP; + *(uint64_t*)(&tripBPSMsg.data) = 0; + tripBPSMsg.idx = 0; + + + + + // Send five charge enable messages so the contactors get flipped on + chargeMsg.data[0] = true; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + + // Send five charge disable messages to test prio-2 disable contactor callback + // Fault state should turn off contactors but not enter a nonrecoverable fault + chargeMsg.data[0] = false; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent disable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + + // Send five more charge enable messages so the contactors get flipped on again + chargeMsg.data[0] = true; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors + printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); + printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + + // Send a trip message of 1 (trip) + // Note: trip messages are not usually sent, + // so any trip message (even 0) should be a concern. + // Maybe we should handle them differently? + *(uint64_t*)(&tripBPSMsg.data) = 1; + CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); + printf("\nSent trip message %d", tripBPSMsg.data[0]); for (int i = 0; i < 20; i++) { - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - //OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_HMSM_STRICT, &err); + //int x = 0; //for (int i = 0; i < 9999999; i++){x+=1;} } @@ -368,13 +617,26 @@ void Task_ManagerTask(void* arg) { printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + OSTaskDel(&ReadCarCAN_TCB, &err); + checkOSError(err); + OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); - printf("\n\r=========== Test UpdateDisplay ==========="); + printf("\n\n\r=========== Test UpdateDisplay ==========="); // Might be able to test if we UpdateDisplay_Init() and then make the task // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. - UpdateDisplay_Init(); + //UpdateDisplay_Init(); + // Call update display put next to overflow the queue (actual issue) + createUpdateDisplay(); createFaultState(); + OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + OSTaskDel(&UpdateDisplay_TCB, &err); + checkOSError(err); + OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); + } @@ -415,3 +677,4 @@ int main(void) { while(1) {} } + From cd55331d4ef779374cf7e4c285223e5ef578e54e Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 22 Jun 2023 04:13:55 +0000 Subject: [PATCH 071/141] Test now runs on LoopBack mode. However, the weird print issue still happens if you let it run through a second round. --- Tests/Test_FaultThread_Exceptions.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 8d0c32265..4c0c93de0 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -529,8 +529,10 @@ void Task_ManagerTask(void* arg) { printf("\n\rShould be testing Tritium error %d", i); if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + printf("\n\rShould be testing Tritium error %d", i); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + printf("\n\rShould be testing Tritium error %d", i); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); } @@ -585,10 +587,16 @@ void Task_ManagerTask(void* arg) { OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); printf("\n\rChargeEnable: %d", ChargeEnable_Get()); } + + for(int i = 0; i<2; i++){ + printf("\nDelay %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } // Send five more charge enable messages so the contactors get flipped on again chargeMsg.data[0] = true; - for(int i = 0; i<3; i++){ + for(int i = 0; i<5; i++){ CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); printf("\nSent enable chargeMsg %d", i); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); @@ -605,11 +613,6 @@ void Task_ManagerTask(void* arg) { *(uint64_t*)(&tripBPSMsg.data) = 1; CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); printf("\nSent trip message %d", tripBPSMsg.data[0]); - for (int i = 0; i < 20; i++) { - - //int x = 0; - //for (int i = 0; i < 9999999; i++){x+=1;} - } // By now, the BPS Trip message should have been sent //OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors @@ -628,6 +631,7 @@ void Task_ManagerTask(void* arg) { //UpdateDisplay_Init(); // Call update display put next to overflow the queue (actual issue) + // Updating display without updateDisplayInit() createUpdateDisplay(); createFaultState(); OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); @@ -637,6 +641,8 @@ void Task_ManagerTask(void* arg) { OSTaskDel(&FaultState_TCB, &err); checkOSError(err); + // overflow the queue + } From 9739c3678358e50fb1e34c9458442743edbc0940 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 22 Jun 2023 18:00:49 +0000 Subject: [PATCH 072/141] Updated comments and added a print statement to readTritium for motor restarts. --- Apps/Src/ReadTritium.c | 1 + Tests/Test_FaultThread_Exceptions.c | 364 +++++++--------------------- 2 files changed, 95 insertions(+), 270 deletions(-) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 30b428cd3..6aa1af16b 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -51,6 +51,7 @@ static void assertTritiumError(uint16_t motor_err){ assertExceptionError(hallErrorPrio1); // Fail out by entering nonrecoverable fault } else { hall_fault_cnt++; + printf("\n\rRestarting motor"); MotorController_Restart(); //re-initialize motor return; } diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 4c0c93de0..704219f19 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -5,8 +5,9 @@ * It does this by testing the assertion functions for each priority option * and creating and faulting tasks using the car and bps sim on Renode * - * This test is run in conjunction with Test_motor_FaultThread_Exceptions - * and Test_car_FaultThread_Exceptions on Renode + * This test is run in LoopBack mode with all messages sent and received by the LeaderBoard. + * However, it can be run in conjunction with motor-sim and car-sim + * ( which don't do anything) when simulated to appease Renode * * @file * @author Madeleine Lee (madeleinercflee@utexas.edu) @@ -37,16 +38,11 @@ static OS_TCB ManagerTask_TCB; static OS_TCB ExceptionTaskTCB; static OS_TCB OSErrorTaskTCB; -//static OS_TCB BPSSim_TCB; -//static OS_TCB MotorSim_TCB; static CPU_STK ManagerTask_Stk[DEFAULT_STACK_SIZE]; static CPU_STK ExceptionTaskStk[DEFAULT_STACK_SIZE]; static CPU_STK OSErrorTaskStk[DEFAULT_STACK_SIZE]; -//static CPU_STK BPSSim_Stk[STACK_SIZE]; -//static CPU_STK MotorSim_Stk[STACK_SIZE]; - @@ -111,126 +107,6 @@ void OSErrorTask(void* arg) { } -/* void MotorSim(void *p_arg){ - printf("\n\rIn MotorSim"); - OS_ERR err; - //CANDATA_t dataBuf = {0}; - //uint16_t data = 0; - - CANDATA_t canError = {0}; - canError.ID=MOTOR_STATUS; - - - for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { - - - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - uint16_t tritiumError = (0x01<>1; - *((uint16_t*)(&canError.data[4])) = tritiumError; - printf("\n\rNow sending: %d", tritiumError); - - // Send error messages to the leader board - if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - } - - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSSemPost(&TestReady_Sema4, OS_OPT_POST_1, &err); // Alert manager task that the test is almost finished - - - } - - - -} - */ - - - -/* - -void BPSSim(void *p_arg){ - - OS_ERR err; - - //CANDATA_t dataBuf; // A buffer in which we can store the messages we read - //uint16_t data = 0; - - // do { - // ErrorStatus status = CANbus_Read(&dataBuf, false, MOTORCAN); - // if (status != SUCCESS) { - // printf("\n\rCANbus Read error status: %d\n\r", status); - // } else { - // data = *((uint16_t*)(&dataBuf.data[0])); - // printf("\n\rWaiting for start. Read: %d", data); - // } - // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - // } while (data != READY_MSG); - - CANDATA_t chargeMsg; - chargeMsg.ID = CHARGE_ENABLE; - *(uint64_t*)(&chargeMsg.data) = 0; - chargeMsg.idx = 0; - - // Message for BPS Fault - CANDATA_t tripBPSMsg; - tripBPSMsg.ID = BPS_TRIP; - *(uint64_t*)(&tripBPSMsg.data) = 0; - tripBPSMsg.idx = 0; - - - - - // Send five charge enable messages so the contactors get flipped on - chargeMsg.data[0] = true; - for(int i = 0; i<3; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); - } - - // Send five charge disable messages to test prio-2 disable contactor callback - // Fault state should turn off contactors but not enter a nonrecoverable fault - chargeMsg.data[0] = false; - for(int i = 0; i<3; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent disable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); - } - - // Send five more charge enable messages so the contactors get flipped on again - chargeMsg.data[0] = true; - for(int i = 0; i<3; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); - } - - // Send a trip message of 1 (trip) - // Note: trip messages are not usually sent, - // so any trip message (even 0) should be a concern. - // Maybe we should handle them differently? - *(uint64_t*)(&tripBPSMsg.data) = 1; - CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); - printf("\nSent trip message %d", tripBPSMsg.data[0]); - - //dataBuf.ID = CARDATA; - *((uint16_t*)(&dataBuf.data[0])) = READY_MSG; - //CANbus_Send(dataBuf, CAN_NON_BLOCKING, CARCAN); - - - while(1){}; -} - */ - - - - - - // Task creation functions @@ -372,60 +248,6 @@ void createOSErrorTask(void) { } -/* // The bps-sim task moved here as BPSSim for Loopback mode testing -void createBPSSimTask(void) { - OS_ERR err; - - OSTaskCreate( - (OS_TCB*)&BPSSim_TCB, - (CPU_CHAR*)"bps-sim", - (OS_TASK_PTR)BPSSim, - (void*)NULL, - (OS_PRIO)4, // May need to change this - (CPU_STK*)BPSSim_Stk, - (CPU_STK_SIZE)STACK_SIZE/10, - (CPU_STK_SIZE)STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)NULL, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), - (OS_ERR*)&err - ); - checkOSError(err); - - - if (err != OS_ERR_NONE) { - printf("bps sim error code %d\n\r", err); - } -} */ - -/* -void createMotorSimTask(void){ - OS_ERR err; - - OSTaskCreate( - (OS_TCB*)&MotorSim_TCB, - (CPU_CHAR*)"Task1", - (OS_TASK_PTR)MotorSim, - (void*)NULL, - (OS_PRIO)4, // May need to change this - (CPU_STK*)MotorSim_Stk, - (CPU_STK_SIZE)STACK_SIZE/10, - (CPU_STK_SIZE)STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)NULL, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), - (OS_ERR*)&err - ); - - if (err != OS_ERR_NONE) { - printf("Task error code %d\n", err); - } -} - - */ - // A high-priority task that manages other tasks and runs the tests @@ -440,19 +262,7 @@ void Task_ManagerTask(void* arg) { OSSemCreate(&TestReady_Sema4, "Ready Flag Semaphore", 0, &err); //ErrorStatus errorCode; - /*** test */ - - - // CANDATA_t testmsg = {0}; - // testmsg.ID=MOTOR_STATUS; - // testmsg.idx=0; - // *((uint16_t*)(&testmsg.data[0])) = 4444; - // while (1) { - // CANbus_Send(testmsg, CAN_BLOCKING, MOTORCAN); - // } - - /****/ while (1) { // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 @@ -506,13 +316,10 @@ void Task_ManagerTask(void* arg) { checkOSError(err); OSTaskDel(&FaultState_TCB, &err); - // Test exceptions in ReadTritium by creating the tasks - // and sending faults using the motor sim on Renode + // Test exceptions in ReadTritium by creating the tasks and sending faults + // TODO: Change ReadTrititum so that we can print out the error code and not just a default message printf("\n\n\r=========== Testing ReadTritium ==========="); - //CANDATA_t dataBuf = {0}; - //uint16_t data = 0; - CANDATA_t canError = {0}; canError.ID=MOTOR_STATUS; @@ -528,12 +335,10 @@ void Task_ManagerTask(void* arg) { OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish printf("\n\rShould be testing Tritium error %d", i); if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - printf("\n\rShould be testing Tritium error %d", i); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - printf("\n\rShould be testing Tritium error %d", i); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + for (int i = 0; i < 4; i++) { // Faults if greater than restart threshold (3). Maybe we should change it to equal to threshold? + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + } } OSTaskDel(&ReadTritium_TCB, &err); @@ -541,78 +346,86 @@ void Task_ManagerTask(void* arg) { OSTaskDel(&FaultState_TCB, &err); checkOSError(err); - } - - // Tests exceptions in ReadCarCAN by creating the tasks - // and sending messages using the bps sim on Renode - printf("\n\r=========== Testing ReadCarCAN ==========="); + } + + // Tests exceptions in ReadCarCAN by creating the tasks and sending messages + // Causes a weird issue where the last things that were printed are + // reprinted sixteen times all at once with some odd changes + // if the messages are sent enough times + // ex: 3 enable, 3 disable, 2 delay, 5 enable works + // but 5 enable ... doesn't + // I think the issue may occur if you let the test loop around + // enough, though. + printf("\n\n\r=========== Testing ReadCarCAN ==========="); createFaultState(); checkOSError(err); createReadCarCAN(); - //createBPSSimTask(); checkOSError(err); - //CANbus_Send(canMessage, CAN_BLOCKING, CARCAN); - //uint16_t canMsgData = 0; + + // Message for charging enable/disable + CANDATA_t chargeMsg; + chargeMsg.ID = CHARGE_ENABLE; + *(uint64_t*)(&chargeMsg.data) = 0; + chargeMsg.idx = 0; + + // Message for BPS Fault + CANDATA_t tripBPSMsg; + tripBPSMsg.ID = BPS_TRIP; + *(uint64_t*)(&tripBPSMsg.data) = 0; + tripBPSMsg.idx = 0; - CANDATA_t chargeMsg; - chargeMsg.ID = CHARGE_ENABLE; - *(uint64_t*)(&chargeMsg.data) = 0; - chargeMsg.idx = 0; - // Message for BPS Fault - CANDATA_t tripBPSMsg; - tripBPSMsg.ID = BPS_TRIP; - *(uint64_t*)(&tripBPSMsg.data) = 0; - tripBPSMsg.idx = 0; - + // Send charge enable messages + chargeMsg.data[0] = true; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + // Send five charge disable messages to test prio-2 disable contactor callback + // Fault state should turn off contactors but not enter a nonrecoverable fault + chargeMsg.data[0] = false; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent disable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } - // Send five charge enable messages so the contactors get flipped on - chargeMsg.data[0] = true; - for(int i = 0; i<3; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } + // Pause the delivery of messages to trigger the canWatchTimer + //TODO: Can't tell that anything is happening here at the moment + for(int i = 0; i<2; i++){ + printf("\nDelay %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + + // Send five more charge enable messages so the contactors get flipped on again + chargeMsg.data[0] = true; + for(int i = 0; i < 5; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\nSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + //TODO: Would these ever be on? Since there's no minion board we may not be able to check + printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors + printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); + printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); - // Send five charge disable messages to test prio-2 disable contactor callback - // Fault state should turn off contactors but not enter a nonrecoverable fault - chargeMsg.data[0] = false; - for(int i = 0; i<3; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent disable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - - for(int i = 0; i<2; i++){ - printf("\nDelay %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } + // Send a trip message of 1 (trip) + // TODO: trip messages are not usually sent, + // so any trip message (even 0) should be a concern. + // Need to change things to handle them differently (might be in ignition fix PR already) + *(uint64_t*)(&tripBPSMsg.data) = 1; + CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); + printf("\nSent trip message %d", tripBPSMsg.data[0]); + OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); - // Send five more charge enable messages so the contactors get flipped on again - chargeMsg.data[0] = true; - for(int i = 0; i<5; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors - printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); - printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); - - // Send a trip message of 1 (trip) - // Note: trip messages are not usually sent, - // so any trip message (even 0) should be a concern. - // Maybe we should handle them differently? - *(uint64_t*)(&tripBPSMsg.data) = 1; - CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); - printf("\nSent trip message %d", tripBPSMsg.data[0]); // By now, the BPS Trip message should have been sent //OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors @@ -628,20 +441,33 @@ void Task_ManagerTask(void* arg) { printf("\n\n\r=========== Test UpdateDisplay ==========="); // Might be able to test if we UpdateDisplay_Init() and then make the task // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. - //UpdateDisplay_Init(); // Call update display put next to overflow the queue (actual issue) - // Updating display without updateDisplayInit() + // Note: currently gets stuck, so you may want to comment this section out to test ReadCarCAN + createUpdateDisplay(); createFaultState(); - OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); OSTaskDel(&UpdateDisplay_TCB, &err); checkOSError(err); OSTaskDel(&FaultState_TCB, &err); checkOSError(err); - // overflow the queue + UpdateDisplay_Init(); + createUpdateDisplay(); + createFaultState(); + for (int i = 0; i < 10; i++) { + UpdateDisplay_SetPage(0); //update display put next is static so I'll try this instead + // It doesn't seem to work, though. + // I appear to be getting stuck in txfifo_is_full instead + } + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + OSTaskDel(&UpdateDisplay_TCB, &err); + checkOSError(err); + OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); } @@ -674,8 +500,6 @@ int main(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err ); - - checkOSError(err); OSStart(&err); From 015367b1df51076ae892e805b719868aad848598 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 24 Jun 2023 09:53:03 +0000 Subject: [PATCH 073/141] Beginning work for new fault thread mechanism that spawns new tasks of high or low priority to deal with errors. Created task files, made priority and macro changes in Tasks, add comments for planning. --- Apps/Inc/Tasks.h | 21 +++++++---- Apps/Src/FaultHighPrio.c | 16 +++++++++ Apps/Src/FaultLowPrio.c | 78 ++++++++++++++++++++++++++++++++++++++++ Apps/Src/ReadTritium.c | 17 +++++---- Apps/Src/Tasks.c | 4 +-- Drivers/Src/Display.c | 9 +++-- 6 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 Apps/Src/FaultHighPrio.c create mode 100644 Apps/Src/FaultLowPrio.c diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 02ed8974a..8ffe6cc17 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -19,11 +19,13 @@ * Priority Definitions */ #define TASK_FAULT_STATE_PRIO 1 +#define TASK_FAULT_HIGHPRIO_PRIO 1 #define TASK_INIT_PRIO 2 -#define TASK_READ_TRITIUM_PRIO 3 -#define TASK_SEND_TRITIUM_PRIO 4 -#define TASK_READ_CAR_CAN_PRIO 5 -#define TASK_UPDATE_DISPLAY_PRIO 6 +#define TASK_FAULT_LOWPRIO_PRIO 3 +#define TASK_READ_TRITIUM_PRIO 4 +#define TASK_SEND_TRITIUM_PRIO 5 +#define TASK_READ_CAR_CAN_PRIO 6 +#define TASK_UPDATE_DISPLAY_PRIO 7 #define TASK_SEND_CAR_CAN_PRIO 8 #define TASK_TELEMETRY_PRIO 9 @@ -67,10 +69,12 @@ void Task_Telemetry(void* p_arg); + + /** * TCBs */ -extern OS_TCB FaultState_TCB; +extern OS_TCB FaultState_TCB; // To be deleted extern OS_TCB Init_TCB; extern OS_TCB SendTritium_TCB; extern OS_TCB ReadCarCAN_TCB; @@ -84,7 +88,7 @@ extern OS_TCB Telemetry_TCB; /** * Stacks */ -extern CPU_STK FaultState_Stk[TASK_FAULT_STATE_STACK_SIZE]; +extern CPU_STK FaultState_Stk[TASK_FAULT_STATE_STACK_SIZE]; // To be deleted extern CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; extern CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; extern CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; @@ -130,7 +134,10 @@ typedef enum{ OS_CANDRIVER_LOC = 0x400, OS_MOTOR_CONNECTION_LOC = 0x800, OS_DISPLAY_LOC = 0x1000, - OS_FAULT_STATE_LOC = 0x2000 + OS_FAULT_STATE_LOC = 0x2000, // to be deleted + OS_FAULT_HIGHPRIO_LOC = 0x2000, + OS_FAULT_LOWPRIO_LOC = 0x4000 + } os_error_loc_t; /** diff --git a/Apps/Src/FaultHighPrio.c b/Apps/Src/FaultHighPrio.c new file mode 100644 index 000000000..8030e9568 --- /dev/null +++ b/Apps/Src/FaultHighPrio.c @@ -0,0 +1,16 @@ +/** + * @copyright Copyright (c) 2023 UT Longhorn Racing Solar + * @file FaultHighPrio.c + * @brief Fault Handler task spawn template for high-priority faults. + * + * This contains a task spawned by error assertion functions to handle faults. + * It pends on a mutex to ensure only one high-prio task is handled at a time, + * Executes a callback function passed in as an argument, + * And enters a nonrecoverable fault handler to stop the car. + * + * The goal of this system is to localize error handling + * and allow high priority errors to be addressed as soon as possible + * while also making sure there are no blocking calls in timer callbacks. + * + * @author Madeleine Lee (KnockbackNemo) +*/ \ No newline at end of file diff --git a/Apps/Src/FaultLowPrio.c b/Apps/Src/FaultLowPrio.c new file mode 100644 index 000000000..a653c7b98 --- /dev/null +++ b/Apps/Src/FaultLowPrio.c @@ -0,0 +1,78 @@ +/** + * @copyright Copyright (c) 2023 UT Longhorn Racing Solar + * + * @file FaultLowPrio.c + * @brief Fault Handler task spawn template for low-priority faults. + * + * This contains a task spawned by error assertion functions to handle faults. + * It pends on a mutex to ensure only one low-prio task is handled at a time, + * Executes a callback function passed in as an argument, + * And deletes itself once finished. + * + * The goal of this system is to localize error handling + * and allow high priority errors to be addressed as soon as possible + * while also making sure there are no blocking calls in timer callbacks. + * + * @author Madeleine Lee (KnockbackNemo) +*/ + +#include "Tasks.h" + +/*** Macros ***/ +#define TASK_FAULT_LOWPRIO_STK_SIZE DEFAULT_STACK_SIZE + +/*** Variables ***/ +static OS_TCB FaultLowPrio_TCB[3]; // Allows three low-prio errors at once +static CPU_STK FaultLowPrio_Stk[3]; // An arbitrary number, but we shouldn't reach it + +static thread_counter = 0; // To keep track of which stack/tcb to use + + + + +bool Spawn_LowPrio_FaultThread(exception_t exception) { + OS_ERR err; + + // Create the task with unique exception message/callback + OSTaskCreate( + (OS_TCB*)&FaultLowPrio_TCB[thread_counter], + (CPU_CHAR*)"FaultLowPrio", + (OS_TASK_PTR)Task_FaultLowPrio, + (void*)((void*)&exception), // must be passed in as a void * + (OS_PRIO)TASK_FAULT_LOWPRIO_PRIO, // Lower than init task but higher than others + (CPU_STK*)&FaultLowPrio_Stk[thread_counter], + (CPU_STK_SIZE)TASK_FAULT_LOWPRIO_STK_SIZE/10, + (CPU_STK_SIZE)TASK_FAULT_LOWPRIO_STK_SIZE, + (OS_MSG_QTY)0, + (OS_TICK)0, + (void*)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR*)&err + ); + assertOSError(OS_FAULT_LOWPRIO_LOC, err); + + thread_counter = (thread_counter + 1) % 3; // tasks should get mutex in order + // So we should be able to reuse task resources starting with the oldest + + +} + +void Task_FaultLowPrio(void *p_arg) { + OS_ERR err; + + + // Ensure no other low-priority faults are already being handled + // to avoid round-robin fault handling + + // Print the exception message + + // Run the callback function if it isn't null + + // Allow other low-priority fault threads to run + + // Fault handling thread has completed its job and will now self-destruct + + OSTaskDel(NULL, &err); // Delete this currently-running task + assertOSError(OS_FAULT_LOWPRIO_LOC, err); + +} \ No newline at end of file diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 6aa1af16b..9a56f3b11 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -35,21 +35,24 @@ tritium_error_code_t MotorController_getTritiumError(void){ /** * @brief Assert Error if Tritium sends error. - * When asserted, Fault state's exception will be set and the fault thread will run - * Asserts an error that either restarts the hall sensor or enters a nonrecoverable fault + * When asserted, a new task will be spawned to handle the fault + * Creates either a low-priority task that restarts the hall sensor + * or a high priority task that enters a nonrecoverable fault * @param motor_err Bitmap which has motor error codes */ static void assertTritiumError(uint16_t motor_err){ static uint8_t hall_fault_cnt = 0; //trip counter if(motor_err != T_NONE){ if(motor_err != T_HALL_SENSOR_ERR){ - exception_t notHallError = {PRI_NONRECOV, "this is Tritium, not-hall-sensor error", NULL}; - assertExceptionError(notHallError); + //create a high priority task that will run the given callback + //exception_t notHallError = {PRI_NONRECOV, "this is Tritium, not-hall-sensor error", NULL}; + //assertExceptionError(notHallError); }else{ if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out - exception_t hallErrorPrio1 = {PRI_NONRECOV, "hall sensor errors have exceeded restart threshold", NULL}; - assertExceptionError(hallErrorPrio1); // Fail out by entering nonrecoverable fault - } else { + // create a high priority task that will run a different message/callback + //exception_t hallErrorPrio1 = {PRI_NONRECOV, "hall sensor errors have exceeded restart threshold", NULL}; + //assertExceptionError(hallErrorPrio1); // Fail out by entering nonrecoverable fault + } else { // Try resetarting the motor hall_fault_cnt++; printf("\n\rRestarting motor"); MotorController_Restart(); //re-initialize motor diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 8a0c225fe..f01b5ff00 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -13,7 +13,7 @@ /** * TCBs */ -OS_TCB FaultState_TCB; +OS_TCB FaultState_TCB; // To be deleted OS_TCB Init_TCB; OS_TCB SendTritium_TCB; OS_TCB ReadCarCAN_TCB; @@ -25,7 +25,7 @@ OS_TCB Telemetry_TCB; /** * Stacks */ -CPU_STK FaultState_Stk[TASK_FAULT_STATE_STACK_SIZE]; +CPU_STK FaultState_Stk[TASK_FAULT_STATE_STACK_SIZE]; // To be deleted CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 1cdbe4bf1..41b1c215a 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -149,9 +149,14 @@ static void callback_displayError(void){ } } +/** + * @brief Spawns a low-priority fault handler task if there is an error + * @param err the display error to check +*/ void assertDisplayError(DisplayError_t err){ if (err != DISPLAY_ERR_NONE){ - exception_t displayError = {PRI_RECOV, "display error", &callback_displayError}; - assertExceptionError(displayError); + // Create a new low priority task that will run the given callback + //exception_t displayError = {PRI_RECOV, "display error", &callback_displayError}; + //assertExceptionError(displayError); } } From 308b9e96f20675cac90c93ccacbaf5f6adee15c9 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 03:04:28 +0000 Subject: [PATCH 074/141] Began new redesign of error handling in which everything is localized to each task and scheduler locking is used to ensure high-priority faults are handled first. This commit includes finishing the error assertion function for the display, as well as renaming variable/function names related to assertDisplayError to reflect our new specification of using the word 'error' to describe when we have issues. --- Drivers/Inc/Display.h | 3 +++ Drivers/Src/Display.c | 27 ++++++++------------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index a92e1fabf..e542d41b8 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -39,6 +39,9 @@ typedef enum{ /** * @brief Error handler for any display errors. Call this after any display driver function. + * Restarts the display if there is an error + * or displays fault if it has reached the threshold for restart attempts + * @param err the display error code to check */ void assertDisplayError(DisplayError_t err); diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 41b1c215a..2bcc653ee 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -14,7 +14,6 @@ #include "Display.h" #include "bsp.h" // for writing to UART #include "Tasks.h" // for os and fault error codes -#include "FaultState.h" #define DISP_OUT UART_3 #define MAX_MSG_LEN 32 @@ -29,6 +28,7 @@ static const char *TERMINATOR = "\xff\xff\xff"; + DisplayError_t Display_Init(){ BSP_UART_Init(DISP_OUT); return Display_Reset(); @@ -138,25 +138,14 @@ DisplayError_t Display_Evac(uint8_t SOC_percent, uint32_t supp_mv){ return DISPLAY_ERR_NONE; } -static void callback_displayError(void){ - static uint8_t disp_fault_cnt = 0; // If faults > three times total, Display_Fault is called - if(disp_fault_cnt>RESTART_THRESHOLD){ - Display_Fault(OSErrLocBitmap, FaultBitmap); - } else { - disp_fault_cnt++; - Display_Reset(); - return; - } -} - -/** - * @brief Spawns a low-priority fault handler task if there is an error - * @param err the display error to check -*/ void assertDisplayError(DisplayError_t err){ + static uint8_t disp_fault_cnt = 0; // Keep track of the number of times the display has faulted if (err != DISPLAY_ERR_NONE){ - // Create a new low priority task that will run the given callback - //exception_t displayError = {PRI_RECOV, "display error", &callback_displayError}; - //assertExceptionError(displayError); + disp_fault_cnt++; + if (disp_fault_cnt > RESTART_THRESHOLD){ // Fault if we've reached the limit on restart attempts + Display_Fault(OS_DISPLAY_LOC, err); + } else { // Otherwise try resetting the display + Display_Reset(); + } } } From ce0b1f19f78c1f95a4ddb6b0db14df943dc6156c Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 03:05:51 +0000 Subject: [PATCH 075/141] Actually, this commit is where names get changed to replace 'fault' with 'error' --- Drivers/Inc/Display.h | 2 +- Drivers/Src/Display.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index e542d41b8..8ed8486bf 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -101,7 +101,7 @@ DisplayError_t Display_Reset(void); * @param faultCode the generic fault code (will be displayed in hex) * @returns DisplayError_t */ -DisplayError_t Display_Fault(os_error_loc_t osErrCode, fault_bitmap_t faultCode); +DisplayError_t Display_Error(os_error_loc_t osErrCode, fault_bitmap_t faultCode); /** * @brief Overwrites any processing commands and triggers the evacuation screen diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 2bcc653ee..73cb62569 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -98,7 +98,7 @@ DisplayError_t Display_Reset(){ return Display_Send(restCmd); } -DisplayError_t Display_Fault(os_error_loc_t osErrCode, fault_bitmap_t faultCode){ +DisplayError_t Display_Error(os_error_loc_t osErrCode, fault_bitmap_t faultCode){ BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); // Terminates any in progress command char faultPage[7] = "page 2"; @@ -139,11 +139,11 @@ DisplayError_t Display_Evac(uint8_t SOC_percent, uint32_t supp_mv){ } void assertDisplayError(DisplayError_t err){ - static uint8_t disp_fault_cnt = 0; // Keep track of the number of times the display has faulted + static uint8_t disp_error_cnt = 0; // Keep track of the number of times the display has an error if (err != DISPLAY_ERR_NONE){ - disp_fault_cnt++; - if (disp_fault_cnt > RESTART_THRESHOLD){ // Fault if we've reached the limit on restart attempts - Display_Fault(OS_DISPLAY_LOC, err); + disp_error_cnt++; + if (disp_error_cnt > RESTART_THRESHOLD){ // Show error screen if we've reached the limit on restart attempts + Display_Error(OS_DISPLAY_LOC, err); } else { // Otherwise try resetting the display Display_Reset(); } From 9eac2a34e424207f322ce0f05e8065d090928d1e Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 03:27:06 +0000 Subject: [PATCH 076/141] Added a currError variable to hold the current error code for inspection purposes, removed task files from the last fault state redesign attempt which we have since aborted. --- Apps/Src/FaultHighPrio.c | 16 --------- Apps/Src/FaultLowPrio.c | 78 ---------------------------------------- Drivers/Inc/Display.h | 2 +- Drivers/Src/Display.c | 4 ++- 4 files changed, 4 insertions(+), 96 deletions(-) delete mode 100644 Apps/Src/FaultHighPrio.c delete mode 100644 Apps/Src/FaultLowPrio.c diff --git a/Apps/Src/FaultHighPrio.c b/Apps/Src/FaultHighPrio.c deleted file mode 100644 index 8030e9568..000000000 --- a/Apps/Src/FaultHighPrio.c +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @copyright Copyright (c) 2023 UT Longhorn Racing Solar - * @file FaultHighPrio.c - * @brief Fault Handler task spawn template for high-priority faults. - * - * This contains a task spawned by error assertion functions to handle faults. - * It pends on a mutex to ensure only one high-prio task is handled at a time, - * Executes a callback function passed in as an argument, - * And enters a nonrecoverable fault handler to stop the car. - * - * The goal of this system is to localize error handling - * and allow high priority errors to be addressed as soon as possible - * while also making sure there are no blocking calls in timer callbacks. - * - * @author Madeleine Lee (KnockbackNemo) -*/ \ No newline at end of file diff --git a/Apps/Src/FaultLowPrio.c b/Apps/Src/FaultLowPrio.c deleted file mode 100644 index a653c7b98..000000000 --- a/Apps/Src/FaultLowPrio.c +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @copyright Copyright (c) 2023 UT Longhorn Racing Solar - * - * @file FaultLowPrio.c - * @brief Fault Handler task spawn template for low-priority faults. - * - * This contains a task spawned by error assertion functions to handle faults. - * It pends on a mutex to ensure only one low-prio task is handled at a time, - * Executes a callback function passed in as an argument, - * And deletes itself once finished. - * - * The goal of this system is to localize error handling - * and allow high priority errors to be addressed as soon as possible - * while also making sure there are no blocking calls in timer callbacks. - * - * @author Madeleine Lee (KnockbackNemo) -*/ - -#include "Tasks.h" - -/*** Macros ***/ -#define TASK_FAULT_LOWPRIO_STK_SIZE DEFAULT_STACK_SIZE - -/*** Variables ***/ -static OS_TCB FaultLowPrio_TCB[3]; // Allows three low-prio errors at once -static CPU_STK FaultLowPrio_Stk[3]; // An arbitrary number, but we shouldn't reach it - -static thread_counter = 0; // To keep track of which stack/tcb to use - - - - -bool Spawn_LowPrio_FaultThread(exception_t exception) { - OS_ERR err; - - // Create the task with unique exception message/callback - OSTaskCreate( - (OS_TCB*)&FaultLowPrio_TCB[thread_counter], - (CPU_CHAR*)"FaultLowPrio", - (OS_TASK_PTR)Task_FaultLowPrio, - (void*)((void*)&exception), // must be passed in as a void * - (OS_PRIO)TASK_FAULT_LOWPRIO_PRIO, // Lower than init task but higher than others - (CPU_STK*)&FaultLowPrio_Stk[thread_counter], - (CPU_STK_SIZE)TASK_FAULT_LOWPRIO_STK_SIZE/10, - (CPU_STK_SIZE)TASK_FAULT_LOWPRIO_STK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - assertOSError(OS_FAULT_LOWPRIO_LOC, err); - - thread_counter = (thread_counter + 1) % 3; // tasks should get mutex in order - // So we should be able to reuse task resources starting with the oldest - - -} - -void Task_FaultLowPrio(void *p_arg) { - OS_ERR err; - - - // Ensure no other low-priority faults are already being handled - // to avoid round-robin fault handling - - // Print the exception message - - // Run the callback function if it isn't null - - // Allow other low-priority fault threads to run - - // Fault handling thread has completed its job and will now self-destruct - - OSTaskDel(NULL, &err); // Delete this currently-running task - assertOSError(OS_FAULT_LOWPRIO_LOC, err); - -} \ No newline at end of file diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index 8ed8486bf..02d275ec1 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -101,7 +101,7 @@ DisplayError_t Display_Reset(void); * @param faultCode the generic fault code (will be displayed in hex) * @returns DisplayError_t */ -DisplayError_t Display_Error(os_error_loc_t osErrCode, fault_bitmap_t faultCode); +DisplayError_t Display_Error(os_error_loc_t osErrCode, uint8_t faultCode); /** * @brief Overwrites any processing commands and triggers the evacuation screen diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 73cb62569..f689d697b 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -27,6 +27,7 @@ static const char *TERMINATOR = "\xff\xff\xff"; +static DisplayError_t currError = DISPLAY_ERR_NONE; // Holds the current display error so we can inspect it DisplayError_t Display_Init(){ @@ -98,7 +99,7 @@ DisplayError_t Display_Reset(){ return Display_Send(restCmd); } -DisplayError_t Display_Error(os_error_loc_t osErrCode, fault_bitmap_t faultCode){ +DisplayError_t Display_Error(os_error_loc_t osErrCode, uint8_t faultCode){ BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); // Terminates any in progress command char faultPage[7] = "page 2"; @@ -140,6 +141,7 @@ DisplayError_t Display_Evac(uint8_t SOC_percent, uint32_t supp_mv){ void assertDisplayError(DisplayError_t err){ static uint8_t disp_error_cnt = 0; // Keep track of the number of times the display has an error + currError = err; if (err != DISPLAY_ERR_NONE){ disp_error_cnt++; if (disp_error_cnt > RESTART_THRESHOLD){ // Show error screen if we've reached the limit on restart attempts From a6b42715f6286b9b0b532f4ee7b6e8a0c7415c4b Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 08:27:11 +0000 Subject: [PATCH 077/141] Wrote assertTritiumError function for ReadTritium, created new nonrecoverableErrorHandler in Tasks.c to cover standard high-priority error actions like killing contactors, displaying the fault, and entering an infinite while loop. --- Apps/Inc/Tasks.h | 12 +++++++++++ Apps/Src/ReadTritium.c | 45 ++++++++++++++++++++++++------------------ Apps/Src/Tasks.c | 18 +++++++++++++++++ Drivers/Src/Display.c | 1 + 4 files changed, 57 insertions(+), 19 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 8ffe6cc17..e1905f029 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -184,6 +184,18 @@ typedef struct{ void (*callback)(void); } exception_t; + +/** + * @brief Used by error assertion functions to handle and signal a critical error + * Kills contactors, turns on brakelights, displays the fault screen with error code, + * and enters an infinite while loop + * TODO: add paramaters to display fault screen + * @param ERR_LOC Location code to display the name of the task, currently uses the OS_ERR_LOC enum + * @param Err_Code The enum value for the task's specific error code +*/ +void nonrecoverableErrorHandler(); + + /** * @brief Assert Error if OS function call fails * @param OS_err_loc Where OS error occured (driver level) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 9a56f3b11..40e218c0d 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -34,32 +34,39 @@ tritium_error_code_t MotorController_getTritiumError(void){ /** - * @brief Assert Error if Tritium sends error. - * When asserted, a new task will be spawned to handle the fault - * Creates either a low-priority task that restarts the hall sensor - * or a high priority task that enters a nonrecoverable fault - * @param motor_err Bitmap which has motor error codes + * @brief Assert Error if Tritium sends error by passing in Motor_FaultBitmap + * Can result in restarting the motor (first few hall sensor errors) + * or locking the scheduler and entering a nonrecoverable fault + * @param motor_err Bitmap with motor error codes to check */ -static void assertTritiumError(uint16_t motor_err){ +static void assertTritiumError(uint16_t motor_err){ + OS_ERR err; static uint8_t hall_fault_cnt = 0; //trip counter - if(motor_err != T_NONE){ + + // TODO: decide how to use Motor_FaultBitmap (should we set it here or assume it's already set?) + + if(motor_err != T_NONE){ // We need to handle an error + if(motor_err != T_HALL_SENSOR_ERR){ - //create a high priority task that will run the given callback - //exception_t notHallError = {PRI_NONRECOV, "this is Tritium, not-hall-sensor error", NULL}; - //assertExceptionError(notHallError); + OSSchedLock(&err); // This is a high-priority error, and we won't unlock the scheduler because it's also nonrecoverable. + nonrecoverableErrorHandler(); // Kill contactors, display fault message, and infinite loop + }else{ - if(hall_fault_cnt > RESTART_THRESHOLD){ //try to restart the motor a few times and then fail out - // create a high priority task that will run a different message/callback - //exception_t hallErrorPrio1 = {PRI_NONRECOV, "hall sensor errors have exceeded restart threshold", NULL}; - //assertExceptionError(hallErrorPrio1); // Fail out by entering nonrecoverable fault - } else { // Try resetarting the motor - hall_fault_cnt++; - printf("\n\rRestarting motor"); - MotorController_Restart(); //re-initialize motor - return; + hall_fault_cnt++; + + //try to restart the motor a few times and then fail out + if(hall_fault_cnt > RESTART_THRESHOLD){ + // enter nonrecoverable fault? TODO: check this + OSSchedLock(&err); // Treat this like another high-prio error + assertOSError(OS_READ_TRITIUM_LOC, err); + nonrecoverableErrorHandler(); + + } else { // Try restarting the motor + MotorController_Restart(); } } } + Motor_FaultBitmap = T_NONE; // Clear the error } diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index f01b5ff00..8df26718c 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -42,6 +42,10 @@ fault_bitmap_t FaultBitmap = FAULT_NONE; os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. +/** + * Error assertion-related functions +*/ + void _assertOSError(uint16_t OS_err_loc, OS_ERR err) { if (err != OS_ERR_NONE) @@ -55,4 +59,18 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) } } +//TODO: add parameters for displaying the fault screen +void nonrecoverableErrorHandler(){ + // Array motor kill + BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); + BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); + + // Turn additional brakelight on to indicate critical error + BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); + + // TODO: Display fault screen + + + while(1){;} //nonrecoverable +} diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index f689d697b..2a34a0788 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -149,5 +149,6 @@ void assertDisplayError(DisplayError_t err){ } else { // Otherwise try resetting the display Display_Reset(); } + currError = DISPLAY_ERR_NONE; // Clear the error after handling it } } From 554cf95d313d02c02bb90be1b495d2417fbfc356 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 08:30:51 +0000 Subject: [PATCH 078/141] Renamed Display_Fault function to Display_Error. --- Tests/Test_DisplayApps.c | 2 +- Tests/Test_DisplayDriver.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Test_DisplayApps.c b/Tests/Test_DisplayApps.c index 072805e2b..3952ae85f 100644 --- a/Tests/Test_DisplayApps.c +++ b/Tests/Test_DisplayApps.c @@ -126,7 +126,7 @@ void Task1(void *arg) testPercentageComp(&UpdateDisplay_SetAccel); - error = Display_Fault(OSErrLocBitmap, FaultBitmap); + error = Display_Error(OSErrLocBitmap, FaultBitmap); assertDisplayError(error); OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &e); diff --git a/Tests/Test_DisplayDriver.c b/Tests/Test_DisplayDriver.c index 2eaca7059..5c64b50c7 100644 --- a/Tests/Test_DisplayDriver.c +++ b/Tests/Test_DisplayDriver.c @@ -133,7 +133,7 @@ int main() // Test the fault screen os_error_loc_t osErrCode = 0x0420; fault_bitmap_t faultCode = 0x69; - err = Display_Fault(osErrCode, faultCode); + err = Display_Error(osErrCode, faultCode); //assertDisplayError(err); while (1) From 3eb63bb83cb8c4439911ff1696c966ce6c0b7256 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 08:42:08 +0000 Subject: [PATCH 079/141] Added parameters and function to nonrecoverableErrorHnadler so that it can display the fault screen. --- Apps/Inc/Tasks.h | 6 +++--- Apps/Src/ReadTritium.c | 8 ++++---- Apps/Src/Tasks.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index e1905f029..cfc6b2cca 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -190,10 +190,10 @@ typedef struct{ * Kills contactors, turns on brakelights, displays the fault screen with error code, * and enters an infinite while loop * TODO: add paramaters to display fault screen - * @param ERR_LOC Location code to display the name of the task, currently uses the OS_ERR_LOC enum - * @param Err_Code The enum value for the task's specific error code + * @param osLocCode Location code to display the name of the task, currently uses the OS_ERR_LOC enum + * @param faultCode The enum value for the task's specific error code */ -void nonrecoverableErrorHandler(); +void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode); /** diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 40e218c0d..2101ea96c 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -13,7 +13,7 @@ #define RESTART_THRESHOLD 3 // Number of times to try restarting the hall sensor -uint16_t Motor_FaultBitmap = T_NONE; +tritium_error_code_t Motor_FaultBitmap = T_NONE; static float Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read static float Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read @@ -39,7 +39,7 @@ tritium_error_code_t MotorController_getTritiumError(void){ * or locking the scheduler and entering a nonrecoverable fault * @param motor_err Bitmap with motor error codes to check */ -static void assertTritiumError(uint16_t motor_err){ +static void assertTritiumError(tritium_error_code_t motor_err){ OS_ERR err; static uint8_t hall_fault_cnt = 0; //trip counter @@ -49,7 +49,7 @@ static void assertTritiumError(uint16_t motor_err){ if(motor_err != T_HALL_SENSOR_ERR){ OSSchedLock(&err); // This is a high-priority error, and we won't unlock the scheduler because it's also nonrecoverable. - nonrecoverableErrorHandler(); // Kill contactors, display fault message, and infinite loop + nonrecoverableErrorHandler(OS_READ_TRITIUM_LOC, motor_err); // Kill contactors, display fault message, and infinite loop }else{ hall_fault_cnt++; @@ -59,7 +59,7 @@ static void assertTritiumError(uint16_t motor_err){ // enter nonrecoverable fault? TODO: check this OSSchedLock(&err); // Treat this like another high-prio error assertOSError(OS_READ_TRITIUM_LOC, err); - nonrecoverableErrorHandler(); + nonrecoverableErrorHandler(OS_READ_TRITIUM_LOC, motor_err); } else { // Try restarting the motor MotorController_Restart(); diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 8df26718c..0e3636794 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -59,8 +59,8 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) } } -//TODO: add parameters for displaying the fault screen -void nonrecoverableErrorHandler(){ + +void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode){ // Array motor kill BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); @@ -68,8 +68,8 @@ void nonrecoverableErrorHandler(){ // Turn additional brakelight on to indicate critical error BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); - // TODO: Display fault screen - + // Display the fault screen with the error location and code + Display_Error(osLocCode, faultCode); while(1){;} //nonrecoverable } From 4097b7ec44de613c52448c8ea1792d602b0407ea Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 09:07:18 +0000 Subject: [PATCH 080/141] Split nonrecoverableErrorHandler so that arrayMotorKill to turn off the motor and array contactors can be called outside of the nonrecoverable error handler, began work on the ReadCarCAN error assertion function --- Apps/Inc/Tasks.h | 5 +++++ Apps/Src/ReadCarCAN.c | 41 +++++++++++++++++++++++++++++++++++++++-- Apps/Src/Tasks.c | 7 ++++++- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index cfc6b2cca..3e3d2becc 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -184,6 +184,11 @@ typedef struct{ void (*callback)(void); } exception_t; +/** + * @brief For use in error handling: turns off array and motor contactor, turns on additional brakelight + * to signal a ciritical error happened +*/ +void arrayMotorKill(); /** * @brief Used by error assertion functions to handle and signal a critical error diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 9c85b9593..700f3461b 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -40,10 +40,47 @@ static uint8_t oldestMsgIdx = 0; static uint8_t SOC = 0; static uint32_t SBPV = 0; +// Error type enum with all possible ReadCarCAN errors for error assertion and display +typedef enum{ + RCC_ERR_NONE, + RCC_ERR_CHARGE_DISABLE_MSG, + RCC_ERR_MISSED_BPS_MSG, + RCC_ERR_BPS_TRIP +} readCarCAN_error_t; -// Handler to turn array back on -static void arrayRestart(void *p_tmr, void *p_arg); +// Error code variable +static readCarCAN_error_t readCarCANError; +/** + * @brief Error assertion function to check and handle errors in ReadCarCAN + * @param errorCode the variable to check for errors + */ +static void assertReadCarCANError(readCarCAN_error_t errorCode) { + OS_ERR err; + + // Check the type of error in a switch case + switch (errorCode) { + case RCC_ERR_BPS_TRIP: + OSSchedLock(&err); + + arrayMotorKill(); // Disable all contactors + + Display_Evac(SOC, SBPV); // Display the evacuation screen instead of the fault screen + + while(1){;} // Enter a nonrecoverable loop + + break; + + case RCC_ERR_MISSED_BPS_MSG: + OSSchedLock(&err); // Want to handle this asap + + + + + } + + +} // Getter function for chargeEnable bool ChargeEnable_Get() diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 0e3636794..123bd7fa2 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -60,13 +60,18 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) } } -void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode){ +void arrayMotorKill() { // Array motor kill BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); // Turn additional brakelight on to indicate critical error BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); +} + +void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode){ + // Turn off contactors, turn on brakelight as a signal + arrayMotorKill(); // Display the fault screen with the error location and code Display_Error(osLocCode, faultCode); From 43dae234d7e1a8c71d75df297d1d0f6a201e5888 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 22:52:23 +0000 Subject: [PATCH 081/141] Finished a first compiling draft of the ReadCarCAN assert function. --- Apps/Src/ReadCarCAN.c | 94 +++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 700f3461b..02462bd70 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -51,44 +51,15 @@ typedef enum{ // Error code variable static readCarCAN_error_t readCarCANError; -/** - * @brief Error assertion function to check and handle errors in ReadCarCAN - * @param errorCode the variable to check for errors - */ -static void assertReadCarCANError(readCarCAN_error_t errorCode) { - OS_ERR err; - - // Check the type of error in a switch case - switch (errorCode) { - case RCC_ERR_BPS_TRIP: - OSSchedLock(&err); - - arrayMotorKill(); // Disable all contactors - - Display_Evac(SOC, SBPV); // Display the evacuation screen instead of the fault screen - while(1){;} // Enter a nonrecoverable loop - - break; - - case RCC_ERR_MISSED_BPS_MSG: - OSSchedLock(&err); // Want to handle this asap - - - - - } - - -} - -// Getter function for chargeEnable +// Public getter function for chargeEnable bool ChargeEnable_Get() { return chargeEnable; } + /** * @brief adds new messages by overwriting old messages in the saturation buffer and then updates saturation * @param chargeMessage whether bps message was charge enable (1) or disable (-1) @@ -108,24 +79,30 @@ static void updateSaturation(int8_t chargeMessage){ } // exception struct callback for charging disable, kills contactors and turns of display +//TODO: rename this static void callback_disableContactors(void){ // Kill contactors - Contactors_Set(ARRAY_CONTACTOR, OFF, true); - Contactors_Set(ARRAY_PRECHARGE, OFF, true); + Contactors_Set(ARRAY_CONTACTOR, OFF, true); // TODO: Change this to a GPIO write because WE DON'T CARE ABOUT PENDING ON YOUR STUPID SEMAPHORES + Contactors_Set(ARRAY_PRECHARGE, OFF, true); // TODO: Add chargeEnable = false? + // Using a GPIO write instead of Contactors_Set for speed, and to avoid blocking calls in timer callbacks + // This also eliminates the possibility of a deadlock in case Task_Init has the contactorsMutex for the motor contactor + // I don't think skipping the function or pend is an issue because the array contactor is only turned on in array restart, + // and if charging is disabled then it won't turn them back on. + + // Being interrupted after checking chargeEnable isn't possible because arrayRestart happens in a timer callback, + // which is performed with the scheduler locked. // Turn off the array contactor display light UpdateDisplay_SetArray(false); } // helper function to disable charging -// Turns off contactors by signaling fault state -static inline void chargingDisable(void) { +static void chargingDisable(void) { // mark regen as disabled chargeEnable = false; // kill contactors - exception_t readBPSError = {.prio=PRI_RECOV, .message="read BPS error", .callback=callback_disableContactors}; - assertExceptionError(readBPSError); + callback_disableContactors(); } // helper function to call if charging should be enabled @@ -188,6 +165,41 @@ void canWatchTimerCallback (void *p_tmr, void *p_arg){ } +/** + * @brief Error assertion function to check and handle errors in ReadCarCAN + * @param errorCode the variable to check for errors + */ +static void assertReadCarCANError(readCarCAN_error_t errorCode) { + OS_ERR err; + + readCarCANError = errorCode; // Allows us to inspect what error we encountered + + // Check the type of error in a switch case + switch (errorCode) { + case RCC_ERR_BPS_TRIP: + OSSchedLock(&err); + arrayMotorKill(); // Disable all contactors + Display_Evac(SOC, SBPV); // Display the evacuation screen instead of the fault screen + while(1){;} // Enter a nonrecoverable loop + break; + + case RCC_ERR_MISSED_BPS_MSG: + case RCC_ERR_CHARGE_DISABLE_MSG: //TODO: is there any difference in how we should andle the missed BPS message vs charging disable? If not, we can let this case falll through. + OSSchedLock(&err); // Want to handle this first without interruptions + chargingDisable(); // Mark chargeEnable as false, turn off contactors, and change display light + //TODO: make sure this takes care of everything we need to do for a missed BPS message. + OSSchedUnlock(&err); + break; + + default: + break; + + } + + readCarCANError = RCC_ERR_NONE; // Clear the error once it has been handled + +} + void Task_ReadCarCAN(void *p_arg) { @@ -244,13 +256,9 @@ void Task_ReadCarCAN(void *p_arg) case BPS_TRIP: { // BPS has a fault and we need to enter fault state (probably) if(dataBuf.data[0] == 1){ // If buffer contains 1 for a BPS trip, we should enter a nonrecoverable fault - - Display_Evac(SOC, SBPV); // Display evacuation message - // Create an exception and assert the error - // kill contactors and enter a nonrecoverable fault - exception_t tripBPSError = {.prio=PRI_NONRECOV, .message="BPS has been tripped", .callback=callback_disableContactors}; - assertExceptionError(tripBPSError); + // Display evacuation message, kill contactors, and enter a nonrecoverable fault + assertReadCarCANError(RCC_ERR_BPS_TRIP); } } case CHARGE_ENABLE: { From 636066d19ee45ae674366f336520f9d72ee41135 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 29 Jun 2023 23:00:25 +0000 Subject: [PATCH 082/141] Renamed the display error variable from currError to displayError. --- Drivers/Src/Display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 2a34a0788..877d17c31 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -27,7 +27,7 @@ static const char *TERMINATOR = "\xff\xff\xff"; -static DisplayError_t currError = DISPLAY_ERR_NONE; // Holds the current display error so we can inspect it +static DisplayError_t displayError = DISPLAY_ERR_NONE; // Holds the current display error so we can inspect it DisplayError_t Display_Init(){ @@ -141,7 +141,7 @@ DisplayError_t Display_Evac(uint8_t SOC_percent, uint32_t supp_mv){ void assertDisplayError(DisplayError_t err){ static uint8_t disp_error_cnt = 0; // Keep track of the number of times the display has an error - currError = err; + displayError = err; if (err != DISPLAY_ERR_NONE){ disp_error_cnt++; if (disp_error_cnt > RESTART_THRESHOLD){ // Show error screen if we've reached the limit on restart attempts @@ -149,6 +149,6 @@ void assertDisplayError(DisplayError_t err){ } else { // Otherwise try resetting the display Display_Reset(); } - currError = DISPLAY_ERR_NONE; // Clear the error after handling it + displayError = DISPLAY_ERR_NONE; // Clear the error after handling it } } From f640691ed0de8605d27cb14e1a62d5f5bc9ed357 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 2 Jul 2023 21:14:59 +0000 Subject: [PATCH 083/141] Added assertTaskError function to serve as a single assertion function that takes care of locking the scheduler and displaying a fault before jumping to a callback. This allows us to avoid locking the scheduler in many places throughout the code. --- Apps/Inc/Tasks.h | 11 ++++++++++- Apps/Src/Tasks.c | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 3e3d2becc..c65f1ba08 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -186,7 +186,7 @@ typedef struct{ /** * @brief For use in error handling: turns off array and motor contactor, turns on additional brakelight - * to signal a ciritical error happened + * to signal a ciritical error happened. Separated from nonrecoverable fault handler */ void arrayMotorKill(); @@ -200,6 +200,15 @@ void arrayMotorKill(); */ void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode); +/** + * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, + * and jumping to the error's specified callback function + * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately + * @param errorLoc the task from which the error originated. TODO: should be taken out when last task pointer is integrated + * @param faultCode the value for what specific error happened + * @param errorCallback a callback function to a handler for that specific error +*/ +void assertTaskError(bool lockSched, os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback); /** * @brief Assert Error if OS function call fails diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 123bd7fa2..1897eaed0 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -60,6 +60,31 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) } } +/** + * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, + * and jumping to the error's specified callback function + * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately + * @param errorLoc the task from which the error originated. TODO: should be taken out when last task pointer is integrated + * @param faultCode the value for what specific error happened + * @param errorCallback a callback function to a handler for that specific error +*/ +void assertTaskError(bool lockSched, os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback) { + OS_ERR err; + + if (lockSched) { + OSSchedLock(&err); + assertOSError(OS_MAIN_LOC, err); //TODO: should this be a different location? + } + + Display_Error(errorLoc, faultCode); + errorCallback(); + + if (lockSched) { + OSSchedUnlock(&err); + assertOSError(OS_MAIN_LOC, err); + } +} + void arrayMotorKill() { // Array motor kill BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); From 57b5fca2e4d6e0113c7b5a29a990ee42c6e4f807 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 3 Jul 2023 07:04:43 +0000 Subject: [PATCH 084/141] Reordered and added new parameters to assertTaskError function. --- Apps/Inc/Tasks.h | 11 ++++------- Apps/Src/Tasks.c | 42 ++++++++++++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index c65f1ba08..723fa496e 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -44,8 +44,6 @@ #define TASK_SEND_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_TELEMETRY_STACK_SIZE DEFAULT_STACK_SIZE - - /** * Task Prototypes */ @@ -135,9 +133,7 @@ typedef enum{ OS_MOTOR_CONNECTION_LOC = 0x800, OS_DISPLAY_LOC = 0x1000, OS_FAULT_STATE_LOC = 0x2000, // to be deleted - OS_FAULT_HIGHPRIO_LOC = 0x2000, - OS_FAULT_LOWPRIO_LOC = 0x4000 - + OS_TASKS_LOC = 0x2000, } os_error_loc_t; /** @@ -203,12 +199,13 @@ void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode); /** * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, * and jumping to the error's specified callback function - * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately * @param errorLoc the task from which the error originated. TODO: should be taken out when last task pointer is integrated * @param faultCode the value for what specific error happened * @param errorCallback a callback function to a handler for that specific error + * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately + * @param nonrecoverable if true, kills the motor, displays the fault screen, and enters an infinite while loop */ -void assertTaskError(bool lockSched, os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback); +void assertTaskError(os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback, bool lockSched, bool nonrecoverable); /** * @brief Assert Error if OS function call fails diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 1897eaed0..b2408eaeb 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -38,10 +38,12 @@ CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; /** * Global Variables */ -fault_bitmap_t FaultBitmap = FAULT_NONE; +fault_bitmap_t FaultBitmap = FAULT_NONE; // Used for faultstate handling, otherwise not used. TODO: Should be deleted? os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; +uint8_t currError = NULL; // Error code from the enum of the task in OSSErrLocBitmap extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. + /** * Error assertion-related functions */ @@ -68,20 +70,37 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) * @param faultCode the value for what specific error happened * @param errorCallback a callback function to a handler for that specific error */ -void assertTaskError(bool lockSched, os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback) { +void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t errorCallback, bool lockSched, bool nonrecoverable) { OS_ERR err; - if (lockSched) { + if (lockSched) { // We want this error to be handled immediately without other tasks being able to interrupt OSSchedLock(&err); - assertOSError(OS_MAIN_LOC, err); //TODO: should this be a different location? + assertOSError(OS_TASKS_LOC, err); + } + + // Set the error variables to store data + OSErrLocBitmap = errorLoc; + currError = errorCode; + + if (nonrecoverable) { + arrayMotorKill(); // Apart from while loop because killing the motor is more important + Display_Error(errorLoc, errorCode); // Needs to happen before callback so that tasks can change the screen + // (ex: readCarCAN and evac screen for BPS trip) + } + + + if (errorCallback != NULL) { + errorCallback(); // Run a handler for this error that was specified in another task file } + - Display_Error(errorLoc, faultCode); - errorCallback(); + if (nonrecoverable) { // enter an infinite while loop + while(1){;} + } - if (lockSched) { - OSSchedUnlock(&err); - assertOSError(OS_MAIN_LOC, err); + if (lockSched) { // Only happens on recoverable errors + OSSchedUnlock(&err); + assertOSError(OS_TASKS_LOC, err); } } @@ -94,7 +113,10 @@ void arrayMotorKill() { BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); } -void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode){ +/** + * TODO: delete? +*/ +void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode){ // Turn off contactors, turn on brakelight as a signal arrayMotorKill(); From dae8a12a665e49928500d19aac971a0265a2604d Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 3 Jul 2023 07:30:25 +0000 Subject: [PATCH 085/141] Rewrote readTritium error assertion to use the main assertTaskError function and a callback handler instead of the separate assertion functions for each task that we were planning earlier. Also added an enum to define options for locking the scheduler and choosing recoverable/nonrecoverable when asserting an error. --- Apps/Inc/Tasks.h | 16 ++++++++++++++++ Apps/Src/ReadTritium.c | 36 +++++++++++++++++++++--------------- Apps/Src/Tasks.c | 8 ++++---- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 723fa496e..5960d8885 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -180,6 +180,22 @@ typedef struct{ void (*callback)(void); } exception_t; +/** + * Error-handling option enums +*/ + +// Whether or not to lock the scheduler when asserting a task error +enum { + OPT_LOCK_SCHED = false, + OPT_NO_LOCK_SCHED = true +}; + +// Whether or not a task error is recoverable +enum { + OPT_RECOV, + OPT_NONRECOV +}; + /** * @brief For use in error handling: turns off array and motor contactor, turns on additional brakelight * to signal a ciritical error happened. Separated from nonrecoverable fault handler diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 2101ea96c..5736806a6 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -32,41 +32,36 @@ tritium_error_code_t MotorController_getTritiumError(void){ } - /** - * @brief Assert Error if Tritium sends error by passing in Motor_FaultBitmap - * Can result in restarting the motor (first few hall sensor errors) - * or locking the scheduler and entering a nonrecoverable fault + * @brief Assert Error if Tritium sends error by passing in and checking Motor_FaultBitmap + * and asserting the error with its handler callback if one exists. + * Can result in restarting the motor (first few hall sensor errors) + * or locking the scheduler and entering a nonrecoverable fault for most other errors * @param motor_err Bitmap with motor error codes to check */ static void assertTritiumError(tritium_error_code_t motor_err){ OS_ERR err; static uint8_t hall_fault_cnt = 0; //trip counter - // TODO: decide how to use Motor_FaultBitmap (should we set it here or assume it's already set?) if(motor_err != T_NONE){ // We need to handle an error if(motor_err != T_HALL_SENSOR_ERR){ - OSSchedLock(&err); // This is a high-priority error, and we won't unlock the scheduler because it's also nonrecoverable. - nonrecoverableErrorHandler(OS_READ_TRITIUM_LOC, motor_err); // Kill contactors, display fault message, and infinite loop - + // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); }else{ hall_fault_cnt++; //try to restart the motor a few times and then fail out if(hall_fault_cnt > RESTART_THRESHOLD){ - // enter nonrecoverable fault? TODO: check this - OSSchedLock(&err); // Treat this like another high-prio error - assertOSError(OS_READ_TRITIUM_LOC, err); - nonrecoverableErrorHandler(OS_READ_TRITIUM_LOC, motor_err); - + // Assert another nonrecoverable error, but this time motor_err will have a different error code + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); } else { // Try restarting the motor - MotorController_Restart(); + // Assert a recoverable error that will run the motor restart callback function + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, handler_Tritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); } } } - Motor_FaultBitmap = T_NONE; // Clear the error } @@ -155,3 +150,14 @@ float Motor_RPM_Get(){ //getter function for motor RPM float Motor_Velocity_Get(){ //getter function for motor velocity return Motor_Velocity; } + + +/** + * Error handler functions + * Passed as callback functions to the main assertTaskError function by assertTritiumError +*/ + +// A callback function to be run by the main assertTaskError function for hall sensor errors +static void handler_Tritium_HallError() { + MotorController_Restart(); // Try restarting the motor +} \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index b2408eaeb..11520d6c9 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -73,7 +73,7 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t errorCallback, bool lockSched, bool nonrecoverable) { OS_ERR err; - if (lockSched) { // We want this error to be handled immediately without other tasks being able to interrupt + if (lockSched = OPT_LOCK_SCHED) { // We want this error to be handled immediately without other tasks being able to interrupt OSSchedLock(&err); assertOSError(OS_TASKS_LOC, err); } @@ -82,7 +82,7 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t erro OSErrLocBitmap = errorLoc; currError = errorCode; - if (nonrecoverable) { + if (nonrecoverable == OPT_NONRECOV) { arrayMotorKill(); // Apart from while loop because killing the motor is more important Display_Error(errorLoc, errorCode); // Needs to happen before callback so that tasks can change the screen // (ex: readCarCAN and evac screen for BPS trip) @@ -94,11 +94,11 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t erro } - if (nonrecoverable) { // enter an infinite while loop + if (nonrecoverable == OPT_NONRECOV) { // enter an infinite while loop while(1){;} } - if (lockSched) { // Only happens on recoverable errors + if (lockSched = OPT_LOCK_SCHED) { // Only happens on recoverable errors OSSchedUnlock(&err); assertOSError(OS_TASKS_LOC, err); } From 33424fa289c8c6c1eb8e2ca6307b63670c42c93a Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 3 Jul 2023 07:40:35 +0000 Subject: [PATCH 086/141] Typedef-ed the error assertion option enums to enforce usage, reorder assertion and handler functions in readTritium so that the program can compile. --- Apps/Inc/Tasks.h | 10 +++---- Apps/Src/ReadTritium.c | 65 ++++++++++++++++++++++-------------------- Apps/Src/Tasks.c | 8 +++--- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 5960d8885..b4fbe4a8c 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -185,16 +185,16 @@ typedef struct{ */ // Whether or not to lock the scheduler when asserting a task error -enum { +typedef enum { OPT_LOCK_SCHED = false, OPT_NO_LOCK_SCHED = true -}; +} error_lock_sched_opt_t; // Whether or not a task error is recoverable -enum { +typedef enum { OPT_RECOV, OPT_NONRECOV -}; +} error_recov_opt_t; /** * @brief For use in error handling: turns off array and motor contactor, turns on additional brakelight @@ -221,7 +221,7 @@ void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode); * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately * @param nonrecoverable if true, kills the motor, displays the fault screen, and enters an infinite while loop */ -void assertTaskError(os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback, bool lockSched, bool nonrecoverable); +void assertTaskError(os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback, error_lock_sched_opt_t lockSched, error_recov_opt_t nonrecoverable); /** * @brief Assert Error if OS function call fails diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 5736806a6..0f2d5fb30 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -17,6 +17,9 @@ tritium_error_code_t Motor_FaultBitmap = T_NONE; static float Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read static float Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read +// Function prototypes +static void assertTritiumError(tritium_error_code_t motor_err); + /** * @brief Returns highest priority tritium error code * @@ -32,37 +35,6 @@ tritium_error_code_t MotorController_getTritiumError(void){ } -/** - * @brief Assert Error if Tritium sends error by passing in and checking Motor_FaultBitmap - * and asserting the error with its handler callback if one exists. - * Can result in restarting the motor (first few hall sensor errors) - * or locking the scheduler and entering a nonrecoverable fault for most other errors - * @param motor_err Bitmap with motor error codes to check - */ -static void assertTritiumError(tritium_error_code_t motor_err){ - OS_ERR err; - static uint8_t hall_fault_cnt = 0; //trip counter - - - if(motor_err != T_NONE){ // We need to handle an error - - if(motor_err != T_HALL_SENSOR_ERR){ - // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); - }else{ - hall_fault_cnt++; - - //try to restart the motor a few times and then fail out - if(hall_fault_cnt > RESTART_THRESHOLD){ - // Assert another nonrecoverable error, but this time motor_err will have a different error code - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); - } else { // Try restarting the motor - // Assert a recoverable error that will run the motor restart callback function - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, handler_Tritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); - } - } - } -} @@ -160,4 +132,35 @@ float Motor_Velocity_Get(){ //getter function for motor velocity // A callback function to be run by the main assertTaskError function for hall sensor errors static void handler_Tritium_HallError() { MotorController_Restart(); // Try restarting the motor +} + + +/** + * @brief Assert Error if Tritium sends error by passing in and checking Motor_FaultBitmap + * and asserting the error with its handler callback if one exists. + * Can result in restarting the motor (first few hall sensor errors) + * or locking the scheduler and entering a nonrecoverable fault for most other errors + * @param motor_err Bitmap with motor error codes to check + */ +static void assertTritiumError(tritium_error_code_t motor_err){ + static uint8_t hall_fault_cnt = 0; //trip counter + + if(motor_err != T_NONE){ // We need to handle an error + if(motor_err != T_HALL_SENSOR_ERR){ + // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + + }else{ + hall_fault_cnt++; + + //try to restart the motor a few times and then fail out + if(hall_fault_cnt > RESTART_THRESHOLD){ + // Assert another nonrecoverable error, but this time motor_err will have a different error code + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + } else { // Try restarting the motor + // Assert a recoverable error that will run the motor restart callback function + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, handler_Tritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); + } + } + } } \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 11520d6c9..88e714f59 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -40,7 +40,7 @@ CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; */ fault_bitmap_t FaultBitmap = FAULT_NONE; // Used for faultstate handling, otherwise not used. TODO: Should be deleted? os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; -uint8_t currError = NULL; // Error code from the enum of the task in OSSErrLocBitmap +uint8_t currError = (int) NULL; // Error code from the enum of the task in OSSErrLocBitmap extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. @@ -70,10 +70,10 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) * @param faultCode the value for what specific error happened * @param errorCallback a callback function to a handler for that specific error */ -void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t errorCallback, bool lockSched, bool nonrecoverable) { +void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t errorCallback, error_lock_sched_opt_t lockSched, error_recov_opt_t nonrecoverable) { OS_ERR err; - if (lockSched = OPT_LOCK_SCHED) { // We want this error to be handled immediately without other tasks being able to interrupt + if (lockSched == OPT_LOCK_SCHED) { // We want this error to be handled immediately without other tasks being able to interrupt OSSchedLock(&err); assertOSError(OS_TASKS_LOC, err); } @@ -98,7 +98,7 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t erro while(1){;} } - if (lockSched = OPT_LOCK_SCHED) { // Only happens on recoverable errors + if (lockSched == OPT_LOCK_SCHED) { // Only happens on recoverable errors OSSchedUnlock(&err); assertOSError(OS_TASKS_LOC, err); } From 48db19a4bf5f2dd027b7a9933a503b34fc66b888 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 3 Jul 2023 09:06:58 +0000 Subject: [PATCH 087/141] Began moving assertError function for display errors from display driver to updatedisplay app. --- Apps/Inc/UpdateDisplay.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index ac3ed56c9..75f6c8d99 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -31,6 +31,7 @@ typedef enum{ UPDATEDISPLAY_ERR_FIFO_POP =-2, // Error popping command from fifo UPDATEDISPLAY_ERR_PARSE_COMP =-3, // Error parsing component/val in SetComponent UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value + UPDATEDISPLAY_ERR_DRIVER =-5 } UpdateDisplayError_t; /** From cdd7c8ff8e15d4898c97d18040aec444f4f8f106 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 4 Jul 2023 08:26:25 +0000 Subject: [PATCH 088/141] Moved error handling from Display.c to UpdateDisplay.c, decided to set global error variables for tasks inside individual task error assertion functions instead of in the main assertion function to avoid needing to figure out which location an error is coming from to set the correct error variable. --- Apps/Inc/Tasks.h | 19 +++++++++++++++ Apps/Src/ReadTritium.c | 4 ++++ Apps/Src/Tasks.c | 7 +++--- Apps/Src/UpdateDisplay.c | 52 +++++++++++++++++++++++++++++++++++++++- Drivers/Inc/Display.h | 9 +------ Drivers/Src/Display.c | 14 +---------- 6 files changed, 80 insertions(+), 25 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index b4fbe4a8c..45668cea3 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -44,6 +44,11 @@ #define TASK_SEND_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_TELEMETRY_STACK_SIZE DEFAULT_STACK_SIZE +/** + * Task error variable type +*/ +#define error_code_t uint8_t + /** * Task Prototypes */ @@ -151,12 +156,26 @@ typedef enum{ FAULT_BPS = 0x20, // for if BPS trips } fault_bitmap_t; +/** + * Error handler task enum +*/ +typedef enum { + TASK_READ_TRITIUM = 0, + TASK_READ_CAR_CAN = 1, + TASK_UPDATE_DISPLAY = 2 +} error_task_t; + /** * Error variables */ extern fault_bitmap_t FaultBitmap; extern os_error_loc_t OSErrLocBitmap; +// Store error codes, set in task error assertion functions +extern error_code_t Error_ReadTritium; +extern error_code_t Error_ReadCarCAN; +extern error_code_t Error_UpdateDisplay; + /** * Fault Exception Enum * For the "prio" field of a fault exception struct to determine handling mode diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 0f2d5fb30..8db3ef867 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -145,6 +145,8 @@ static void handler_Tritium_HallError() { static void assertTritiumError(tritium_error_code_t motor_err){ static uint8_t hall_fault_cnt = 0; //trip counter + Error_ReadTritium = motor_err; + if(motor_err != T_NONE){ // We need to handle an error if(motor_err != T_HALL_SENSOR_ERR){ // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop @@ -163,4 +165,6 @@ static void assertTritiumError(tritium_error_code_t motor_err){ } } } + + Error_ReadTritium = T_NONE; // Clear the error after handling it } \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 88e714f59..2e58c93e3 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -40,7 +40,9 @@ CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; */ fault_bitmap_t FaultBitmap = FAULT_NONE; // Used for faultstate handling, otherwise not used. TODO: Should be deleted? os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; -uint8_t currError = (int) NULL; // Error code from the enum of the task in OSSErrLocBitmap +error_code_t Error_ReadTritium = NULL; // Variables to store error codes, stored and cleared in task error assert functions +error_code_t Error_ReadCarCAN = NULL; +error_code_t Error_UpdateDisplay = NULL; extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. @@ -78,9 +80,8 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t erro assertOSError(OS_TASKS_LOC, err); } - // Set the error variables to store data + // Set the error variables to store data //TODO: delete? OSErrLocBitmap = errorLoc; - currError = errorCode; if (nonrecoverable == OPT_NONRECOV) { arrayMotorKill(); // Apart from while loop because killing the motor is more important diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index e1db6f143..998b76538 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -113,7 +113,8 @@ static UpdateDisplayError_t UpdateDisplay_PopNext(){ return UPDATEDISPLAY_ERR_FIFO_POP; } - assertDisplayError(Display_Send(cmd)); + // Assert a display driver error code if the send fails, else assert that there's no error + assertDisplayError(Display_Send(cmd) ? UPDATEDISPLAY_ERR_DRIVER : UPDATEDISPLAY_ERR_NONE); return UPDATEDISPLAY_ERR_NONE; } @@ -383,4 +384,53 @@ void Task_UpdateDisplay(void *p_arg) { UpdateDisplayError_t err = UpdateDisplay_PopNext(); assertDisplayError(err); } +} + + +/** + * Error handler functions + * Passed as callback functions to the main assertTaskError function by assertTritiumError +*/ + +/** + * @brief A handler callback function run by the main assertTaskError function + * if we haven't reached the restart limit and want to restart the display + */ +static void handler_UpdateDisplay_Restart() { + Display_Restart(); // Try resetting the display +} + +/** + * @brief A handler callback function run by the main assertTaskError function + * if we have reached the restart limit and want to show the error screen + */ +static void handler_UpdateDisplay_ShowError() { + Display_Error(OS_DISPLAY_LOC, Error_UpdateDisplay); // Try resetting the display +} + + +/** + * @brief Check for a display error and assert one if it exists. + * Sotres the error code, calls the main assertion function + * and runs a handler to restart or display the error. + * @param err variable with display error codes + */static void assertDisplayError(DisplayError_t err){ + static uint8_t disp_error_cnt = 0; // Keep track of the number of times the display has an error + + Error_UpdateDisplay = err; // Store the error code for inspection + + if (err != DISPLAY_ERR_NONE){ + disp_error_cnt++; + + if (disp_error_cnt > RESTART_THRESHOLD){ + // Use error assertion to show error screen if at restart attempt limit + assertTaskError(OS_DISPLAY_LOC, err, handler_UpdateDisplay_ShowError, + OPT_NO_LOCK_SCHED, OPT_RECOV); + } else { // Otherwise try resetting the display using the restart callback + assertTaskError(OS_DISPLAY_LOC, err, handler_UpdateDisplay_Restart, + OPT_NO_LOCK_SCHED, OPT_RECOV); + } + + Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; // Clear the error after handling it + } } \ No newline at end of file diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index 02d275ec1..9129d8171 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -23,7 +23,7 @@ /** * Error types */ -typedef enum{ +typedef enum{ // Currently only ERR_NONE and ERR_PARSE are used DISPLAY_ERR_NONE = 0, DISPLAY_ERR_PARSE =-1, // Error parsing command struct passed to Display_Send DISPLAY_ERR_INV_INSTR =-2, // Invalid instruction passed to nextion (0x00) @@ -37,13 +37,6 @@ typedef enum{ DISPLAY_ERR_OTHER =-10 // Other nextion display error } DisplayError_t; -/** - * @brief Error handler for any display errors. Call this after any display driver function. - * Restarts the display if there is an error - * or displays fault if it has reached the threshold for restart attempts - * @param err the display error code to check - */ -void assertDisplayError(DisplayError_t err); /** * All three pages on the HMI diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 877d17c31..2ac2be493 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -139,16 +139,4 @@ DisplayError_t Display_Evac(uint8_t SOC_percent, uint32_t supp_mv){ return DISPLAY_ERR_NONE; } -void assertDisplayError(DisplayError_t err){ - static uint8_t disp_error_cnt = 0; // Keep track of the number of times the display has an error - displayError = err; - if (err != DISPLAY_ERR_NONE){ - disp_error_cnt++; - if (disp_error_cnt > RESTART_THRESHOLD){ // Show error screen if we've reached the limit on restart attempts - Display_Error(OS_DISPLAY_LOC, err); - } else { // Otherwise try resetting the display - Display_Reset(); - } - displayError = DISPLAY_ERR_NONE; // Clear the error after handling it - } -} + From a5bd69abd019d14a6a9dd1ed2cf7429aa0ca6a68 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 5 Jul 2023 00:52:23 +0000 Subject: [PATCH 089/141] Modified test file, ReadTritium hall and nonhall sensor error tests appear to work. --- Apps/Src/UpdateDisplay.c | 9 +- Drivers/Src/Display.c | 1 - Tests/Test_FaultThread_Exceptions.c | 542 +++++++++++++++------------- 3 files changed, 307 insertions(+), 245 deletions(-) diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 998b76538..a5a86fbf3 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -34,6 +34,13 @@ disp_fifo_t msg_queue; static OS_SEM DisplayQ_Sem4; // counting semaphore for queue message availability static OS_MUTEX DisplayQ_Mutex; // mutex to ensure thread safety when writing/reading to queue + +/** + * Function prototypes +*/ +static void assertDisplayError(DisplayError_t err); + + /** * Enum and corresponding array for easy component selection. */ @@ -397,7 +404,7 @@ void Task_UpdateDisplay(void *p_arg) { * if we haven't reached the restart limit and want to restart the display */ static void handler_UpdateDisplay_Restart() { - Display_Restart(); // Try resetting the display + Display_Reset(); // Try resetting the display } /** diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 2ac2be493..a692fbb52 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -27,7 +27,6 @@ static const char *TERMINATOR = "\xff\xff\xff"; -static DisplayError_t displayError = DISPLAY_ERR_NONE; // Holds the current display error so we can inspect it DisplayError_t Display_Init(){ diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 704219f19..2836ced45 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -29,9 +29,19 @@ #include "UpdateDisplay.h" #include "CANConfig.h" +enum { // Test menu enum + TEST_GENERAL, + TEST_OS_ASSERT, + TEST_READTRITIUM_HALL, + TEST_READTRITIUM_NONHALL, // Maybe break this into others? + TEST_READCARCAN, + TEST_UPDATEDISPLAY +}; + /*** Constants ***/ -#define READY_MSG 0x4444 -#define STACK_SIZE 128 +#define TEST_OPTION TEST_UPDATEDISPLAY // Decide what to test based on test menu enum +#define READTRITIUM_OPTION 3 // The enum value for the tritium error we want to test (reference error enum) +// Choose from 0 - 11 /*** Task components ***/ @@ -46,11 +56,15 @@ static CPU_STK OSErrorTaskStk[DEFAULT_STACK_SIZE]; -/*** Globals ***/ -OS_SEM TestReady_Sema4; -OS_SEM TestDone_Sema4; +/*** Function prototypes ***/ +void createExceptionTask(void * callback_function); +void createOSErrorTask(void); +void createReadCarCAN(void); +void createReadTritium(void); +void createUpdateDisplay(void); + // Assertion function for OS errors void checkOSError(OS_ERR err) { if (err != OS_ERR_NONE) { @@ -58,7 +72,7 @@ void checkOSError(OS_ERR err) { __asm("bkpt"); } } - + // Callback function for ExceptionTask test exceptions @@ -70,14 +84,13 @@ void exceptionCallback(void) { // Creates an exception of priority 1 and 2 to test // test_callbacks: the callback function to use for the exceptions void ExceptionTask(void* test_callbacks) { - OS_ERR err; if (test_callbacks == NULL) { printf("\n\n\rTesting exceptions without callback functions"); } else { printf("\n\n\rTesting exceptions with callback functions"); } - // Throw a priority 2 exception + // Throw a printf("\n\n\rThrowing priority level 2 exception"); exception_t prio2Exception = {.prio = PRI_RECOV, .message = "\n\rprio2 exception message", .callback = test_callbacks}; assertExceptionError(prio2Exception); @@ -85,7 +98,6 @@ void ExceptionTask(void* test_callbacks) { // Throw a priority 1 exception printf("\n\n\rThrowing priority level 1 exception"); exception_t prio1Exception = {.prio = PRI_NONRECOV, .message = "\n\rprio1 exception message", .callback = test_callbacks}; - OSSemPost(&TestReady_Sema4, OS_OPT_POST_1, &err); // Alert manager task that the test is almost finished assertExceptionError(prio1Exception); printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); @@ -94,13 +106,11 @@ void ExceptionTask(void* test_callbacks) { // Test the assertOSError function by pending on a mutex that wasn't created void OSErrorTask(void* arg) { - OS_ERR err; OS_ERR test_err; OS_MUTEX testMut; CPU_TS ts; printf("\n\rasserting an OS error"); OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &test_err); - OSSemPost(&TestReady_Sema4, OS_OPT_POST_1, &err); assertOSError(OS_MAIN_LOC, test_err); printf("\n\rassertOSError test failed: assertion did not immediately result in an unrecoverable fault"); while(1){}; @@ -108,6 +118,269 @@ void OSErrorTask(void* arg) { + +// A high-priority task that manages other tasks and runs the tests +void Task_ManagerTask(void* arg) { + OS_ERR err; + CPU_Init(); + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); + CANbus_Init(MOTORCAN, NULL, 0); + CANbus_Init(CARCAN, NULL, 0); + Contactors_Init(); + //ErrorStatus errorCode; + CANDATA_t canError; + uint16_t tritiumError; + + + while (1) { + switch (TEST_OPTION) { + case TEST_GENERAL: + // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 + // Both with and without callback functions + // Successful if exception message and callback message (if applicable) are printed + // and the fail message is not printed (tasks are stopped when they assert an error) + printf("\n\n\r=========== Testing exception priorities 1 and 2 ==========="); + + // Test level 1 & 2 exceptions without callbacks + createExceptionTask(NULL); + printf("\n\rAt line %d", __LINE__); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // extra time for the task finished + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&ExceptionTaskTCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + + // Test level 1 & 2 exceptions with callbacks + createExceptionTask(exceptionCallback); + checkOSError(err); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&ExceptionTaskTCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + + break; + + case TEST_OS_ASSERT: // Decide what to do with this + + // Test the assertOSError function using the OSErrorTask + // Creates an OS error by pending on a mutex that isn't created + // Successful if it prints the OS Error code + // and doesn't print the fail message (task is stopped by asserting an error) + printf("\n\n\r=========== Testing OS assert ==========="); + + createOSErrorTask(); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&OSErrorTaskTCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&FaultState_TCB, &err); + + break; + + + case TEST_READTRITIUM_HALL: // 8, or 0x1000, for tritium hall error // Also seems to work + + canError.ID = MOTOR_STATUS; + tritiumError = T_HALL_SENSOR_ERR; // Leftshifted i-1 times, allows for an error of 0x00 + *((uint16_t*)(&canError.data[4])) = tritiumError; + + createReadTritium(); + // Send the message extra times to allow for motor restart + for (int i = 0; i < 4; i++) { // Faults if greater than restart threshold (3). Maybe we should change it to equal to threshold? + printf("\n\n\rNow sending: error %d", tritiumError); // Sending the hall sensor error message + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + printf("\n\rShould be testing Tritium hall error %d", (i + 1)); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + } + + // This code should not be reached because the error assertion should cause a nonrecoverable fault. + printf("\n\rTest failed: error assertion did not lead to an unrecoverable fault"); + OSTaskDel(&ReadTritium_TCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + + + + break; + + case TEST_READTRITIUM_NONHALL: // Seems to work + // Test exceptions in ReadTritium by creating the tasks and sending faults + // TODO: Change ReadTrititum so that we can print out the error code and not just a default message + printf("\n\n\r=========== Testing ReadTritium ==========="); + + uint16_t tritiumError = (0x01<>1; // Change to i-1? + *((uint16_t*)(&canError.data[4])) = tritiumError; + canError.ID = MOTOR_STATUS; + + createReadTritium(); + printf("\n\n\rNow sending: %d", tritiumError); // Sending 0 means no Tritium error + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + printf("\n\rShould be testing Tritium error %d", READTRITIUM_OPTION); + if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart + for (int i = 0; i < 4; i++) { // Faults if greater than restart threshold (3). Maybe we should change it to equal to threshold? + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + } + } + + OSTaskDel(&ReadTritium_TCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + + + break; + + + case TEST_READCARCAN: + + // Tests exceptions in ReadCarCAN by creating the tasks and sending messages + // Causes a weird issue where the last things that were printed are + // reprinted sixteen times all at once with some odd changes + // if the messages are sent enough times + // ex: 3 enable, 3 disable, 2 delay, 5 enable works + // but 5 enable ... doesn't + // I think the issue may occur if you let the test loop around + // enough, though. + printf("\n\n\r=========== Testing ReadCarCAN ==========="); + createReadCarCAN(); + checkOSError(err); + printf("\n\rCreated readCarCAN"); + + // Message for charging enable/disable + CANDATA_t chargeMsg; + chargeMsg.ID = CHARGE_ENABLE; + *(uint64_t*)(&chargeMsg.data) = 0; + chargeMsg.idx = 0; + printf("\n\rMade charging message"); + + // Message for BPS Fault + CANDATA_t tripBPSMsg; + tripBPSMsg.ID = BPS_TRIP; + *(uint64_t*)(&tripBPSMsg.data) = 0; + tripBPSMsg.idx = 0; + printf("\n\rMade BPS trip message"); + + + + + // Send charge enable messages + chargeMsg.data[0] = true; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\n\rSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + + // Send five charge disable messages to test prio-2 disable contactor callback + // Fault state should turn off contactors but not enter a nonrecoverable fault + chargeMsg.data[0] = false; + for(int i = 0; i<3; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\n\rSent disable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + + // Pause the delivery of messages to trigger the canWatchTimer + //TODO: Can't tell that anything is happening here at the moment + for(int i = 0; i<5; i++){ + printf("\n\rDelay %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + + // Send five more charge enable messages so the contactors get flipped on again + chargeMsg.data[0] = true; + for(int i = 0; i < 5; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\n\rSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + //TODO: Would these ever be on? Since there's no minion board we may not be able to check + printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors + printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); + printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + + // Send a trip message of 1 (trip) + // TODO: trip messages are not usually sent, + // so any trip message (even 0) should be a concern. + // Need to change things to handle them differently (might be in ignition fix PR already) + *(uint64_t*)(&tripBPSMsg.data) = 1; + CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); + printf("\n\rSent trip message %d", tripBPSMsg.data[0]); + OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); + + + // By now, the BPS Trip message should have been sent + //OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors + printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors + printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); + printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + + OSTaskDel(&ReadCarCAN_TCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&FaultState_TCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + break; + + + case TEST_UPDATEDISPLAY: + printf("\n\n\r=========== Test UpdateDisplay ==========="); + // Might be able to test if we UpdateDisplay_Init() and then make the task + // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. + // Call update display put next to overflow the queue (actual issue) + + // Note: currently gets stuck, so you may want to comment this section out to test ReadCarCAN + + createUpdateDisplay(); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&UpdateDisplay_TCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + + + UpdateDisplay_Init(); + createUpdateDisplay(); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + for (int i = 0; i < 10; i++) { + UpdateDisplay_SetCruiseState(0); + } + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + OSTaskDel(&UpdateDisplay_TCB, &err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); + break; + } + + + } + +} + + + // Task creation functions // Initializes FaultState @@ -129,7 +402,8 @@ void createFaultState(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err ); - checkOSError(err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); } @@ -153,6 +427,7 @@ void createReadTritium(void) { (OS_ERR*)&err ); checkOSError(err); + printf("\n\rin createReadTritium at line %d", __LINE__); } // Initializes ReadCarCAN @@ -166,8 +441,8 @@ void createReadCarCAN(void) { (void*)NULL, (OS_PRIO)5, (CPU_STK*)ReadCarCAN_Stk, - (CPU_STK_SIZE)128/10, - (CPU_STK_SIZE)128, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE/10, + (CPU_STK_SIZE)DEFAULT_STACK_SIZE, (OS_MSG_QTY)0, (OS_TICK)NULL, (void*)NULL, @@ -175,6 +450,7 @@ void createReadCarCAN(void) { (OS_ERR*)&err ); checkOSError(err); + printf("\n\rIn createReadCarCAN at line %d", __LINE__); } @@ -197,7 +473,8 @@ void createUpdateDisplay(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR *)&err ); - checkOSError(err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); } @@ -221,7 +498,8 @@ void createExceptionTask(void * callback_function) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR *)&err ); - checkOSError(err); + checkOSError(err); + printf("\n\rAt line %d", __LINE__); } @@ -244,233 +522,8 @@ void createOSErrorTask(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR *)&err ); - checkOSError(err); - -} - - - -// A high-priority task that manages other tasks and runs the tests -void Task_ManagerTask(void* arg) { - OS_ERR err; - CPU_TS ts; - CPU_Init(); - OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - CANbus_Init(MOTORCAN, NULL, 0); - CANbus_Init(CARCAN, NULL, 0); - Contactors_Init(); - OSSemCreate(&TestReady_Sema4, "Ready Flag Semaphore", 0, &err); - //ErrorStatus errorCode; - - - - while (1) { - // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 - // Both with and without callback functions - // Successful if exception message and callback message (if applicable) are printed - // and the fail message is not printed (tasks are stopped when they assert an error) - printf("\n\n\r=========== Testing exception priorities 1 and 2 ==========="); - - // Test level 1 & 2 exceptions without callbacks - createExceptionTask(NULL); - checkOSError(err); - createFaultState(); - checkOSError(err); - OSSemPend(&TestReady_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); // Wait for task to finish - checkOSError(err); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // extra time for the task finished - checkOSError(err); - OSTaskDel(&ExceptionTaskTCB, &err); - checkOSError(err); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - - // Test level 1 & 2 exceptions with callbacks - createExceptionTask(exceptionCallback); - checkOSError(err); - createFaultState(); - checkOSError(err); - OSSemPend(&TestReady_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - OSTaskDel(&ExceptionTaskTCB, &err); - checkOSError(err); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - - // Test the assertOSError function using the OSErrorTask - // Creates an OS error by pending on a mutex that isn't created - // Successful if it prints the OS Error code - // and doesn't print the fail message (task is stopped by asserting an error) - printf("\n\n\r=========== Testing OS assert ==========="); - - createOSErrorTask(); - checkOSError(err); - createFaultState(); - checkOSError(err); - OSSemPend(&TestReady_Sema4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); - checkOSError(err); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - OSTaskDel(&OSErrorTaskTCB, &err); - checkOSError(err); - OSTaskDel(&FaultState_TCB, &err); - - // Test exceptions in ReadTritium by creating the tasks and sending faults - // TODO: Change ReadTrititum so that we can print out the error code and not just a default message - printf("\n\n\r=========== Testing ReadTritium ==========="); - - CANDATA_t canError = {0}; - canError.ID=MOTOR_STATUS; - - - for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { - uint16_t tritiumError = (0x01<>1; // Change to i-1? - *((uint16_t*)(&canError.data[4])) = tritiumError; - - createFaultState(); - createReadTritium(); - printf("\n\rNow sending: %d", tritiumError); - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish - printf("\n\rShould be testing Tritium error %d", i); - if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart - for (int i = 0; i < 4; i++) { // Faults if greater than restart threshold (3). Maybe we should change it to equal to threshold? - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - } - } - - OSTaskDel(&ReadTritium_TCB, &err); - checkOSError(err); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - - } - - // Tests exceptions in ReadCarCAN by creating the tasks and sending messages - // Causes a weird issue where the last things that were printed are - // reprinted sixteen times all at once with some odd changes - // if the messages are sent enough times - // ex: 3 enable, 3 disable, 2 delay, 5 enable works - // but 5 enable ... doesn't - // I think the issue may occur if you let the test loop around - // enough, though. - printf("\n\n\r=========== Testing ReadCarCAN ==========="); - createFaultState(); - checkOSError(err); - createReadCarCAN(); - checkOSError(err); - - // Message for charging enable/disable - CANDATA_t chargeMsg; - chargeMsg.ID = CHARGE_ENABLE; - *(uint64_t*)(&chargeMsg.data) = 0; - chargeMsg.idx = 0; - - // Message for BPS Fault - CANDATA_t tripBPSMsg; - tripBPSMsg.ID = BPS_TRIP; - *(uint64_t*)(&tripBPSMsg.data) = 0; - tripBPSMsg.idx = 0; - - - - - // Send charge enable messages - chargeMsg.data[0] = true; - for(int i = 0; i<3; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - - // Send five charge disable messages to test prio-2 disable contactor callback - // Fault state should turn off contactors but not enter a nonrecoverable fault - chargeMsg.data[0] = false; - for(int i = 0; i<3; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent disable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - - // Pause the delivery of messages to trigger the canWatchTimer - //TODO: Can't tell that anything is happening here at the moment - for(int i = 0; i<2; i++){ - printf("\nDelay %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - - // Send five more charge enable messages so the contactors get flipped on again - chargeMsg.data[0] = true; - for(int i = 0; i < 5; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - //TODO: Would these ever be on? Since there's no minion board we may not be able to check - printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors - printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); - printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); - - // Send a trip message of 1 (trip) - // TODO: trip messages are not usually sent, - // so any trip message (even 0) should be a concern. - // Need to change things to handle them differently (might be in ignition fix PR already) - *(uint64_t*)(&tripBPSMsg.data) = 1; - CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); - printf("\nSent trip message %d", tripBPSMsg.data[0]); - OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); - - - // By now, the BPS Trip message should have been sent - //OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors - printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors - printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); - printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); - - OSTaskDel(&ReadCarCAN_TCB, &err); - checkOSError(err); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - - printf("\n\n\r=========== Test UpdateDisplay ==========="); - // Might be able to test if we UpdateDisplay_Init() and then make the task - // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. - // Call update display put next to overflow the queue (actual issue) - - // Note: currently gets stuck, so you may want to comment this section out to test ReadCarCAN - - createUpdateDisplay(); - createFaultState(); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - OSTaskDel(&UpdateDisplay_TCB, &err); - checkOSError(err); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - - UpdateDisplay_Init(); - createUpdateDisplay(); - createFaultState(); - for (int i = 0; i < 10; i++) { - UpdateDisplay_SetPage(0); //update display put next is static so I'll try this instead - // It doesn't seem to work, though. - // I appear to be getting stuck in txfifo_is_full instead - } - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - OSTaskDel(&UpdateDisplay_TCB, &err); - checkOSError(err); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - - - } + checkOSError(err); + printf("\n\rAt line %d", __LINE__); } @@ -482,6 +535,7 @@ int main(void) { OSInit(&err); checkOSError(err); + printf("\n\rIn main at line %d", __LINE__); // Create the task manager thread @@ -501,9 +555,11 @@ int main(void) { (OS_ERR*)&err ); checkOSError(err); + printf("\n\rAt line %d", __LINE__); OSStart(&err); checkOSError(err); + printf("\n\rIn main after OS start at line %d", __LINE__); while(1) {} } From 95a5e038c898aa9f786d236f5bc9bcbbaf3fe643 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 5 Jul 2023 19:21:26 +0000 Subject: [PATCH 090/141] This is a commit where I tried to test assertDisplayError by using the SetCruiseState function and it didn't work because it returns an error but nothing checks it and the assertDisplayError function is static. Next I'm going try using PutNext to overflow the fifo because I think that was something we wanted to test, but in order to do that I'm going to have to make it nonstatic. --- Tests/Test_FaultThread_Exceptions.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 2836ced45..c1b94999f 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -2,12 +2,16 @@ * * This file tests the fault state exception struct mechanism * to ensure thrown exceptions are handled correctly. - * It does this by testing the assertion functions for each priority option - * and creating and faulting tasks using the car and bps sim on Renode + * It does this by creating and faulting tasks + * to see if they stop working when an exception is thrown. + * + * Choose the task to test using TEST_OPTION. + * If testing ReadTritium non-Hall, choose the tritium error using READTRITIUM_OPTION. + * Once the task enters an infinite loop, it won't ever exit and you'll need to restart the test. * * This test is run in LoopBack mode with all messages sent and received by the LeaderBoard. * However, it can be run in conjunction with motor-sim and car-sim - * ( which don't do anything) when simulated to appease Renode + * (which don't do anything) when simulated to appease Renode. * * @file * @author Madeleine Lee (madeleinercflee@utexas.edu) @@ -348,29 +352,21 @@ void Task_ManagerTask(void* arg) { // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. // Call update display put next to overflow the queue (actual issue) - // Note: currently gets stuck, so you may want to comment this section out to test ReadCarCAN - createUpdateDisplay(); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - OSTaskDel(&UpdateDisplay_TCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - + Display_Init(); UpdateDisplay_Init(); createUpdateDisplay(); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + + OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); for (int i = 0; i < 10; i++) { - UpdateDisplay_SetCruiseState(0); + UpdateDisplay_SetCruiseState(1 + i); } OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); printf("\n\rAt line %d", __LINE__); OSTaskDel(&UpdateDisplay_TCB, &err); checkOSError(err); - printf("\n\rAt line %d", __LINE__); break; } From c6663a1ba08c3788ca810485fa198ad9274318fd Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 5 Jul 2023 19:30:20 +0000 Subject: [PATCH 091/141] Removed assertDisplayError from UpdateDisplay header file to make it a static function --- Apps/Inc/UpdateDisplay.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 75f6c8d99..fa11a2fde 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -30,8 +30,8 @@ typedef enum{ UPDATEDISPLAY_ERR_FIFO_PUT =-1, // Error putting command in fifo UPDATEDISPLAY_ERR_FIFO_POP =-2, // Error popping command from fifo UPDATEDISPLAY_ERR_PARSE_COMP =-3, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value - UPDATEDISPLAY_ERR_DRIVER =-5 + UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value + UPDATEDISPLAY_ERR_DRIVER =-5 // Driver call returned an error } UpdateDisplayError_t; /** From 85226cc0f0cd4984e9aa88677eaeaea05fd2a866 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 5 Jul 2023 19:40:58 +0000 Subject: [PATCH 092/141] Actually the display error thing seems to work as intended. Nothing major changed. --- Tests/Test_FaultThread_Exceptions.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index c1b94999f..c6ffa58f8 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -358,7 +358,6 @@ void Task_ManagerTask(void* arg) { UpdateDisplay_Init(); createUpdateDisplay(); - OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); for (int i = 0; i < 10; i++) { UpdateDisplay_SetCruiseState(1 + i); } From 8ac622663f3e68e31cde79bb9e5d99b13d28cbce Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 5 Jul 2023 20:43:50 +0000 Subject: [PATCH 093/141] Deleted faultstate things. --- Apps/Inc/FaultState.h | 14 ------ Apps/Inc/Tasks.h | 77 ++----------------------------- Apps/Src/FaultState.c | 98 ---------------------------------------- Apps/Src/ReadCarCAN.c | 1 - Apps/Src/ReadTritium.c | 1 - Apps/Src/Tasks.c | 27 +++-------- Apps/Src/UpdateDisplay.c | 1 - Apps/Src/main.c | 19 -------- 8 files changed, 11 insertions(+), 227 deletions(-) delete mode 100644 Apps/Inc/FaultState.h delete mode 100644 Apps/Src/FaultState.c diff --git a/Apps/Inc/FaultState.h b/Apps/Inc/FaultState.h deleted file mode 100644 index 619c1ba54..000000000 --- a/Apps/Inc/FaultState.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __FAULT_STATE_H -#define __FAULT_STATE_H - -#include "Tasks.h" - -/** - * @brief Assert Error if non OS function call fails - * @param exception non OS Error that occurred - */ -void assertExceptionError(exception_t exception); - - - -#endif \ No newline at end of file diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 45668cea3..0b99516b5 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -17,15 +17,12 @@ /** * Priority Definitions - */ -#define TASK_FAULT_STATE_PRIO 1 -#define TASK_FAULT_HIGHPRIO_PRIO 1 + */ #define TASK_INIT_PRIO 2 -#define TASK_FAULT_LOWPRIO_PRIO 3 -#define TASK_READ_TRITIUM_PRIO 4 -#define TASK_SEND_TRITIUM_PRIO 5 -#define TASK_READ_CAR_CAN_PRIO 6 -#define TASK_UPDATE_DISPLAY_PRIO 7 +#define TASK_READ_TRITIUM_PRIO 3 +#define TASK_SEND_TRITIUM_PRIO 4 +#define TASK_READ_CAR_CAN_PRIO 5 +#define TASK_UPDATE_DISPLAY_PRIO 6 #define TASK_SEND_CAR_CAN_PRIO 8 #define TASK_TELEMETRY_PRIO 9 @@ -35,7 +32,6 @@ #define DEFAULT_STACK_SIZE 256 #define WATERMARK_STACK_LIMIT DEFAULT_STACK_SIZE/2 -#define TASK_FAULT_STATE_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_INIT_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_SEND_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE #define TASK_READ_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE @@ -52,8 +48,6 @@ /** * Task Prototypes */ -void Task_FaultState(void* p_arg); - void Task_Init(void* p_arg); void Task_SendTritium(void* p_arg); @@ -77,7 +71,6 @@ void Task_Telemetry(void* p_arg); /** * TCBs */ -extern OS_TCB FaultState_TCB; // To be deleted extern OS_TCB Init_TCB; extern OS_TCB SendTritium_TCB; extern OS_TCB ReadCarCAN_TCB; @@ -91,7 +84,6 @@ extern OS_TCB Telemetry_TCB; /** * Stacks */ -extern CPU_STK FaultState_Stk[TASK_FAULT_STATE_STACK_SIZE]; // To be deleted extern CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; extern CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; extern CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; @@ -137,38 +129,12 @@ typedef enum{ OS_CANDRIVER_LOC = 0x400, OS_MOTOR_CONNECTION_LOC = 0x800, OS_DISPLAY_LOC = 0x1000, - OS_FAULT_STATE_LOC = 0x2000, // to be deleted OS_TASKS_LOC = 0x2000, } os_error_loc_t; -/** - * Fault Enum - * - * Different fault states that need to be handled by the FaultState task - */ -typedef enum{ - FAULT_NONE = 0x00, // No fault - FAULT_OS = 0x01, // for OS faults - FAULT_UNREACH = 0x02, // for unreachable conditions - FAULT_TRITIUM = 0x04, // for errors sent from the tritium - FAULT_READBPS = 0x08, // for unsuccessfully reading from BPS CAN - FAULT_DISPLAY = 0x10, // for display faults - FAULT_BPS = 0x20, // for if BPS trips -} fault_bitmap_t; - -/** - * Error handler task enum -*/ -typedef enum { - TASK_READ_TRITIUM = 0, - TASK_READ_CAR_CAN = 1, - TASK_UPDATE_DISPLAY = 2 -} error_task_t; - /** * Error variables */ -extern fault_bitmap_t FaultBitmap; extern os_error_loc_t OSErrLocBitmap; // Store error codes, set in task error assertion functions @@ -176,29 +142,6 @@ extern error_code_t Error_ReadTritium; extern error_code_t Error_ReadCarCAN; extern error_code_t Error_UpdateDisplay; -/** - * Fault Exception Enum - * For the "prio" field of a fault exception struct to determine handling mode - */ -typedef enum { - PRI_RESERVED = 0, // Currently unused, reserved prio of max severity for future use - PRI_NONRECOV = 1, // Kills contactors, turns on lights, and enters a nonrecoverable fault - PRI_RECOV = 2, // Returns to thread (no action besides message and callback) - -} exception_prio_t; - -/** - * Fault Exception Struct - * Created by different tasks and passed to fault thread by asserting errors - * Priority: 1 for nonrecoverable fault, 2 for callback only - * Callback function will run first regardless of priority -*/ -typedef struct{ - exception_prio_t prio; - const char* message; - void (*callback)(void); -} exception_t; - /** * Error-handling option enums */ @@ -221,16 +164,6 @@ typedef enum { */ void arrayMotorKill(); -/** - * @brief Used by error assertion functions to handle and signal a critical error - * Kills contactors, turns on brakelights, displays the fault screen with error code, - * and enters an infinite while loop - * TODO: add paramaters to display fault screen - * @param osLocCode Location code to display the name of the task, currently uses the OS_ERR_LOC enum - * @param faultCode The enum value for the task's specific error code -*/ -void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode); - /** * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, * and jumping to the error's specified callback function diff --git a/Apps/Src/FaultState.c b/Apps/Src/FaultState.c deleted file mode 100644 index 3f8c780dc..000000000 --- a/Apps/Src/FaultState.c +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @copyright Copyright (c) 202X UT Longhorn Racing Solar - * @file FaultState.c - * @brief - * - * This contains - * - * @author -*/ - -#include "FaultState.h" -#include "Display.h" -#include "Contactors.h" -#include "os.h" -#include "Tasks.h" -#include "Contactors.h" -#include "Minions.h" -#include "UpdateDisplay.h" -#include "ReadTritium.h" -extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. - -/** - * Semaphores - */ -OS_SEM FaultState_Sem4; -OS_SEM ExceptionProtection_Sem4; - -// current exception is initialized -exception_t currException = {.prio=PRI_RECOV,.message=NULL,.callback=NULL}; - -/** - * @brief Assert Error if non OS function call fails - * @param exception non OS Error that occurred - */ -void assertExceptionError(exception_t exception){ - OS_ERR err; - CPU_TS ticks; - - OSSemPend(&ExceptionProtection_Sem4, 0, OS_OPT_POST_NONE, &ticks, &err); - assertOSError(OS_FAULT_STATE_LOC, err); - - currException = exception; - - OSSemPost(&FaultState_Sem4, OS_OPT_POST_1, &err); - //printf("\n\rThis should happen after the exception is handled"); - assertOSError(OS_FAULT_STATE_LOC, err); -} - -static void nonrecoverableFaultHandler(){ - // Turn additional brakelight on to indicate critical error - BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); - - // Array motor kill - BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); - BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); - while(1){;} //nonrecoverable -} - - -void EnterFaultState(void) { - - printf("\r\n%s\r\n", currException.message); - if(currException.callback != NULL){ - currException.callback(); - } // Custom callback - - switch (currException.prio) - { - case PRI_RESERVED: - // Things could always be worse - // (Reserved for future cases of greater severity) - case PRI_NONRECOV: - nonrecoverableFaultHandler(); - break; - case PRI_RECOV: - // Priority level 2 only calls callback - break; - default: - break; - } - -} - -void Task_FaultState(void *p_arg) { - OS_ERR err; - CPU_TS ts; - - OSSemCreate(&ExceptionProtection_Sem4, "Fault State Exception Protection Semaphore", 1, &err); // To ensure currException won't be replaced too soon - OSSemCreate(&FaultState_Sem4, "Fault State Semaphore", 0, &err); - - // Block until fault is signaled by an assert - while(1){ - OSSemPend(&FaultState_Sem4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); - EnterFaultState(); - OSSemPost(&ExceptionProtection_Sem4, OS_OPT_POST_NONE, &err); - assertOSError(OS_FAULT_STATE_LOC, err); // We've finished handling the error and can post the mutex now - } -} \ No newline at end of file diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 02462bd70..6f768239a 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -3,7 +3,6 @@ #include "ReadCarCAN.h" #include "UpdateDisplay.h" #include "Contactors.h" -#include "FaultState.h" #include "Minions.h" #include "Minions.h" #include "os_cfg_app.h" diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 8db3ef867..bfafd59c6 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -4,7 +4,6 @@ #include "CAN_Queue.h" #include "CANbus.h" #include "UpdateDisplay.h" -#include "FaultState.h" #include //status limit flag masks diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 2e58c93e3..295043929 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -1,19 +1,20 @@ /* Copyright (c) 2020 UT Longhorn Racing Solar */ #include "Tasks.h" -#include "FaultState.h" #include "os.h" #include "CANbus.h" #include "Contactors.h" #include "Display.h" #include "Minions.h" #include "Pedals.h" +#include "ReadTritium.h" // For ReadTritium error enum +#include "ReadCarCAN.h" // For ReadCarCAN error enum +#include "UpdateDisplay.h" // For update display error enum /** * TCBs */ -OS_TCB FaultState_TCB; // To be deleted OS_TCB Init_TCB; OS_TCB SendTritium_TCB; OS_TCB ReadCarCAN_TCB; @@ -25,7 +26,6 @@ OS_TCB Telemetry_TCB; /** * Stacks */ -CPU_STK FaultState_Stk[TASK_FAULT_STATE_STACK_SIZE]; // To be deleted CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; @@ -38,11 +38,10 @@ CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; /** * Global Variables */ -fault_bitmap_t FaultBitmap = FAULT_NONE; // Used for faultstate handling, otherwise not used. TODO: Should be deleted? os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; -error_code_t Error_ReadTritium = NULL; // Variables to store error codes, stored and cleared in task error assert functions -error_code_t Error_ReadCarCAN = NULL; -error_code_t Error_UpdateDisplay = NULL; +error_code_t Error_ReadTritium = T_NONE; // Variables to store error codes, stored and cleared in task error assert functions +//error_code_t Error_ReadCarCAN = RCC_ERR_NONE; +error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. @@ -113,17 +112,3 @@ void arrayMotorKill() { // Turn additional brakelight on to indicate critical error BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); } - -/** - * TODO: delete? -*/ -void nonrecoverableErrorHandler(os_error_loc_t osLocCode, uint8_t faultCode){ - // Turn off contactors, turn on brakelight as a signal - arrayMotorKill(); - - // Display the fault screen with the error location and code - Display_Error(osLocCode, faultCode); - - while(1){;} //nonrecoverable -} - diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index a5a86fbf3..c8d27850e 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -13,7 +13,6 @@ */ #include "UpdateDisplay.h" #include "Minions.h" -#include "FaultState.h" #include /** diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 9b46f1ef8..9ca07d134 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -21,7 +21,6 @@ int main(void) { // Initialize some fault bitmaps for error checking purposes OSErrLocBitmap = OS_NONE_LOC; - FaultBitmap = FAULT_NONE; OS_ERR err; OSInit(&err); @@ -84,24 +83,6 @@ void Task_Init(void *p_arg){ // Initialize applications UpdateDisplay_Init(); - // Initialize FaultState - OSTaskCreate( - (OS_TCB*)&FaultState_TCB, - (CPU_CHAR*)"FaultState", - (OS_TASK_PTR)Task_FaultState, - (void*)NULL, - (OS_PRIO)TASK_FAULT_STATE_PRIO, - (CPU_STK*)FaultState_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_FAULT_STATE_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - assertOSError(OS_MAIN_LOC, err); - // Initialize SendTritium OSTaskCreate( (OS_TCB*)&SendTritium_TCB, From 82a419c5d72c75bf72a5db47a7807e94540da43c Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 5 Jul 2023 23:10:14 +0000 Subject: [PATCH 094/141] Small documentation changes. --- Apps/Inc/Tasks.h | 2 +- Apps/Src/ReadTritium.c | 15 +++++++++------ Apps/Src/Tasks.c | 4 ++++ Apps/Src/UpdateDisplay.c | 23 ++++++++++++----------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 0b99516b5..2887d0053 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -160,7 +160,7 @@ typedef enum { /** * @brief For use in error handling: turns off array and motor contactor, turns on additional brakelight - * to signal a ciritical error happened. Separated from nonrecoverable fault handler + * to signal a ciritical error happened. */ void arrayMotorKill(); diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index bfafd59c6..2d78542b3 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -128,23 +128,26 @@ float Motor_Velocity_Get(){ //getter function for motor velocity * Passed as callback functions to the main assertTaskError function by assertTritiumError */ -// A callback function to be run by the main assertTaskError function for hall sensor errors +/** + * @brief A callback function to be run by the main assertTaskError function for hall sensor errors + * restart the motor if the number of hall errors is still less than the RESTART_THRESHOLD. + */ static void handler_Tritium_HallError() { - MotorController_Restart(); // Try restarting the motor + MotorController_Restart(); } /** * @brief Assert Error if Tritium sends error by passing in and checking Motor_FaultBitmap * and asserting the error with its handler callback if one exists. - * Can result in restarting the motor (first few hall sensor errors) - * or locking the scheduler and entering a nonrecoverable fault for most other errors + * Can result in restarting the motor (while < RESTART_THRESHOLD hall sensor errors) + * or locking the scheduler and entering a nonrecoverable fault (other errors) * @param motor_err Bitmap with motor error codes to check */ static void assertTritiumError(tritium_error_code_t motor_err){ - static uint8_t hall_fault_cnt = 0; //trip counter + static uint8_t hall_fault_cnt = 0; //trip counter, doesn't ever reset - Error_ReadTritium = motor_err; + Error_ReadTritium = motor_err; // Store error code for inspection info if(motor_err != T_NONE){ // We need to handle an error if(motor_err != T_HALL_SENSOR_ERR){ diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 295043929..f2e21bb41 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -104,6 +104,10 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t erro } } +/** + * @brief For use in error handling: turns off array and motor contactor, turns on additional brakelight + * to signal a ciritical error happened. +*/ void arrayMotorKill() { // Array motor kill BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index c8d27850e..44dfeb84e 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -26,7 +26,7 @@ #include "fifo.h" // For fault handling -#define RESTART_THRESHOLD 3 +#define RESTART_THRESHOLD 3 // number of times to reset before displaying the fault screen disp_fifo_t msg_queue; @@ -37,7 +37,8 @@ static OS_MUTEX DisplayQ_Mutex; // mutex to ensure thread safety when writing/re /** * Function prototypes */ -static void assertDisplayError(DisplayError_t err); +// check for and assert errors in UpdateDisplay +static void assertDisplayError(DisplayError_t err); /** @@ -395,20 +396,20 @@ void Task_UpdateDisplay(void *p_arg) { /** * Error handler functions - * Passed as callback functions to the main assertTaskError function by assertTritiumError + * Passed as callback functions to the main assertTaskError function by assertDisplayError */ /** * @brief A handler callback function run by the main assertTaskError function - * if we haven't reached the restart limit and want to restart the display + * used if we haven't reached the restart limit and encounter an error */ static void handler_UpdateDisplay_Restart() { - Display_Reset(); // Try resetting the display + Display_Reset(); // Try resetting to fix the display error } /** - * @brief A handler callback function run by the main assertTaskError function - * if we have reached the restart limit and want to show the error screen + * @brief A handler callback function run by the main assertTaskErrorfunction + * to show the error screen if we have reached the restart limit */ static void handler_UpdateDisplay_ShowError() { Display_Error(OS_DISPLAY_LOC, Error_UpdateDisplay); // Try resetting the display @@ -416,12 +417,12 @@ static void handler_UpdateDisplay_ShowError() { /** - * @brief Check for a display error and assert one if it exists. + * @brief Check for a display error and assert it if it exists. * Sotres the error code, calls the main assertion function - * and runs a handler to restart or display the error. + * and runs a callback function as a handler to restart the display or show the error. * @param err variable with display error codes */static void assertDisplayError(DisplayError_t err){ - static uint8_t disp_error_cnt = 0; // Keep track of the number of times the display has an error + static uint8_t disp_error_cnt = 0; // Track the number of display errors, doesn't ever reset Error_UpdateDisplay = err; // Store the error code for inspection @@ -429,7 +430,7 @@ static void handler_UpdateDisplay_ShowError() { disp_error_cnt++; if (disp_error_cnt > RESTART_THRESHOLD){ - // Use error assertion to show error screen if at restart attempt limit + // Show error screen if restart attempt limit has been reached assertTaskError(OS_DISPLAY_LOC, err, handler_UpdateDisplay_ShowError, OPT_NO_LOCK_SCHED, OPT_RECOV); } else { // Otherwise try resetting the display using the restart callback From 211b64380c0ef6d385c08b961e27c3527551228c Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 5 Jul 2023 23:31:56 +0000 Subject: [PATCH 095/141] Reverted ReadCarCAN to where it was before fix_ignition_delay branched off to prepare for merging update_faultstate into fix_ignition_delay. --- Apps/Src/ReadCarCAN.c | 76 +++++++++---------------------------------- 1 file changed, 16 insertions(+), 60 deletions(-) diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 6f768239a..875e7e51d 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -3,6 +3,7 @@ #include "ReadCarCAN.h" #include "UpdateDisplay.h" #include "Contactors.h" +#include "FaultState.h" #include "Minions.h" #include "Minions.h" #include "os_cfg_app.h" @@ -39,26 +40,18 @@ static uint8_t oldestMsgIdx = 0; static uint8_t SOC = 0; static uint32_t SBPV = 0; -// Error type enum with all possible ReadCarCAN errors for error assertion and display -typedef enum{ - RCC_ERR_NONE, - RCC_ERR_CHARGE_DISABLE_MSG, - RCC_ERR_MISSED_BPS_MSG, - RCC_ERR_BPS_TRIP -} readCarCAN_error_t; -// Error code variable -static readCarCAN_error_t readCarCANError; +// Handler to turn array back on +static void arrayRestart(void *p_tmr, void *p_arg); -// Public getter function for chargeEnable +// Getter function for chargeEnable bool ChargeEnable_Get() { return chargeEnable; } - /** * @brief adds new messages by overwriting old messages in the saturation buffer and then updates saturation * @param chargeMessage whether bps message was charge enable (1) or disable (-1) @@ -78,30 +71,24 @@ static void updateSaturation(int8_t chargeMessage){ } // exception struct callback for charging disable, kills contactors and turns of display -//TODO: rename this static void callback_disableContactors(void){ // Kill contactors - Contactors_Set(ARRAY_CONTACTOR, OFF, true); // TODO: Change this to a GPIO write because WE DON'T CARE ABOUT PENDING ON YOUR STUPID SEMAPHORES - Contactors_Set(ARRAY_PRECHARGE, OFF, true); // TODO: Add chargeEnable = false? - // Using a GPIO write instead of Contactors_Set for speed, and to avoid blocking calls in timer callbacks - // This also eliminates the possibility of a deadlock in case Task_Init has the contactorsMutex for the motor contactor - // I don't think skipping the function or pend is an issue because the array contactor is only turned on in array restart, - // and if charging is disabled then it won't turn them back on. - - // Being interrupted after checking chargeEnable isn't possible because arrayRestart happens in a timer callback, - // which is performed with the scheduler locked. + Contactors_Set(ARRAY_CONTACTOR, OFF, true); + Contactors_Set(ARRAY_PRECHARGE, OFF, true); // Turn off the array contactor display light UpdateDisplay_SetArray(false); } // helper function to disable charging -static void chargingDisable(void) { +// Turns off contactors by signaling fault state +static inline void chargingDisable(void) { // mark regen as disabled chargeEnable = false; // kill contactors - callback_disableContactors(); + exception_t readBPSError = {.prio=2, .message="read BPS error", .callback=callback_disableContactors}; + assertExceptionError(readBPSError); } // helper function to call if charging should be enabled @@ -164,41 +151,6 @@ void canWatchTimerCallback (void *p_tmr, void *p_arg){ } -/** - * @brief Error assertion function to check and handle errors in ReadCarCAN - * @param errorCode the variable to check for errors - */ -static void assertReadCarCANError(readCarCAN_error_t errorCode) { - OS_ERR err; - - readCarCANError = errorCode; // Allows us to inspect what error we encountered - - // Check the type of error in a switch case - switch (errorCode) { - case RCC_ERR_BPS_TRIP: - OSSchedLock(&err); - arrayMotorKill(); // Disable all contactors - Display_Evac(SOC, SBPV); // Display the evacuation screen instead of the fault screen - while(1){;} // Enter a nonrecoverable loop - break; - - case RCC_ERR_MISSED_BPS_MSG: - case RCC_ERR_CHARGE_DISABLE_MSG: //TODO: is there any difference in how we should andle the missed BPS message vs charging disable? If not, we can let this case falll through. - OSSchedLock(&err); // Want to handle this first without interruptions - chargingDisable(); // Mark chargeEnable as false, turn off contactors, and change display light - //TODO: make sure this takes care of everything we need to do for a missed BPS message. - OSSchedUnlock(&err); - break; - - default: - break; - - } - - readCarCANError = RCC_ERR_NONE; // Clear the error once it has been handled - -} - void Task_ReadCarCAN(void *p_arg) { @@ -255,9 +207,13 @@ void Task_ReadCarCAN(void *p_arg) case BPS_TRIP: { // BPS has a fault and we need to enter fault state (probably) if(dataBuf.data[0] == 1){ // If buffer contains 1 for a BPS trip, we should enter a nonrecoverable fault + + Display_Evac(SOC, SBPV); // Display evacuation message + // Create an exception and assert the error - // Display evacuation message, kill contactors, and enter a nonrecoverable fault - assertReadCarCANError(RCC_ERR_BPS_TRIP); + // kill contactors and enter a nonrecoverable fault + exception_t tripBPSError = {.prio=1, .message="BPS has been tripped", .callback=callback_disableContactors}; + assertExceptionError(tripBPSError); } } case CHARGE_ENABLE: { From 5c0f76053038b849561ced40a4af2db115e21825 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 5 Jul 2023 23:38:56 +0000 Subject: [PATCH 096/141] Renamed assertDisplayError to assertUpdateDisplayError to reduce changes to files. --- Apps/Inc/UpdateDisplay.h | 2 +- Apps/Src/UpdateDisplay.c | 50 ++++++++++++++++++++-------------------- Drivers/Inc/Display.h | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index fa11a2fde..dba6cf42d 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -4,7 +4,7 @@ * @brief Function prototypes for the display application. * * This contains function prototypes relevant to the UpdateDisplay - * application. Call assertDisplayError after calling any of the + * application. Call assertUpdateDisplayError after calling any of the * functions in this application. * * @author Ishan Deshpande (IshDeshpa) diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 44dfeb84e..bb72a08d2 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -38,7 +38,7 @@ static OS_MUTEX DisplayQ_Mutex; // mutex to ensure thread safety when writing/re * Function prototypes */ // check for and assert errors in UpdateDisplay -static void assertDisplayError(DisplayError_t err); +static void assertUpdateDisplayError(DisplayError_t err); /** @@ -88,7 +88,7 @@ UpdateDisplayError_t UpdateDisplay_Init(){ assertOSError(OS_DISPLAY_LOC, err); UpdateDisplayError_t ret = UpdateDisplay_SetPage(INFO); - assertDisplayError(ret); + assertUpdateDisplayError(ret); return ret; } @@ -116,12 +116,12 @@ static UpdateDisplayError_t UpdateDisplay_PopNext(){ assertOSError(OS_SEND_CAN_LOC, err); if(!result){ - assertDisplayError(UPDATEDISPLAY_ERR_FIFO_POP); + assertUpdateDisplayError(UPDATEDISPLAY_ERR_FIFO_POP); return UPDATEDISPLAY_ERR_FIFO_POP; } // Assert a display driver error code if the send fails, else assert that there's no error - assertDisplayError(Display_Send(cmd) ? UPDATEDISPLAY_ERR_DRIVER : UPDATEDISPLAY_ERR_NONE); + assertUpdateDisplayError(Display_Send(cmd) ? UPDATEDISPLAY_ERR_DRIVER : UPDATEDISPLAY_ERR_NONE); return UPDATEDISPLAY_ERR_NONE; } @@ -147,7 +147,7 @@ static UpdateDisplayError_t UpdateDisplay_PutNext(DisplayCmd_t cmd){ assertOSError(OS_DISPLAY_LOC, err); } else{ - assertDisplayError(UPDATEDISPLAY_ERR_FIFO_PUT); + assertUpdateDisplayError(UPDATEDISPLAY_ERR_FIFO_PUT); return UPDATEDISPLAY_ERR_FIFO_PUT; } @@ -174,7 +174,7 @@ static UpdateDisplayError_t UpdateDisplay_Refresh(){ }; UpdateDisplayError_t ret = UpdateDisplay_PutNext(refreshCmd); - assertDisplayError(ret); + assertUpdateDisplayError(ret); return ret; } @@ -203,7 +203,7 @@ static UpdateDisplayError_t UpdateDisplay_SetComponent(Component_t comp, uint32_ }; ret = UpdateDisplay_PutNext(visCmd); - assertDisplayError(ret); + assertUpdateDisplayError(ret); return ret; } // For components that have a non-boolean value @@ -220,11 +220,11 @@ static UpdateDisplayError_t UpdateDisplay_SetComponent(Component_t comp, uint32_ }; ret = UpdateDisplay_PutNext(setCmd); - assertDisplayError(ret); + assertUpdateDisplayError(ret); return UpdateDisplay_PutNext(setCmd); } else{ - assertDisplayError(UPDATEDISPLAY_ERR_PARSE_COMP); + assertUpdateDisplayError(UPDATEDISPLAY_ERR_PARSE_COMP); return UPDATEDISPLAY_ERR_PARSE_COMP; } return UPDATEDISPLAY_ERR_NONE; @@ -254,11 +254,11 @@ UpdateDisplayError_t UpdateDisplay_SetSOC(uint8_t percent){ // Integer percentag } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SOC, percent); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastPercent = percent; return ret; @@ -271,11 +271,11 @@ UpdateDisplayError_t UpdateDisplay_SetSBPV(uint32_t mv){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SUPP_BATT, mv/100); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastMv = mv; return ret; @@ -288,7 +288,7 @@ UpdateDisplayError_t UpdateDisplay_SetVelocity(uint32_t mphTenths){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(VELOCITY, mphTenths); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastMphTenths = mphTenths; return ret; @@ -301,7 +301,7 @@ UpdateDisplayError_t UpdateDisplay_SetAccel(uint8_t percent){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ACCEL_METER, percent); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastPercentAccel = percent; return ret; @@ -314,7 +314,7 @@ UpdateDisplayError_t UpdateDisplay_SetArray(bool state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ARRAY, (state)?1:0); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -327,7 +327,7 @@ UpdateDisplayError_t UpdateDisplay_SetMotor(bool state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(MOTOR, (state)?1:0); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -340,11 +340,11 @@ UpdateDisplayError_t UpdateDisplay_SetGear(TriState_t gear){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(GEAR, (uint32_t)gear); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastGear = gear; return ret; @@ -357,11 +357,11 @@ UpdateDisplayError_t UpdateDisplay_SetRegenState(TriState_t state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(REGEN_ST, (uint32_t)state); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -377,7 +377,7 @@ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertDisplayError(ret); + assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -389,14 +389,14 @@ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ void Task_UpdateDisplay(void *p_arg) { while (1) { UpdateDisplayError_t err = UpdateDisplay_PopNext(); - assertDisplayError(err); + assertUpdateDisplayError(err); } } /** * Error handler functions - * Passed as callback functions to the main assertTaskError function by assertDisplayError + * Passed as callback functions to the main assertTaskError function by assertUpdateDisplayError */ /** @@ -421,7 +421,7 @@ static void handler_UpdateDisplay_ShowError() { * Sotres the error code, calls the main assertion function * and runs a callback function as a handler to restart the display or show the error. * @param err variable with display error codes - */static void assertDisplayError(DisplayError_t err){ + */static void assertUpdateDisplayError(DisplayError_t err){ static uint8_t disp_error_cnt = 0; // Track the number of display errors, doesn't ever reset Error_UpdateDisplay = err; // Store the error code for inspection diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index 9129d8171..2c19720b0 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -4,7 +4,7 @@ * @brief Function prototypes for the display driver. * * This contains function prototypes relevant to sending/receiving messages - * to/from our Nextion HMI. Call assertDisplayError after calling any of the + * to/from our Nextion HMI. Call assertUpdateDisplayError after calling any of the * functions in this application. * * @author Ishan Deshpande (IshDeshpa) From 0e6464b7e5e72c7503877014b88f967f8686ac4c Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 8 Jul 2023 00:53:40 +0000 Subject: [PATCH 097/141] Deleted the motorsim and carsim files for faultstate testing because the current test runs in loopback mode and doesn't use extra Renode machines. --- CarSim/Test_car_FaultThread_Exceptions.c | 154 ------------------- MotorSim/Test_motor_FaultThread_Exceptions.c | 118 -------------- 2 files changed, 272 deletions(-) delete mode 100644 CarSim/Test_car_FaultThread_Exceptions.c delete mode 100644 MotorSim/Test_motor_FaultThread_Exceptions.c diff --git a/CarSim/Test_car_FaultThread_Exceptions.c b/CarSim/Test_car_FaultThread_Exceptions.c deleted file mode 100644 index 945261268..000000000 --- a/CarSim/Test_car_FaultThread_Exceptions.c +++ /dev/null @@ -1,154 +0,0 @@ -/** - * This is meant to test exception handling in the ReadTritium module by pretending to be the motor - * - * This testfile is intended to be compiled and run on Renode as the supplementary machine - * to send Tritium error messages to the main machine. - * It is designed to send messages on CAN3 (MOTORCAN) to test ReadTritium and FaultState's error handling. - * Specifically, it goes through each Tritium error and sends it to the leaderboard. - * - * Run this test in conjuction with Test_FaultThread_Exceptions - * - * @file - * @author Madeleine Lee (madeleinercflee@utexas.edu) - * @brief Tests the fault state exception mechanism - * @version - * @date 2023-6-08 - * - * @copyright Copyright (c) 2022 Longhorn Racing Solar - * -*/ - - -#include "Tasks.h" -#include "CANbus.h" -#include "BSP_UART.h" -#include "CANConfig.h" - -static OS_TCB Task1_TCB; -static CPU_STK Task1_Stk[128]; - -#define STACK_SIZE 128 -#define READY_MSG 0x4444 - - - -void Task1(void *p_arg){ - CPU_Init(); - OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - printf("\n\rAbout to init Canbus"); - CANbus_Init(CARCAN, NULL, 0); - printf("\n\rCanbus init-ed"); - OS_ERR err; - - CANDATA_t dataBuf; // A buffer in which we can store the messages we read - //uint16_t data = 0; - - // do { - // ErrorStatus status = CANbus_Read(&dataBuf, false, MOTORCAN); - // if (status != SUCCESS) { - // printf("\n\rCANbus Read error status: %d\n\r", status); - // } else { - // data = *((uint16_t*)(&dataBuf.data[0])); - // printf("\n\rWaiting for start. Read: %d", data); - // } - // OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - // } while (data != READY_MSG); - - CANDATA_t chargeMsg; - chargeMsg.ID = CHARGE_ENABLE; - *(uint64_t*)(&chargeMsg.data) = 0; - chargeMsg.idx = 0; - - // Message for BPS Fault - CANDATA_t tripBPSMsg; - tripBPSMsg.ID = BPS_TRIP; - *(uint64_t*)(&tripBPSMsg.data) = 0; - tripBPSMsg.idx = 0; - - - while (1) { - - // Send five charge enable messages so the contactors get flipped on - chargeMsg.data[0] = true; - for(int i = 0; i<5; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); - } - - // Send five charge disable messages to test prio-2 disable contactor callback - // Fault state should turn off contactors but not enter a nonrecoverable fault - chargeMsg.data[0] = false; - for(int i = 0; i<5; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent disable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); - } - - // Send five more charge enable messages so the contactors get flipped on again - chargeMsg.data[0] = true; - for(int i = 0; i<5; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\nSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); - } - - // Send a trip message of 1 (trip) - // Note: trip messages are not usually sent, - // so any trip message (even 0) should be a concern. - // Maybe we should handle them differently? - *(uint64_t*)(&tripBPSMsg.data) = 1; - CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); - printf("\nSent trip message %d", tripBPSMsg.data[0]); - - dataBuf.ID = CARDATA; - *((uint16_t*)(&dataBuf.data[0])) = READY_MSG; - CANbus_Send(dataBuf, CAN_NON_BLOCKING, CARCAN); - } - - while(1){}; - - - - -} - -int main(void){ //initialize things and spawn task - OS_ERR err; - OSInit(&err); - if(err != OS_ERR_NONE){ - printf("OS error code %d\n\r",err); - } - - BSP_UART_Init(UART_2); - - OSTaskCreate( - (OS_TCB*)&Task1_TCB, - (CPU_CHAR*)"Task1", - (OS_TASK_PTR)Task1, - (void*)NULL, - (OS_PRIO)4, - (CPU_STK*)Task1_Stk, - (CPU_STK_SIZE)STACK_SIZE/10, - (CPU_STK_SIZE)STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)NULL, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), - (OS_ERR*)&err - ); - - - if (err != OS_ERR_NONE) { - printf("Task1 error code %d\n\r", err); - } - OSStart(&err); - if (err != OS_ERR_NONE) { - printf("OS error code %d\n\r", err); - } - return 0; - -} - - - diff --git a/MotorSim/Test_motor_FaultThread_Exceptions.c b/MotorSim/Test_motor_FaultThread_Exceptions.c deleted file mode 100644 index 228754b43..000000000 --- a/MotorSim/Test_motor_FaultThread_Exceptions.c +++ /dev/null @@ -1,118 +0,0 @@ -/** - * This is meant to test exception handling in the ReadCarCAN module by pretending to be BPS. - * - * This testfile is intended to be compiled and run on Renode as the supplementary machine to send CAN messages to the main machine. - * It is designed to send messages on CAN1 (CARCAN) to test ReadCarCAN and FaultState's fault handling - * Specifically, it tests the exceptions for disabling charging and handling the BPS trip message - * - * Run this test in conjuction with Test_FaultThread_Exceptions - * - * @file - * @author Madeleine Lee (madeleinercflee@utexas.edu) - * @brief Supplemental testfile for testing the fault state exception mechanism - * @version - * @date 2023-6-08 - * - * @copyright Copyright (c) 2022 Longhorn Racing Solar - * -*/ - - -#include "Tasks.h" -#include "CANbus.h" -#include "ReadTritium.h" - - -#define STACK_SIZE 128 -#define READY_MSG 0x4444 - -static OS_TCB Task1_TCB; -static CPU_STK Task1_Stk[STACK_SIZE]; - - - - -void Task1(void *p_arg){ - CPU_Init(); - OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - printf("\n\rIn Task1"); - OS_ERR err; - CANDATA_t dataBuf = {0}; - CANbus_Init(MOTORCAN, NULL, 0); - uint16_t data = 0; - - CANDATA_t canError = {0}; - canError.ID=MOTOR_STATUS; - - - for (int i = 0; i < NUM_TRITIUM_ERRORS + 2; i++) { - do { - ErrorStatus status = CANbus_Read(&dataBuf, false, MOTORCAN); - if (status != SUCCESS) { - printf("CANbus Read error status: %d\n\r", status); - } else { - data = dataBuf.data[0]; - printf("\n\rWaiting for start. Read: %d", data); - } - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - } while (data != READY_MSG); - - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - uint16_t tritiumError = (0x01<>1; - *((uint16_t*)(&canError.data[4])) = tritiumError; - printf("\n\rNow sending: %d", tritiumError); - - // Send error messages to the leader board - if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - } - - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - - } - - - -} - -int main(void){ //startup OS stuff, spawn test task - - OS_ERR err; - OSInit(&err); - if(err != OS_ERR_NONE){ - printf("OS error code %d\n",err); - } - BSP_UART_Init(UART_2); - - - OSTaskCreate( - (OS_TCB*)&Task1_TCB, - (CPU_CHAR*)"Task1", - (OS_TASK_PTR)Task1, - (void*)NULL, - (OS_PRIO)4, - (CPU_STK*)Task1_Stk, - (CPU_STK_SIZE)STACK_SIZE/10, - (CPU_STK_SIZE)STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)NULL, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), - (OS_ERR*)&err - ); - - if (err != OS_ERR_NONE) { - printf("Task error code %d\n", err); - } - OSStart(&err); - if (err != OS_ERR_NONE) { - printf("OS error code %d\n", err); - } - return 0; -} - - - From dd0e14026586f66d7f29d3cb51465b7b39076f02 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 8 Jul 2023 02:19:03 +0000 Subject: [PATCH 098/141] Small documentation changes and file cleanup. --- Apps/Inc/Tasks.h | 21 ++++---- Apps/Src/ReadTritium.c | 12 ++--- Apps/Src/Tasks.c | 20 ++++--- Apps/Src/UpdateDisplay.c | 2 +- Tests/Test_Driver_CANbus.c | 106 ------------------------------------- 5 files changed, 30 insertions(+), 131 deletions(-) delete mode 100644 Tests/Test_Driver_CANbus.c diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 2887d0053..060924b35 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -137,7 +137,7 @@ typedef enum{ */ extern os_error_loc_t OSErrLocBitmap; -// Store error codes, set in task error assertion functions +// Store error codes that are set in task error assertion functions extern error_code_t Error_ReadTritium; extern error_code_t Error_ReadCarCAN; extern error_code_t Error_UpdateDisplay; @@ -146,32 +146,33 @@ extern error_code_t Error_UpdateDisplay; * Error-handling option enums */ -// Whether or not to lock the scheduler when asserting a task error +// Scheduler lock parameter option for asserting a task error typedef enum { OPT_LOCK_SCHED = false, OPT_NO_LOCK_SCHED = true } error_lock_sched_opt_t; -// Whether or not a task error is recoverable +// Recoverable/nonrecoverable parameter option for asserting a task error typedef enum { OPT_RECOV, OPT_NONRECOV } error_recov_opt_t; /** - * @brief For use in error handling: turns off array and motor contactor, turns on additional brakelight - * to signal a ciritical error happened. + * @brief For use in error handling: turns off array and motor contactor + * and turns on additional brakelight to signal that a critical error happened. */ void arrayMotorKill(); /** * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, - * and jumping to the error's specified callback function - * @param errorLoc the task from which the error originated. TODO: should be taken out when last task pointer is integrated - * @param faultCode the value for what specific error happened - * @param errorCallback a callback function to a handler for that specific error + * and jumping to the error's specified callback function. + * Called by task-specific error-assertion functions that are also responsible for setting the error variable. + * @param errorLoc the task from which the error originated. Note: should be taken out when last task pointer is integrated + * @param faultCode the enum for the specific error that happened + * @param errorCallback a callback function to a handler for that specific error, * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately - * @param nonrecoverable if true, kills the motor, displays the fault screen, and enters an infinite while loop + * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ void assertTaskError(os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback, error_lock_sched_opt_t lockSched, error_recov_opt_t nonrecoverable); diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 2d78542b3..d0dddd7c8 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -9,10 +9,10 @@ //status limit flag masks #define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor 6 #define MAX_CAN_LEN 8 -#define RESTART_THRESHOLD 3 // Number of times to try restarting the hall sensor +#define RESTART_THRESHOLD 3 // Number of times to restart before asserting a nonrecoverable error -tritium_error_code_t Motor_FaultBitmap = T_NONE; +tritium_error_code_t Motor_FaultBitmap = T_NONE; //initialized to no error, changed when the motor asserts an error static float Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read static float Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read @@ -138,10 +138,10 @@ static void handler_Tritium_HallError() { /** - * @brief Assert Error if Tritium sends error by passing in and checking Motor_FaultBitmap + * @brief Assert a Tritium error by checking Motor_FaultBitmap * and asserting the error with its handler callback if one exists. - * Can result in restarting the motor (while < RESTART_THRESHOLD hall sensor errors) - * or locking the scheduler and entering a nonrecoverable fault (other errors) + * Can result in restarting the motor (while < RESTART_THRESHOLD number of hall sensor errors) + * or locking the scheduler and entering a nonrecoverable fault (all other cases) * @param motor_err Bitmap with motor error codes to check */ static void assertTritiumError(tritium_error_code_t motor_err){ @@ -159,7 +159,7 @@ static void assertTritiumError(tritium_error_code_t motor_err){ //try to restart the motor a few times and then fail out if(hall_fault_cnt > RESTART_THRESHOLD){ - // Assert another nonrecoverable error, but this time motor_err will have a different error code + // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); } else { // Try restarting the motor // Assert a recoverable error that will run the motor restart callback function diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index f2e21bb41..4a8e99951 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -38,7 +38,7 @@ CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; /** * Global Variables */ -os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; +os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; // Store the location of the current error error_code_t Error_ReadTritium = T_NONE; // Variables to store error codes, stored and cleared in task error assert functions //error_code_t Error_ReadCarCAN = RCC_ERR_NONE; error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; @@ -65,11 +65,13 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) /** * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, - * and jumping to the error's specified callback function + * and jumping to the error's specified callback function. + * Called by task-specific error-assertion functions that are also responsible for setting the error variable. + * @param errorLoc the task from which the error originated. Note: should be taken out when last task pointer is integrated + * @param faultCode the enum for the specific error that happened + * @param errorCallback a callback function to a handler for that specific error, * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately - * @param errorLoc the task from which the error originated. TODO: should be taken out when last task pointer is integrated - * @param faultCode the value for what specific error happened - * @param errorCallback a callback function to a handler for that specific error + * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t errorCallback, error_lock_sched_opt_t lockSched, error_recov_opt_t nonrecoverable) { OS_ERR err; @@ -79,7 +81,7 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t erro assertOSError(OS_TASKS_LOC, err); } - // Set the error variables to store data //TODO: delete? + // Set the location error variable OSErrLocBitmap = errorLoc; if (nonrecoverable == OPT_NONRECOV) { @@ -102,11 +104,13 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t erro OSSchedUnlock(&err); assertOSError(OS_TASKS_LOC, err); } + + OSErrLocBitmap = OS_NONE_LOC; // Clear the location error variable once handled } /** - * @brief For use in error handling: turns off array and motor contactor, turns on additional brakelight - * to signal a ciritical error happened. + * @brief For use in error handling: turns off array and motor contactor + * and turns on additional brakelight to signal that a critical error happened. */ void arrayMotorKill() { // Array motor kill diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index bb72a08d2..557c24e33 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -418,7 +418,7 @@ static void handler_UpdateDisplay_ShowError() { /** * @brief Check for a display error and assert it if it exists. - * Sotres the error code, calls the main assertion function + * Stores the error code, calls the main assertion function * and runs a callback function as a handler to restart the display or show the error. * @param err variable with display error codes */static void assertUpdateDisplayError(DisplayError_t err){ diff --git a/Tests/Test_Driver_CANbus.c b/Tests/Test_Driver_CANbus.c deleted file mode 100644 index 1092755f2..000000000 --- a/Tests/Test_Driver_CANbus.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "Tasks.h" -#include "CANbus.h" -#include "BSP_UART.h" -#include "CANConfig.h" - -static OS_TCB Task1_TCB; -static CPU_STK Task1_Stk[128]; - -#define STACK_SIZE 128 - -#define CARCAN_FILTER_SIZE (sizeof carCANFilterList / sizeof(CANId_t)) - -static void assert(bool); - -CANDATA_t dataBuf, resultBuf; -uint64_t data = 0xdeadbeef12345678; - -/* - * NOTE: This test must be run with car CAN in loopback mode - * TODO: automate this, either with arguments to BSP or #define - */ - -void Task1(void *p_arg) { - (void) p_arg; - - CPU_Init(); - OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - - CANbus_Init(CARCAN, carCANFilterList, NUM_CARCAN_FILTERS); - - dataBuf.ID = CHARGE_ENABLE; // First, send a value that we want to be able to receive - memcpy(&dataBuf.data, &data, sizeof data); - - assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); - assert(CANbus_Read(&resultBuf, true, CARCAN) == SUCCESS); - assert(memcmp(&dataBuf, &resultBuf, sizeof dataBuf) == 0); // TODO: make sure that all 8 data bytes are copied - - dataBuf.ID = ODOMETER_AMPHOURS; // Now, send a message that we shouldn't receive - assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); - assert(CANbus_Read(&resultBuf, false, CARCAN) == ERROR); // check that no can message is read - - // Now send a bunch of messages that should be ignored, followed by those that shouldn't - for (int i=0; i<10; i++) { - assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); - } - - dataBuf.ID = BPS_TRIP; - assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); - dataBuf.ID = STATE_OF_CHARGE; - assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); - dataBuf.ID = SUPPLEMENTAL_VOLTAGE; - assert(CANbus_Send(dataBuf, true, CARCAN) == SUCCESS); - - // Make sure that only three messages make it through - assert(CANbus_Read(&resultBuf, true, CARCAN) == SUCCESS); - assert(resultBuf.ID == BPS_TRIP); - assert(CANbus_Read(&resultBuf, true, CARCAN) == SUCCESS); - assert(resultBuf.ID == STATE_OF_CHARGE); - assert(CANbus_Read(&resultBuf, true, CARCAN) == SUCCESS); - assert(resultBuf.ID == SUPPLEMENTAL_VOLTAGE); - assert(CANbus_Read(&resultBuf, false, CARCAN) == ERROR); // No more messages - - printf("Success!\r\n"); - for (;;); -} - -int main(void){ //initialize things and spawn task - OS_ERR err; - OSInit(&err); - if(err != OS_ERR_NONE){ - printf("OS error code %d\n\r",err); - } - - BSP_UART_Init(UART_2); - - OSTaskCreate( - (OS_TCB*)&Task1_TCB, - (CPU_CHAR*)"Task1", - (OS_TASK_PTR)Task1, - (void*)NULL, - (OS_PRIO)4, - (CPU_STK*)Task1_Stk, - (CPU_STK_SIZE)STACK_SIZE/10, - (CPU_STK_SIZE)STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)NULL, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_STK_CHK), - (OS_ERR*)&err - ); - - - if (err != OS_ERR_NONE) { - printf("Task1 error code %d\n\r", err); - } - OSStart(&err); - if (err != OS_ERR_NONE) { - printf("OS error code %d\n\r", err); - } - return 0; - -} - -static void assert(bool cond) { - if (!cond) __asm("bkpt"); -} \ No newline at end of file From f62fa7b5f7c58cddc38d7ef3d325aa6cab585832 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 8 Jul 2023 21:08:46 +0000 Subject: [PATCH 099/141] Update faultstate testfile to work with new faultstate. --- Tests/Test_FaultThread_Exceptions.c | 152 ++++++++++------------------ 1 file changed, 53 insertions(+), 99 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index c6ffa58f8..a6d25ee26 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -24,7 +24,6 @@ */ #include "BSP_UART.h" -#include "FaultState.h" #include "Tasks.h" #include "CANbus.h" #include "ReadTritium.h" @@ -37,7 +36,7 @@ enum { // Test menu enum TEST_GENERAL, TEST_OS_ASSERT, TEST_READTRITIUM_HALL, - TEST_READTRITIUM_NONHALL, // Maybe break this into others? + TEST_READTRITIUM_NONHALL, TEST_READCARCAN, TEST_UPDATEDISPLAY }; @@ -45,7 +44,7 @@ enum { // Test menu enum /*** Constants ***/ #define TEST_OPTION TEST_UPDATEDISPLAY // Decide what to test based on test menu enum #define READTRITIUM_OPTION 3 // The enum value for the tritium error we want to test (reference error enum) -// Choose from 0 - 11 +// Choose from 0 - 11 if running TEST_READTRITIUM_NONHALL /*** Task components ***/ @@ -84,42 +83,58 @@ void exceptionCallback(void) { printf("\n\rException callback successfully executed."); } - -// Creates an exception of priority 1 and 2 to test -// test_callbacks: the callback function to use for the exceptions -void ExceptionTask(void* test_callbacks) { +/** + * @brief Creates and throws recoverable and nonrecoverable errors + * with or without callback handlers to test the general assertion mechanism + * @param test_callbacks the callback function to run during error handling +*/ +void ExceptionTask(callback_t test_callbacks) { + OS_ERR err; if (test_callbacks == NULL) { printf("\n\n\rTesting exceptions without callback functions"); } else { printf("\n\n\rTesting exceptions with callback functions"); } - // Throw a - printf("\n\n\rThrowing priority level 2 exception"); - exception_t prio2Exception = {.prio = PRI_RECOV, .message = "\n\rprio2 exception message", .callback = test_callbacks}; - assertExceptionError(prio2Exception); - // Throw a priority 1 exception - printf("\n\n\rThrowing priority level 1 exception"); - exception_t prio1Exception = {.prio = PRI_NONRECOV, .message = "\n\rprio1 exception message", .callback = test_callbacks}; - assertExceptionError(prio1Exception); - printf("\n\rTest failed: Prio 1 exception did not immediately result in an unrecoverable fault"); - - while(1){}; + // Throw two recoverable errors + printf("\n\n\rAsserting recoverable errors"); + // Throw an arbitrary recoverable error w/o locking the scheduler + assertTaskError(OS_MAIN_LOC, 0x01, test_callbacks, OPT_NO_LOCK_SCHED, OPT_RECOV); + // Throw an arbitrary recoverable error w/ locked scheduler + assertTaskError(OS_TASKS_LOC, 0x02, test_callbacks, OPT_LOCK_SCHED, OPT_RECOV); + + // Throw a nonrecoverable error + printf("\n\n\rAsserting a nonrecoverable error"); + assertTaskError(OS_SEND_CAN_LOC, 0x03, test_callbacks, OPT_LOCK_SCHED, OPT_NONRECOV); + printf("\n\rTest failed: locked nonrecoverable error did not immediately result in an unrecoverable fault"); + + OSTaskDel(NULL, &err); // Self-delete task once finished + checkOSError(err); } // Test the assertOSError function by pending on a mutex that wasn't created void OSErrorTask(void* arg) { + OS_ERR err; OS_ERR test_err; OS_MUTEX testMut; CPU_TS ts; + printf("\n\rasserting an OS error"); OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &test_err); assertOSError(OS_MAIN_LOC, test_err); printf("\n\rassertOSError test failed: assertion did not immediately result in an unrecoverable fault"); - while(1){}; + + OSTaskDel(NULL, &err); // Self-delete task once finished + checkOSError(err); } +// Helper function to see the state of the contactors +static void print_Contactors() { + printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR)); + printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); + printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); +} @@ -131,7 +146,6 @@ void Task_ManagerTask(void* arg) { CANbus_Init(MOTORCAN, NULL, 0); CANbus_Init(CARCAN, NULL, 0); Contactors_Init(); - //ErrorStatus errorCode; CANDATA_t canError; uint16_t tritiumError; @@ -139,37 +153,22 @@ void Task_ManagerTask(void* arg) { while (1) { switch (TEST_OPTION) { case TEST_GENERAL: - // Test the exceptions mechanism by creating and throwing exceptions of priorities 1 and 2 + // Test the exceptions mechanism by creating and asserting recoverable and nonrecoverable errors // Both with and without callback functions // Successful if exception message and callback message (if applicable) are printed // and the fail message is not printed (tasks are stopped when they assert an error) - printf("\n\n\r=========== Testing exception priorities 1 and 2 ==========="); + printf("\n\n\r=========== Testing general task error assertion ==========="); // Test level 1 & 2 exceptions without callbacks - createExceptionTask(NULL); - printf("\n\rAt line %d", __LINE__); + createExceptionTask(NULL); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // extra time for the task finished - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - OSTaskDel(&ExceptionTaskTCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); + checkOSError(err); // Test level 1 & 2 exceptions with callbacks createExceptionTask(exceptionCallback); checkOSError(err); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - OSTaskDel(&ExceptionTaskTCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); + checkOSError(err); break; @@ -182,15 +181,8 @@ void Task_ManagerTask(void* arg) { printf("\n\n\r=========== Testing OS assert ==========="); createOSErrorTask(); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); - printf("\n\rAt line %d", __LINE__); - OSTaskDel(&OSErrorTaskTCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - OSTaskDel(&FaultState_TCB, &err); break; @@ -252,13 +244,6 @@ void Task_ManagerTask(void* arg) { case TEST_READCARCAN: // Tests exceptions in ReadCarCAN by creating the tasks and sending messages - // Causes a weird issue where the last things that were printed are - // reprinted sixteen times all at once with some odd changes - // if the messages are sent enough times - // ex: 3 enable, 3 disable, 2 delay, 5 enable works - // but 5 enable ... doesn't - // I think the issue may occur if you let the test loop around - // enough, though. printf("\n\n\r=========== Testing ReadCarCAN ==========="); createReadCarCAN(); checkOSError(err); @@ -283,17 +268,17 @@ void Task_ManagerTask(void* arg) { // Send charge enable messages chargeMsg.data[0] = true; - for(int i = 0; i<3; i++){ + for(int i = 0; i<5; i++){ CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); printf("\n\rSent enable chargeMsg %d", i); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); printf("\n\rChargeEnable: %d", ChargeEnable_Get()); } - // Send five charge disable messages to test prio-2 disable contactor callback + // Send charge disable messages to test prio-2 disable contactor callback // Fault state should turn off contactors but not enter a nonrecoverable fault chargeMsg.data[0] = false; - for(int i = 0; i<3; i++){ + for(int i = 0; i<5; i++){ CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); printf("\n\rSent disable chargeMsg %d", i); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); @@ -301,7 +286,6 @@ void Task_ManagerTask(void* arg) { } // Pause the delivery of messages to trigger the canWatchTimer - //TODO: Can't tell that anything is happening here at the moment for(int i = 0; i<5; i++){ printf("\n\rDelay %d", i); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); @@ -316,40 +300,34 @@ void Task_ManagerTask(void* arg) { OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); printf("\n\rChargeEnable: %d", ChargeEnable_Get()); } - //TODO: Would these ever be on? Since there's no minion board we may not be able to check - printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors - printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); - printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + + // Check the contactors + print_Contactors(); + + Contactors_Set(ARRAY_CONTACTOR, ON, true); + Contactors_Set(MOTOR_CONTACTOR, ON, true); + Contactors_Set(ARRAY_PRECHARGE, ON, true); // Although BPS has control of the precharge contactor + + print_Contactors(); // See the state of the contactors before we send the trip message // Send a trip message of 1 (trip) - // TODO: trip messages are not usually sent, - // so any trip message (even 0) should be a concern. - // Need to change things to handle them differently (might be in ignition fix PR already) *(uint64_t*)(&tripBPSMsg.data) = 1; CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); printf("\n\rSent trip message %d", tripBPSMsg.data[0]); OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); - // By now, the BPS Trip message should have been sent - //OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Give ReadCarCAN time to turn off contactors - printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR));// Check the contactors - printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); - printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + // By now, the BPS Trip message should have been sent and the contactors should be off + print_Contactors(); OSTaskDel(&ReadCarCAN_TCB, &err); checkOSError(err); printf("\n\rAt line %d", __LINE__); - OSTaskDel(&FaultState_TCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); break; case TEST_UPDATEDISPLAY: printf("\n\n\r=========== Test UpdateDisplay ==========="); - // Might be able to test if we UpdateDisplay_Init() and then make the task - // UpdateDisplay and Display error functions do actually do the same thing, so one of them should be deleted. // Call update display put next to overflow the queue (actual issue) @@ -378,30 +356,6 @@ void Task_ManagerTask(void* arg) { // Task creation functions -// Initializes FaultState -void createFaultState(void) { - OS_ERR err; - - OSTaskCreate( // Create fault task - (OS_TCB*)&FaultState_TCB, - (CPU_CHAR*)"Fault State", - (OS_TASK_PTR)&Task_FaultState, - (void*)NULL, - (OS_PRIO)2, - (CPU_STK*)FaultState_Stk, - (CPU_STK_SIZE)128/10, - (CPU_STK_SIZE)128, - (OS_MSG_QTY)0, - (OS_TICK)NULL, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - -} - // Initializes ReadTritium void createReadTritium(void) { OS_ERR err; From 9f60cf0cb8bfd45615ea589c5a552aadcde71c3d Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 11 Jul 2023 02:31:30 +0000 Subject: [PATCH 100/141] Bringing improvements to the fault thread test from fix_ignition_delay so that it has the most recent changes, including those to test ReadCarCAN. --- Tests/Test_FaultThread_Exceptions.c | 392 +++++++++++++--------------- 1 file changed, 184 insertions(+), 208 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index a6d25ee26..a37419d2b 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -8,6 +8,8 @@ * Choose the task to test using TEST_OPTION. * If testing ReadTritium non-Hall, choose the tritium error using READTRITIUM_OPTION. * Once the task enters an infinite loop, it won't ever exit and you'll need to restart the test. + * Additionally, you'll need to use GDB to inspect the state of the system after a fault + * since nothing else will be run or printed. * * This test is run in LoopBack mode with all messages sent and received by the LeaderBoard. * However, it can be run in conjunction with motor-sim and car-sim @@ -17,7 +19,7 @@ * @author Madeleine Lee (madeleinercflee@utexas.edu) * @brief Tests the fault state exception mechanism * @version - * @date 2023-6-08 + * @date 2023-7-10 * * @copyright Copyright (c) 2022 Longhorn Racing Solar * @@ -35,16 +37,14 @@ enum { // Test menu enum TEST_GENERAL, TEST_OS_ASSERT, - TEST_READTRITIUM_HALL, - TEST_READTRITIUM_NONHALL, + TEST_READTRITIUM, TEST_READCARCAN, TEST_UPDATEDISPLAY }; /*** Constants ***/ -#define TEST_OPTION TEST_UPDATEDISPLAY // Decide what to test based on test menu enum -#define READTRITIUM_OPTION 3 // The enum value for the tritium error we want to test (reference error enum) -// Choose from 0 - 11 if running TEST_READTRITIUM_NONHALL +#define TEST_OPTION TEST_READCARCAN // Decide what to test based on test menu enum +#define READTRITIUM_OPTION T_MOTOR_OVER_SPEED_ERR // The enum for the tritium error we want to test (reference error enum) /*** Task components ***/ @@ -67,6 +67,7 @@ void createOSErrorTask(void); void createReadCarCAN(void); void createReadTritium(void); void createUpdateDisplay(void); +void endTestReadCarCAN(void); // Assertion function for OS errors void checkOSError(OS_ERR err) { @@ -107,9 +108,9 @@ void ExceptionTask(callback_t test_callbacks) { // Throw a nonrecoverable error printf("\n\n\rAsserting a nonrecoverable error"); assertTaskError(OS_SEND_CAN_LOC, 0x03, test_callbacks, OPT_LOCK_SCHED, OPT_NONRECOV); - printf("\n\rTest failed: locked nonrecoverable error did not immediately result in an unrecoverable fault"); + printf("\n\rTest failed: locked nonrecoverable error did not immediately result in an unrecoverable fault"); // Shouldn't print - OSTaskDel(NULL, &err); // Self-delete task once finished + OSTaskDel(NULL, &err); // Self-delete task once finished, though we shouldn't get this far checkOSError(err); } @@ -137,7 +138,6 @@ static void print_Contactors() { } - // A high-priority task that manages other tasks and runs the tests void Task_ManagerTask(void* arg) { OS_ERR err; @@ -147,209 +147,176 @@ void Task_ManagerTask(void* arg) { CANbus_Init(CARCAN, NULL, 0); Contactors_Init(); CANDATA_t canError; - uint16_t tritiumError; + + switch (TEST_OPTION) { + case TEST_GENERAL: + // Test the exceptions mechanism by creating and asserting recoverable and nonrecoverable errors + // Successful if exception message and callback message are printed + // and the fail message is not printed (tasks are stopped when they assert an error) + printf("\n\n\r=========== Testing general task error assertion ==========="); + + // Test level 1 & 2 exceptions with callbacks + createExceptionTask(exceptionCallback); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + break; + + case TEST_OS_ASSERT: + // Test the assertOSError function using the OSErrorTask + // Creates an OS error by pending on a mutex that isn't created + // Successful if it prints the OS Error code 24004 + // and doesn't print the fail message (task is stopped by asserting an error) + printf("\n\n\r=========== Testing OS assert ==========="); + + createOSErrorTask(); + OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + break; + + case TEST_READTRITIUM: + // Test exceptions in ReadTritium by sending the fault chosen in READTRITIUM_OPTION + // Successful we enter a nonrecoverable fault and the fail message is not printed + // Also if the motor is reset three times before the fault for a hall error + printf("\n\n\r=========== Testing ReadTritium ==========="); + + uint16_t tritiumError = READTRITIUM_OPTION; + *((uint16_t*)(&canError.data[4])) = tritiumError; + canError.ID = MOTOR_STATUS; + + createReadTritium(); + printf("\n\n\rNow sending: %d", tritiumError); // Sending 0 means no Tritium error + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish + printf("\n\rTesting Tritium error %d", READTRITIUM_OPTION); + if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart + for (int i = 0; i < 3; i++) { // Faults if greater than restart threshold (3) + CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + } + } - while (1) { - switch (TEST_OPTION) { - case TEST_GENERAL: - // Test the exceptions mechanism by creating and asserting recoverable and nonrecoverable errors - // Both with and without callback functions - // Successful if exception message and callback message (if applicable) are printed - // and the fail message is not printed (tasks are stopped when they assert an error) - printf("\n\n\r=========== Testing general task error assertion ==========="); - - // Test level 1 & 2 exceptions without callbacks - createExceptionTask(NULL); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // extra time for the task finished - checkOSError(err); - - // Test level 1 & 2 exceptions with callbacks - createExceptionTask(exceptionCallback); - checkOSError(err); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); + // Fail message: this should not be reached because we should hit an unrecoverable fault first + printf("\n\rTest failed: error assertion did not lead to an unrecoverable fault"); + OSTaskDel(&ReadTritium_TCB, &err); + checkOSError(err); + + break; - break; - case TEST_OS_ASSERT: // Decide what to do with this + case TEST_READCARCAN: - // Test the assertOSError function using the OSErrorTask - // Creates an OS error by pending on a mutex that isn't created - // Successful if it prints the OS Error code - // and doesn't print the fail message (task is stopped by asserting an error) - printf("\n\n\r=========== Testing OS assert ==========="); + // Tests exceptions in ReadCarCAN by creating the tasks and sending messages + // Successful if charging disable and missed messages turns off contactors + // And we enter a nonrecoverable fault immediately after receiving the trip message + printf("\n\n\r=========== Testing ReadCarCAN ==========="); - createOSErrorTask(); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + createReadCarCAN(); + + // Message for charging enable/disable + CANDATA_t chargeMsg; + chargeMsg.ID = CHARGE_ENABLE; + *(uint64_t*)(&chargeMsg.data) = 0; + chargeMsg.idx = 0; + printf("\n\rMade charging message"); + + // Message for BPS Fault + CANDATA_t tripBPSMsg; + tripBPSMsg.ID = BPS_TRIP; + *(uint64_t*)(&tripBPSMsg.data) = 0; + tripBPSMsg.idx = 0; + printf("\n\rMade BPS trip message"); + + // Send charge enable messages + chargeMsg.data[0] = true; + for(int i = 0; i<7; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\n\rSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); - - break; - - - case TEST_READTRITIUM_HALL: // 8, or 0x1000, for tritium hall error // Also seems to work - - canError.ID = MOTOR_STATUS; - tritiumError = T_HALL_SENSOR_ERR; // Leftshifted i-1 times, allows for an error of 0x00 - *((uint16_t*)(&canError.data[4])) = tritiumError; - - createReadTritium(); - // Send the message extra times to allow for motor restart - for (int i = 0; i < 4; i++) { // Faults if greater than restart threshold (3). Maybe we should change it to equal to threshold? - printf("\n\n\rNow sending: error %d", tritiumError); // Sending the hall sensor error message - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - printf("\n\rShould be testing Tritium hall error %d", (i + 1)); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish - } - - // This code should not be reached because the error assertion should cause a nonrecoverable fault. - printf("\n\rTest failed: error assertion did not lead to an unrecoverable fault"); - OSTaskDel(&ReadTritium_TCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - - - - break; - - case TEST_READTRITIUM_NONHALL: // Seems to work - // Test exceptions in ReadTritium by creating the tasks and sending faults - // TODO: Change ReadTrititum so that we can print out the error code and not just a default message - printf("\n\n\r=========== Testing ReadTritium ==========="); - - uint16_t tritiumError = (0x01<>1; // Change to i-1? - *((uint16_t*)(&canError.data[4])) = tritiumError; - canError.ID = MOTOR_STATUS; - - createReadTritium(); - printf("\n\n\rNow sending: %d", tritiumError); // Sending 0 means no Tritium error - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish - printf("\n\rShould be testing Tritium error %d", READTRITIUM_OPTION); - if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart - for (int i = 0; i < 4; i++) { // Faults if greater than restart threshold (3). Maybe we should change it to equal to threshold? - CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - } - } - - OSTaskDel(&ReadTritium_TCB, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - - - break; - - - case TEST_READCARCAN: - - // Tests exceptions in ReadCarCAN by creating the tasks and sending messages - printf("\n\n\r=========== Testing ReadCarCAN ==========="); - createReadCarCAN(); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + + print_Contactors(); + + // Send charge disable messages to test disable contactor callback + // Fault state should turn off the array contactor but not enter a nonrecoverable fault + chargeMsg.data[0] = false; + for(int i = 0; i<5; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\n\rSent disable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); - printf("\n\rCreated readCarCAN"); - - // Message for charging enable/disable - CANDATA_t chargeMsg; - chargeMsg.ID = CHARGE_ENABLE; - *(uint64_t*)(&chargeMsg.data) = 0; - chargeMsg.idx = 0; - printf("\n\rMade charging message"); - - // Message for BPS Fault - CANDATA_t tripBPSMsg; - tripBPSMsg.ID = BPS_TRIP; - *(uint64_t*)(&tripBPSMsg.data) = 0; - tripBPSMsg.idx = 0; - printf("\n\rMade BPS trip message"); - - - - - // Send charge enable messages - chargeMsg.data[0] = true; - for(int i = 0; i<5; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\n\rSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - - // Send charge disable messages to test prio-2 disable contactor callback - // Fault state should turn off contactors but not enter a nonrecoverable fault - chargeMsg.data[0] = false; - for(int i = 0; i<5; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\n\rSent disable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - - // Pause the delivery of messages to trigger the canWatchTimer - for(int i = 0; i<5; i++){ - printf("\n\rDelay %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - - // Send five more charge enable messages so the contactors get flipped on again - chargeMsg.data[0] = true; - for(int i = 0; i < 5; i++){ - CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); - printf("\n\rSent enable chargeMsg %d", i); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); - printf("\n\rChargeEnable: %d", ChargeEnable_Get()); - } - - // Check the contactors - print_Contactors(); - - Contactors_Set(ARRAY_CONTACTOR, ON, true); - Contactors_Set(MOTOR_CONTACTOR, ON, true); - Contactors_Set(ARRAY_PRECHARGE, ON, true); // Although BPS has control of the precharge contactor - - print_Contactors(); // See the state of the contactors before we send the trip message - - // Send a trip message of 1 (trip) - *(uint64_t*)(&tripBPSMsg.data) = 1; - CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); - printf("\n\rSent trip message %d", tripBPSMsg.data[0]); - OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); - - - // By now, the BPS Trip message should have been sent and the contactors should be off - print_Contactors(); - - OSTaskDel(&ReadCarCAN_TCB, &err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + } + + print_Contactors(); + + // Send more charge enable messages so the contactor gets flipped on again + chargeMsg.data[0] = true; + for(int i = 0; i < 7; i++){ + CANbus_Send(chargeMsg, CAN_BLOCKING,CARCAN); + printf("\n\rSent enable chargeMsg %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); - printf("\n\rAt line %d", __LINE__); - break; + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + } + + print_Contactors(); + // Pause the delivery of messages to trigger the canWatchTimer + for(int i = 0; i<5; i++){ + printf("\n\rDelay %d", i); + OSTimeDlyHMSM(0, 0, 0, 400, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + printf("\n\rChargeEnable: %d", ChargeEnable_Get()); + printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + } - case TEST_UPDATEDISPLAY: - printf("\n\n\r=========== Test UpdateDisplay ==========="); - // Call update display put next to overflow the queue (actual issue) + + // Check the contactors + print_Contactors(); - - Display_Init(); - UpdateDisplay_Init(); - createUpdateDisplay(); - - for (int i = 0; i < 10; i++) { - UpdateDisplay_SetCruiseState(1 + i); - } - OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); - OSTaskDel(&UpdateDisplay_TCB, &err); - checkOSError(err); - break; - } - + // Turn on contactors so we can see if they get turned off by the error assertion + Contactors_Set(ARRAY_CONTACTOR, ON, true); + Contactors_Set(MOTOR_CONTACTOR, ON, true); + Contactors_Set(ARRAY_PRECHARGE, ON, true); // Although BPS has control of the precharge contactor + print_Contactors(); // See the state of the contactors before we send the trip message + + // Send a trip message of 1 (trip) + *(uint64_t*)(&tripBPSMsg.data) = 1; + CANbus_Send(tripBPSMsg, CAN_BLOCKING, CARCAN); + printf("\n\rSent trip message %d", tripBPSMsg.data[0]); + OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err); + + // Code below here shouldn't be run unless the error assertion fails + + // By now, the BPS Trip message should have been sent and the contactors should be off + print_Contactors(); + endTestReadCarCAN(); // Delete ReadCarCAN and UpdateDisplay tasks + break; + + + case TEST_UPDATEDISPLAY: + // Call update display put next to overflow the queue (actual issue) + printf("\n\n\r=========== Test UpdateDisplay ==========="); + + createUpdateDisplay(); + + for (int i = 0; i < 10; i++) { + UpdateDisplay_SetCruiseState(1 + i); + } + OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); + checkOSError(err); + OSTaskDel(&UpdateDisplay_TCB, &err); + checkOSError(err); + break; } + while(1){;} } @@ -376,7 +343,7 @@ void createReadTritium(void) { (OS_ERR*)&err ); checkOSError(err); - printf("\n\rin createReadTritium at line %d", __LINE__); + printf("\n\rCreated ReadTritium"); } // Initializes ReadCarCAN @@ -399,8 +366,18 @@ void createReadCarCAN(void) { (OS_ERR*)&err ); checkOSError(err); - printf("\n\rIn createReadCarCAN at line %d", __LINE__); + printf("\n\rCreated readCarCAN"); + createUpdateDisplay(); + +} +// Deletes tasks used in ReadCarCAN test +void endTestReadCarCAN(void) { + OS_ERR err; + OSTaskDel(&ReadCarCAN_TCB, &err); + checkOSError(err); + OSTaskDel(&UpdateDisplay_TCB, &err); + checkOSError(err); } // Initializes UpdateDisplay @@ -423,7 +400,9 @@ void createUpdateDisplay(void) { (OS_ERR *)&err ); checkOSError(err); - printf("\n\rAt line %d", __LINE__); + Display_Init(); + UpdateDisplay_Init(); + printf("\n\rCreated and initialized Display and UpdateDisplay"); } @@ -447,8 +426,8 @@ void createExceptionTask(void * callback_function) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR *)&err ); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); + checkOSError(err); + printf("\n\rCreated ExceptionTask"); } @@ -471,8 +450,8 @@ void createOSErrorTask(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR *)&err ); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); + checkOSError(err); + printf("\n\rCreated OSErrorTask"); } @@ -483,8 +462,7 @@ int main(void) { OSInit(&err); - checkOSError(err); - printf("\n\rIn main at line %d", __LINE__); + checkOSError(err); // Create the task manager thread @@ -503,12 +481,10 @@ int main(void) { (OS_OPT)(OS_OPT_TASK_STK_CLR), (OS_ERR*)&err ); - checkOSError(err); - printf("\n\rAt line %d", __LINE__); + checkOSError(err); OSStart(&err); checkOSError(err); - printf("\n\rIn main after OS start at line %d", __LINE__); while(1) {} } From 0c833b8b402c756e1ffb43cf5ade17ab3ea0b199 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 11 Jul 2023 02:33:52 +0000 Subject: [PATCH 101/141] Small changes made while updating error handling for ReadCarCAN on fix_ignition_delay. --- Apps/Inc/Tasks.h | 6 +++--- Apps/Src/ReadTritium.c | 2 +- Apps/Src/Tasks.c | 14 +++++++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 060924b35..e170f25f8 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -159,14 +159,14 @@ typedef enum { } error_recov_opt_t; /** - * @brief For use in error handling: turns off array and motor contactor + * @brief For use in error handling: turns off array, array precharge, and motor contactor * and turns on additional brakelight to signal that a critical error happened. */ void arrayMotorKill(); /** - * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, - * and jumping to the error's specified callback function. + * @brief Assert a task error by setting the location variable and optionally locking the scheduler, + * displaying a fault screen (if nonrecoverable), jumping to a callback function, and entering an infinite loop. * Called by task-specific error-assertion functions that are also responsible for setting the error variable. * @param errorLoc the task from which the error originated. Note: should be taken out when last task pointer is integrated * @param faultCode the enum for the specific error that happened diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index d0dddd7c8..b9f094f75 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -132,7 +132,7 @@ float Motor_Velocity_Get(){ //getter function for motor velocity * @brief A callback function to be run by the main assertTaskError function for hall sensor errors * restart the motor if the number of hall errors is still less than the RESTART_THRESHOLD. */ -static void handler_Tritium_HallError() { +static void handler_Tritium_HallError(void) { MotorController_Restart(); } diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 4a8e99951..adb6ea239 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -39,9 +39,12 @@ CPU_STK Telemetry_Stk[TASK_TELEMETRY_STACK_SIZE]; * Global Variables */ os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; // Store the location of the current error -error_code_t Error_ReadTritium = T_NONE; // Variables to store error codes, stored and cleared in task error assert functions -//error_code_t Error_ReadCarCAN = RCC_ERR_NONE; + +// Variables to store error codes, stored and cleared in task error assert functions +error_code_t Error_ReadTritium = T_NONE; // Initialized to no error +error_code_t Error_ReadCarCAN = READCARCAN_ERR_NONE; error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; + extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. @@ -102,7 +105,11 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t erro if (lockSched == OPT_LOCK_SCHED) { // Only happens on recoverable errors OSSchedUnlock(&err); - assertOSError(OS_TASKS_LOC, err); + // Don't err out if scheduler is still locked because of a timer callback + if (err != OS_ERR_SCHED_LOCKED && OSSchedLockNestingCtr > 1) { // But we don't plan to lock more than one level deep + assertOSError(OS_TASKS_LOC, err); + } + } OSErrLocBitmap = OS_NONE_LOC; // Clear the location error variable once handled @@ -116,6 +123,7 @@ void arrayMotorKill() { // Array motor kill BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); + BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_PRECHARGE_PIN, OFF); // Turn additional brakelight on to indicate critical error BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); From 8880dc577a26e245cfb5ead50d99091ae162fa34 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 13 Jul 2023 06:02:57 +0000 Subject: [PATCH 102/141] Renamed the scheduler lock option, changed error_code_t to a typedef. --- Apps/Inc/Tasks.h | 6 +++--- Apps/Src/Tasks.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index e170f25f8..8f7d173eb 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -43,7 +43,7 @@ /** * Task error variable type */ -#define error_code_t uint8_t +typedef uint16_t error_code_t; /** * Task Prototypes @@ -150,7 +150,7 @@ extern error_code_t Error_UpdateDisplay; typedef enum { OPT_LOCK_SCHED = false, OPT_NO_LOCK_SCHED = true -} error_lock_sched_opt_t; +} error_scheduler_lock_opt_t; // Recoverable/nonrecoverable parameter option for asserting a task error typedef enum { @@ -174,7 +174,7 @@ void arrayMotorKill(); * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ -void assertTaskError(os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback, error_lock_sched_opt_t lockSched, error_recov_opt_t nonrecoverable); +void assertTaskError(os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); /** * @brief Assert Error if OS function call fails diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index adb6ea239..be90359f8 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -76,7 +76,7 @@ void _assertOSError(uint16_t OS_err_loc, OS_ERR err) * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ -void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t errorCallback, error_lock_sched_opt_t lockSched, error_recov_opt_t nonrecoverable) { +void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { OS_ERR err; if (lockSched == OPT_LOCK_SCHED) { // We want this error to be handled immediately without other tasks being able to interrupt From bffcbb50b3b841bdb1524d5ae2708bc5b0761140 Mon Sep 17 00:00:00 2001 From: Madeleine Lee <74027612+KnockbackNemo@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:25:04 -0500 Subject: [PATCH 103/141] Update Apps/Src/ReadTritium.c Accepted suggestion to restructure assertTritiumError for less-nested if-elses Co-authored-by: Sidharth N. Babu --- Apps/Src/ReadTritium.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index b9f094f75..09374e339 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -148,25 +148,25 @@ static void assertTritiumError(tritium_error_code_t motor_err){ static uint8_t hall_fault_cnt = 0; //trip counter, doesn't ever reset Error_ReadTritium = motor_err; // Store error code for inspection info - - if(motor_err != T_NONE){ // We need to handle an error - if(motor_err != T_HALL_SENSOR_ERR){ - // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); - - }else{ - hall_fault_cnt++; - - //try to restart the motor a few times and then fail out - if(hall_fault_cnt > RESTART_THRESHOLD){ - // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); - } else { // Try restarting the motor - // Assert a recoverable error that will run the motor restart callback function - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, handler_Tritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); - } - } + if(motor_err == T_NONE) return; // No error, return + + if(motor_err != T_HALL_SENSOR_ERR){ + // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + return; } + hall_fault_cnt++; + + //try to restart the motor a few times and then fail out + if(hall_fault_cnt > RESTART_THRESHOLD){ + // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + return; + } + // Try restarting the motor + // Assert a recoverable error that will run the motor restart callback function + assertTaskError(OS_READ_TRITIUM_LOC, motor_err, handler_Tritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); + Error_ReadTritium = T_NONE; // Clear the error after handling it } \ No newline at end of file From 3574cd4376f734a1900a13dca2641ee75bc0a9d9 Mon Sep 17 00:00:00 2001 From: Madeleine Lee <74027612+KnockbackNemo@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:30:31 -0500 Subject: [PATCH 104/141] Update Apps/Src/ReadTritium.c Accepted suggestion to change the small function handler_Tritium_HallError to an inline function Co-authored-by: Sidharth N. Babu --- Apps/Src/ReadTritium.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 09374e339..23ca66e4d 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -132,7 +132,7 @@ float Motor_Velocity_Get(){ //getter function for motor velocity * @brief A callback function to be run by the main assertTaskError function for hall sensor errors * restart the motor if the number of hall errors is still less than the RESTART_THRESHOLD. */ -static void handler_Tritium_HallError(void) { +static inline void handler_Tritium_HallError(void) { MotorController_Restart(); } From 5dbc972f35451b3725fd77a06d9d32f3ad11f4b8 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 13 Jul 2023 18:39:15 +0000 Subject: [PATCH 105/141] Changed _assertOSError to use the os_error_loc_t, attempted to realign the updatedisplay enum. --- Apps/Inc/Tasks.h | 2 +- Apps/Inc/UpdateDisplay.h | 2 +- Apps/Src/Tasks.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 8f7d173eb..189313ef0 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -181,7 +181,7 @@ void assertTaskError(os_error_loc_t errorLoc, uint8_t faultCode, callback_t erro * @param OS_err_loc Where OS error occured (driver level) * @param err OS Error that occurred */ -void _assertOSError(uint16_t OS_err_loc, OS_ERR err); +void _assertOSError(os_error_loc_t OS_err_loc, OS_ERR err); #if DEBUG == 1 #define assertOSError(OS_err_loc,err) \ diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index dba6cf42d..c8d91641c 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -30,7 +30,7 @@ typedef enum{ UPDATEDISPLAY_ERR_FIFO_PUT =-1, // Error putting command in fifo UPDATEDISPLAY_ERR_FIFO_POP =-2, // Error popping command from fifo UPDATEDISPLAY_ERR_PARSE_COMP =-3, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value + UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value UPDATEDISPLAY_ERR_DRIVER =-5 // Driver call returned an error } UpdateDisplayError_t; diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index be90359f8..5d585d328 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -52,7 +52,7 @@ extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions * Error assertion-related functions */ -void _assertOSError(uint16_t OS_err_loc, OS_ERR err) +void _assertOSError(os_error_loc_t OS_err_loc, OS_ERR err) { if (err != OS_ERR_NONE) { From 17900d4a7117269862ea82b4139c9ea7fad60b6f Mon Sep 17 00:00:00 2001 From: Madeleine Lee <74027612+KnockbackNemo@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:54:28 -0500 Subject: [PATCH 106/141] Update Apps/Src/ReadTritium.c Co-authored-by: Sidharth N. Babu --- Apps/Src/ReadTritium.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 23ca66e4d..0a6f96acf 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -156,10 +156,8 @@ static void assertTritiumError(tritium_error_code_t motor_err){ return; } - hall_fault_cnt++; - //try to restart the motor a few times and then fail out - if(hall_fault_cnt > RESTART_THRESHOLD){ + if(++hall_fault_cnt > RESTART_THRESHOLD){ // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; From 2ca1f4ecc7f53f595055be2a1b064fc8eaeadcf5 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 13 Jul 2023 19:00:22 +0000 Subject: [PATCH 107/141] Reattempting to align the UpdateDisplay.h error enum. --- Apps/Inc/UpdateDisplay.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index c8d91641c..7ade46a85 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -26,12 +26,12 @@ * Error types */ typedef enum{ - UPDATEDISPLAY_ERR_NONE = 0, - UPDATEDISPLAY_ERR_FIFO_PUT =-1, // Error putting command in fifo - UPDATEDISPLAY_ERR_FIFO_POP =-2, // Error popping command from fifo - UPDATEDISPLAY_ERR_PARSE_COMP =-3, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value - UPDATEDISPLAY_ERR_DRIVER =-5 // Driver call returned an error + UPDATEDISPLAY_ERR_NONE = 0, + UPDATEDISPLAY_ERR_FIFO_PUT =-1, // Error putting command in fifo + UPDATEDISPLAY_ERR_FIFO_POP =-2, // Error popping command from fifo + UPDATEDISPLAY_ERR_PARSE_COMP =-3, // Error parsing component/val in SetComponent + UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value + UPDATEDISPLAY_ERR_DRIVER =-5 // Driver call returned an error } UpdateDisplayError_t; /** From 639e1e01863fe8f770cd7ea4a0ec77a21a55a07e Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 13 Jul 2023 19:16:59 +0000 Subject: [PATCH 108/141] Aligned(?) the comments from UpdateDisplay.h. I think it should all look nice now --- Apps/Inc/UpdateDisplay.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 7ade46a85..0876aa681 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -27,11 +27,11 @@ */ typedef enum{ UPDATEDISPLAY_ERR_NONE = 0, - UPDATEDISPLAY_ERR_FIFO_PUT =-1, // Error putting command in fifo - UPDATEDISPLAY_ERR_FIFO_POP =-2, // Error popping command from fifo - UPDATEDISPLAY_ERR_PARSE_COMP =-3, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value - UPDATEDISPLAY_ERR_DRIVER =-5 // Driver call returned an error + UPDATEDISPLAY_ERR_FIFO_PUT =-1, // Error putting command in fifo + UPDATEDISPLAY_ERR_FIFO_POP =-2, // Error popping command from fifo + UPDATEDISPLAY_ERR_PARSE_COMP =-3, // Error parsing component/val in SetComponent + UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value + UPDATEDISPLAY_ERR_DRIVER =-5 // Driver call returned an error } UpdateDisplayError_t; /** From 1b5a23e40321852cb04d60eb97f936c6483fa364 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Fri, 14 Jul 2023 22:37:19 +0000 Subject: [PATCH 109/141] Changed assertTaskError to take an error_code_t, and changed error_code_t to be an int16_t. --- Apps/Inc/Tasks.h | 6 +++--- Apps/Src/ReadTritium.c | 8 ++++---- Apps/Src/Tasks.c | 2 +- Apps/Src/UpdateDisplay.c | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 189313ef0..38d609991 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -43,7 +43,7 @@ /** * Task error variable type */ -typedef uint16_t error_code_t; +typedef int16_t error_code_t; /** * Task Prototypes @@ -169,12 +169,12 @@ void arrayMotorKill(); * displaying a fault screen (if nonrecoverable), jumping to a callback function, and entering an infinite loop. * Called by task-specific error-assertion functions that are also responsible for setting the error variable. * @param errorLoc the task from which the error originated. Note: should be taken out when last task pointer is integrated - * @param faultCode the enum for the specific error that happened + * @param errorCode the enum for the specific error that happened * @param errorCallback a callback function to a handler for that specific error, * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ -void assertTaskError(os_error_loc_t errorLoc, uint8_t faultCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); +void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); /** * @brief Assert Error if OS function call fails diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 0a6f96acf..424b23a8b 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -147,24 +147,24 @@ static inline void handler_Tritium_HallError(void) { static void assertTritiumError(tritium_error_code_t motor_err){ static uint8_t hall_fault_cnt = 0; //trip counter, doesn't ever reset - Error_ReadTritium = motor_err; // Store error code for inspection info + Error_ReadTritium = (error_code_t)motor_err; // Store error code for inspection info if(motor_err == T_NONE) return; // No error, return if(motor_err != T_HALL_SENSOR_ERR){ // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; } //try to restart the motor a few times and then fail out if(++hall_fault_cnt > RESTART_THRESHOLD){ // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; } // Try restarting the motor // Assert a recoverable error that will run the motor restart callback function - assertTaskError(OS_READ_TRITIUM_LOC, motor_err, handler_Tritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); + assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, handler_Tritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); Error_ReadTritium = T_NONE; // Clear the error after handling it } \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 5d585d328..ea1fdd543 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -76,7 +76,7 @@ void _assertOSError(os_error_loc_t OS_err_loc, OS_ERR err) * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ -void assertTaskError(os_error_loc_t errorLoc, uint8_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { +void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { OS_ERR err; if (lockSched == OPT_LOCK_SCHED) { // We want this error to be handled immediately without other tasks being able to interrupt diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 557c24e33..738e7896a 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -424,17 +424,17 @@ static void handler_UpdateDisplay_ShowError() { */static void assertUpdateDisplayError(DisplayError_t err){ static uint8_t disp_error_cnt = 0; // Track the number of display errors, doesn't ever reset - Error_UpdateDisplay = err; // Store the error code for inspection + Error_UpdateDisplay = (error_code_t)err; // Store the error code for inspection if (err != DISPLAY_ERR_NONE){ disp_error_cnt++; if (disp_error_cnt > RESTART_THRESHOLD){ // Show error screen if restart attempt limit has been reached - assertTaskError(OS_DISPLAY_LOC, err, handler_UpdateDisplay_ShowError, + assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_ShowError, OPT_NO_LOCK_SCHED, OPT_RECOV); } else { // Otherwise try resetting the display using the restart callback - assertTaskError(OS_DISPLAY_LOC, err, handler_UpdateDisplay_Restart, + assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_Restart, OPT_NO_LOCK_SCHED, OPT_RECOV); } From e93af92707b574a71caabff861d3b7bffa87d820 Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Wed, 19 Jul 2023 20:40:11 -0500 Subject: [PATCH 110/141] Modified ReadCarCAN so it compiles --- Apps/Src/ReadCarCAN.c | 17 ++++++----------- Apps/Src/Tasks.c | 3 +-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 875e7e51d..7b64cb120 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -3,7 +3,6 @@ #include "ReadCarCAN.h" #include "UpdateDisplay.h" #include "Contactors.h" -#include "FaultState.h" #include "Minions.h" #include "Minions.h" #include "os_cfg_app.h" @@ -86,9 +85,8 @@ static inline void chargingDisable(void) { // mark regen as disabled chargeEnable = false; - // kill contactors - exception_t readBPSError = {.prio=2, .message="read BPS error", .callback=callback_disableContactors}; - assertExceptionError(readBPSError); + // kill contactors TODO: fill in error code + assertTaskError(OS_READ_CAN_LOC, 0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); } // helper function to call if charging should be enabled @@ -206,15 +204,12 @@ void Task_ReadCarCAN(void *p_arg) switch(dataBuf.ID){ //we got a message case BPS_TRIP: { // BPS has a fault and we need to enter fault state (probably) - if(dataBuf.data[0] == 1){ // If buffer contains 1 for a BPS trip, we should enter a nonrecoverable fault - Display_Evac(SOC, SBPV); // Display evacuation message + Display_Evac(SOC, SBPV); // Display evacuation message - // Create an exception and assert the error - // kill contactors and enter a nonrecoverable fault - exception_t tripBPSError = {.prio=1, .message="BPS has been tripped", .callback=callback_disableContactors}; - assertExceptionError(tripBPSError); - } + // kill contactors and enter a nonrecoverable fault + // TODO: change error code to real value + assertTaskError(OS_READ_CAN_LOC, 0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); } case CHARGE_ENABLE: { diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index ea1fdd543..26c472b7c 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -42,12 +42,11 @@ os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; // Store the location of the curren // Variables to store error codes, stored and cleared in task error assert functions error_code_t Error_ReadTritium = T_NONE; // Initialized to no error -error_code_t Error_ReadCarCAN = READCARCAN_ERR_NONE; +error_code_t Error_ReadCarCAN = /*READCARCAN_ERR_NONE*/ 0; // TODO: change this back to the error error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. - /** * Error assertion-related functions */ From 5b55b392a87a15fe19e1c0a18d8fdfee222cdf9f Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 29 Jul 2023 08:32:02 +0000 Subject: [PATCH 111/141] Addressed PR review comments. Mostly small changes and one doc alteration. --- Apps/Inc/ReadTritium.h | 2 -- Apps/Src/ReadCarCAN.c | 1 - Apps/Src/ReadTritium.c | 12 +++++------ Apps/Src/Tasks.c | 7 ++----- Apps/Src/UpdateDisplay.c | 27 +++++++++++++------------ Docs/source/Drivers/MotorController.rst | 2 -- Drivers/Inc/Display.h | 3 +-- Drivers/Src/Display.c | 1 - 8 files changed, 23 insertions(+), 32 deletions(-) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index 7b3b44f93..5a3cb99ac 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -7,7 +7,6 @@ #include "common.h" #include "Tasks.h" #define MOTOR_STOPPED 0 -#define CAR_STOPPED 0 /** * Motor Error States @@ -36,6 +35,5 @@ tritium_error_code_t MotorController_getTritiumError(void); float Motor_RPM_Get(); float Motor_Velocity_Get(); -void MotorController_Restart(); #endif diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 7b64cb120..2f3050cef 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -4,7 +4,6 @@ #include "UpdateDisplay.h" #include "Contactors.h" #include "Minions.h" -#include "Minions.h" #include "os_cfg_app.h" #include "Display.h" diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 424b23a8b..e9691fd1b 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -14,7 +14,7 @@ tritium_error_code_t Motor_FaultBitmap = T_NONE; //initialized to no error, changed when the motor asserts an error static float Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read -static float Motor_Velocity = CAR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read +static float Motor_Velocity = MOTOR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read // Function prototypes static void assertTritiumError(tritium_error_code_t motor_err); @@ -107,7 +107,7 @@ void Task_ReadTritium(void *p_arg){ } } -void MotorController_Restart(void){ +static void restartMotorController(void){ CANDATA_t resetmsg = {0}; resetmsg.ID = MOTOR_RESET; CANbus_Send(resetmsg, true, MOTORCAN); @@ -132,8 +132,8 @@ float Motor_Velocity_Get(){ //getter function for motor velocity * @brief A callback function to be run by the main assertTaskError function for hall sensor errors * restart the motor if the number of hall errors is still less than the RESTART_THRESHOLD. */ -static inline void handler_Tritium_HallError(void) { - MotorController_Restart(); +static inline void handler_ReadTritium_HallError(void) { + restartMotorController(); } @@ -156,7 +156,7 @@ static void assertTritiumError(tritium_error_code_t motor_err){ return; } - //try to restart the motor a few times and then fail out + // If it's a hall sensor error, try to restart the motor a few times and then fail out if(++hall_fault_cnt > RESTART_THRESHOLD){ // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); @@ -164,7 +164,7 @@ static void assertTritiumError(tritium_error_code_t motor_err){ } // Try restarting the motor // Assert a recoverable error that will run the motor restart callback function - assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, handler_Tritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); + assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, handler_ReadTritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); Error_ReadTritium = T_NONE; // Clear the error after handling it } \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 173af1e5d..256a6c819 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -60,11 +60,8 @@ void _assertOSError(os_error_loc_t OS_err_loc, OS_ERR err) { if (err != OS_ERR_NONE) { - printf("\n\rOS Error code %d", err); - BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); - - BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); - BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); + arrayMotorKill(); // Turn off contactors and turn on the brakelight to indicate an emergency + Display_Error(OS_err_loc, err); // Display the location and error code while(1){;} //nonrecoverable } diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 738e7896a..b99a17211 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -26,7 +26,7 @@ #include "fifo.h" // For fault handling -#define RESTART_THRESHOLD 3 // number of times to reset before displaying the fault screen +#define DISPLAY_RESTART_THRESHOLD 3 // number of times to reset before displaying the fault screen disp_fifo_t msg_queue; @@ -426,18 +426,19 @@ static void handler_UpdateDisplay_ShowError() { Error_UpdateDisplay = (error_code_t)err; // Store the error code for inspection - if (err != DISPLAY_ERR_NONE){ - disp_error_cnt++; + if (err == DISPLAY_ERR_NONE) return; // No error, return + + disp_error_cnt++; - if (disp_error_cnt > RESTART_THRESHOLD){ - // Show error screen if restart attempt limit has been reached - assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_ShowError, - OPT_NO_LOCK_SCHED, OPT_RECOV); - } else { // Otherwise try resetting the display using the restart callback - assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_Restart, - OPT_NO_LOCK_SCHED, OPT_RECOV); - } + if (disp_error_cnt > DISPLAY_RESTART_THRESHOLD){ + // Show error screen if restart attempt limit has been reached + assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_ShowError, + OPT_NO_LOCK_SCHED, OPT_RECOV); - Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; // Clear the error after handling it - } + } else { // Otherwise try resetting the display using the restart callback + assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_Restart, + OPT_NO_LOCK_SCHED, OPT_RECOV); + } + + Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; // Clear the error after handling it } \ No newline at end of file diff --git a/Docs/source/Drivers/MotorController.rst b/Docs/source/Drivers/MotorController.rst index 170931348..50061ae41 100644 --- a/Docs/source/Drivers/MotorController.rst +++ b/Docs/source/Drivers/MotorController.rst @@ -13,5 +13,3 @@ The motor controller driver is responsible for communicating with the motor over ``float MotorController_ReadVelocity(void)`` — The motor controller driver returns the latest cached velocity value obtained by a ``MotorController_Read`` call. As such, the obtained value is only as new as the last time the read call obtained a velocity value. ``float MotorController_ReadRPM(void)`` — The motor controller driver returns the latest cached RPM value obtained by a ``MotorController_Read`` call. As such, the obtained value is only as new as the last time the read call obtained an RPM value. - -``void MotorController_Restart(void)`` — Used to restart the motor controller after a recoverable fault. This is currently only used during after a motor controller initialization fault or a hall sensor fault. **DO NOT** call this function otherwise. \ No newline at end of file diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index 2c19720b0..c259b2d61 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -4,8 +4,7 @@ * @brief Function prototypes for the display driver. * * This contains function prototypes relevant to sending/receiving messages - * to/from our Nextion HMI. Call assertUpdateDisplayError after calling any of the - * functions in this application. + * to/from our Nextion HMI. * * @author Ishan Deshpande (IshDeshpa) * @author Roie Gal (Cam0Cow) diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index a692fbb52..85407cc55 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -23,7 +23,6 @@ // Operational commands have no attribute and no operator, just a command and >= 0 arguments #define isOpCmd(cmd) (cmd.op == NULL && cmd.attr == NULL) -#define RESTART_THRESHOLD 3 // number of times to restart before fault static const char *TERMINATOR = "\xff\xff\xff"; From 26596e2d252b5d664cf09c9f04ecac42000e1c52 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 29 Jul 2023 08:38:21 +0000 Subject: [PATCH 112/141] Additional PR review changes (renaming things) --- Apps/Inc/Tasks.h | 4 ++-- Apps/Src/ReadTritium.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 290acca50..3c891a79c 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -171,8 +171,8 @@ extern error_code_t Error_UpdateDisplay; // Scheduler lock parameter option for asserting a task error typedef enum { - OPT_LOCK_SCHED = false, - OPT_NO_LOCK_SCHED = true + OPT_NO_LOCK_SCHED, + OPT_LOCK_SCHED } error_scheduler_lock_opt_t; // Recoverable/nonrecoverable parameter option for asserting a task error diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index e9691fd1b..afa8986bd 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -9,7 +9,7 @@ //status limit flag masks #define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor 6 #define MAX_CAN_LEN 8 -#define RESTART_THRESHOLD 3 // Number of times to restart before asserting a nonrecoverable error +#define MOTOR_RESTART_THRESHOLD 3 // Number of times to restart before asserting a nonrecoverable error tritium_error_code_t Motor_FaultBitmap = T_NONE; //initialized to no error, changed when the motor asserts an error @@ -130,7 +130,7 @@ float Motor_Velocity_Get(){ //getter function for motor velocity /** * @brief A callback function to be run by the main assertTaskError function for hall sensor errors - * restart the motor if the number of hall errors is still less than the RESTART_THRESHOLD. + * restart the motor if the number of hall errors is still less than the MOTOR_RESTART_THRESHOLD. */ static inline void handler_ReadTritium_HallError(void) { restartMotorController(); @@ -140,7 +140,7 @@ static inline void handler_ReadTritium_HallError(void) { /** * @brief Assert a Tritium error by checking Motor_FaultBitmap * and asserting the error with its handler callback if one exists. - * Can result in restarting the motor (while < RESTART_THRESHOLD number of hall sensor errors) + * Can result in restarting the motor (while < MOTOR_RESTART_THRESHOLD number of hall sensor errors) * or locking the scheduler and entering a nonrecoverable fault (all other cases) * @param motor_err Bitmap with motor error codes to check */ @@ -157,7 +157,7 @@ static void assertTritiumError(tritium_error_code_t motor_err){ } // If it's a hall sensor error, try to restart the motor a few times and then fail out - if(++hall_fault_cnt > RESTART_THRESHOLD){ + if(++hall_fault_cnt > MOTOR_RESTART_THRESHOLD){ // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; From d38f440243d6c5bcff3248f2d7a84e3251cdc136 Mon Sep 17 00:00:00 2001 From: Madeleine Lee <74027612+KnockbackNemo@users.noreply.github.com> Date: Sat, 29 Jul 2023 03:42:05 -0500 Subject: [PATCH 113/141] Apply suggestions from code review Co-authored-by: Ishan Deshpande --- Apps/Src/Tasks.c | 2 +- Apps/Src/UpdateDisplay.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 256a6c819..1074b0eaf 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -101,7 +101,7 @@ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t if (nonrecoverable == OPT_NONRECOV) { // enter an infinite while loop - while(1){;} + while(1); } if (lockSched == OPT_LOCK_SCHED) { // Only happens on recoverable errors diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index b99a17211..c7bd8c067 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -421,7 +421,8 @@ static void handler_UpdateDisplay_ShowError() { * Stores the error code, calls the main assertion function * and runs a callback function as a handler to restart the display or show the error. * @param err variable with display error codes - */static void assertUpdateDisplayError(DisplayError_t err){ + */ + static void assertUpdateDisplayError(DisplayError_t err){ static uint8_t disp_error_cnt = 0; // Track the number of display errors, doesn't ever reset Error_UpdateDisplay = (error_code_t)err; // Store the error code for inspection From a0015d6776cd4fcd25d47f5f27f95d5598ffb9d0 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 29 Jul 2023 08:49:11 +0000 Subject: [PATCH 114/141] Addressed review comment: assertUpdateDisplayError takes in an UpdateDisplayError_t instead of a DisplayError_t --- Apps/Src/UpdateDisplay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index b99a17211..3015e982a 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -38,7 +38,7 @@ static OS_MUTEX DisplayQ_Mutex; // mutex to ensure thread safety when writing/re * Function prototypes */ // check for and assert errors in UpdateDisplay -static void assertUpdateDisplayError(DisplayError_t err); +static void assertUpdateDisplayError(UpdateDisplayError_t err); /** @@ -421,7 +421,7 @@ static void handler_UpdateDisplay_ShowError() { * Stores the error code, calls the main assertion function * and runs a callback function as a handler to restart the display or show the error. * @param err variable with display error codes - */static void assertUpdateDisplayError(DisplayError_t err){ + */static void assertUpdateDisplayError(UpdateDisplayError_t err){ static uint8_t disp_error_cnt = 0; // Track the number of display errors, doesn't ever reset Error_UpdateDisplay = (error_code_t)err; // Store the error code for inspection From 3a27d917265f2794d5dda885ed1298b4dc6ba268 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 29 Jul 2023 09:19:09 +0000 Subject: [PATCH 115/141] Fixed assertUpdateDisplayError using the wrong error type. --- Apps/Src/UpdateDisplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 121b8c01e..96a1ebfbf 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -427,7 +427,7 @@ static void handler_UpdateDisplay_ShowError() { Error_UpdateDisplay = (error_code_t)err; // Store the error code for inspection - if (err == DISPLAY_ERR_NONE) return; // No error, return + if (err == UPDATEDISPLAY_ERR_NONE) return; // No error, return disp_error_cnt++; From ff162266e1093087e996b8207f070b566e3e7f06 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Fri, 4 Aug 2023 20:26:18 +0000 Subject: [PATCH 116/141] Additional review edits: Changed error_code_t from an int16_t to a uint16_t and made more functions use it, including Display_Error, which previously took a uint8_t instead. Also added more comments to assertTritiumError. --- Apps/Inc/Tasks.h | 2 +- Apps/Inc/UpdateDisplay.h | 12 ++++++------ Apps/Src/ReadTritium.c | 19 +++++++++++-------- Drivers/Inc/Display.h | 4 ++-- Drivers/Src/Display.c | 6 +++--- 5 files changed, 23 insertions(+), 20 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 3c891a79c..087521e39 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -47,7 +47,7 @@ /** * Task error variable type */ -typedef int16_t error_code_t; +typedef uint16_t error_code_t; /** * Task Prototypes diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 0876aa681..1a98fc8d9 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -26,12 +26,12 @@ * Error types */ typedef enum{ - UPDATEDISPLAY_ERR_NONE = 0, - UPDATEDISPLAY_ERR_FIFO_PUT =-1, // Error putting command in fifo - UPDATEDISPLAY_ERR_FIFO_POP =-2, // Error popping command from fifo - UPDATEDISPLAY_ERR_PARSE_COMP =-3, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_NO_CHANGE =-4, // No change in component value - UPDATEDISPLAY_ERR_DRIVER =-5 // Driver call returned an error + UPDATEDISPLAY_ERR_NONE =0, + UPDATEDISPLAY_ERR_FIFO_PUT =1, // Error putting command in fifo + UPDATEDISPLAY_ERR_FIFO_POP =2, // Error popping command from fifo + UPDATEDISPLAY_ERR_PARSE_COMP =3, // Error parsing component/val in SetComponent + UPDATEDISPLAY_ERR_NO_CHANGE =4, // No change in component value + UPDATEDISPLAY_ERR_DRIVER =5 // Driver call returned an error } UpdateDisplayError_t; /** diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index afa8986bd..c6fc82c7d 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -140,30 +140,33 @@ static inline void handler_ReadTritium_HallError(void) { /** * @brief Assert a Tritium error by checking Motor_FaultBitmap * and asserting the error with its handler callback if one exists. - * Can result in restarting the motor (while < MOTOR_RESTART_THRESHOLD number of hall sensor errors) + * Can result in restarting the motor (for hall sensor errors while less than MOTOR_RESTART_THRESHOLD) * or locking the scheduler and entering a nonrecoverable fault (all other cases) * @param motor_err Bitmap with motor error codes to check */ static void assertTritiumError(tritium_error_code_t motor_err){ static uint8_t hall_fault_cnt = 0; //trip counter, doesn't ever reset - Error_ReadTritium = (error_code_t)motor_err; // Store error code for inspection info + Error_ReadTritium = (error_code_t)motor_err; // Store error codes for inspection info if(motor_err == T_NONE) return; // No error, return - - if(motor_err != T_HALL_SENSOR_ERR){ + // NOTE: If we had >1 recoverable errors, + // Hall sensor error is the only recoverable error, so any other error // make sure a combination of them wouldn't + // or combination of errors includes at least one that is nonrecoverable // accidentally fall into this nonrecoverable bucket + if(motor_err != T_HALL_SENSOR_ERR){ // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; } - // If it's a hall sensor error, try to restart the motor a few times and then fail out - if(++hall_fault_cnt > MOTOR_RESTART_THRESHOLD){ + // If it's purely a hall sensor error, try to restart the motor a few times and then fail out + + if(++hall_fault_cnt > MOTOR_RESTART_THRESHOLD){ // Threshold has been exceeded // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; } - // Try restarting the motor - // Assert a recoverable error that will run the motor restart callback function + + // Threshold hasn't been exceeded, so assert a recoverable error with the motor restart callback function assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, handler_ReadTritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); Error_ReadTritium = T_NONE; // Clear the error after handling it diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index c259b2d61..de483a48f 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -90,10 +90,10 @@ DisplayError_t Display_Reset(void); /** * @brief Overwrites any processing commands and triggers the display fault screen * @param osErrCode the os error location (will be displayed in hex) - * @param faultCode the generic fault code (will be displayed in hex) + * @param faultCode the application's fault code (will be displayed in hex) * @returns DisplayError_t */ -DisplayError_t Display_Error(os_error_loc_t osErrCode, uint8_t faultCode); +DisplayError_t Display_Error(os_error_loc_t osErrCode, error_code_t faultCode); /** * @brief Overwrites any processing commands and triggers the evacuation screen diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 85407cc55..520746d3b 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -97,7 +97,7 @@ DisplayError_t Display_Reset(){ return Display_Send(restCmd); } -DisplayError_t Display_Error(os_error_loc_t osErrCode, uint8_t faultCode){ +DisplayError_t Display_Error(os_error_loc_t osErrCode, error_code_t faultCode){ BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); // Terminates any in progress command char faultPage[7] = "page 2"; @@ -109,8 +109,8 @@ DisplayError_t Display_Error(os_error_loc_t osErrCode, uint8_t faultCode){ BSP_UART_Write(DISP_OUT, setOSCode, strlen(setOSCode)); BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); - char setFaultCode[18]; - sprintf(setFaultCode, "%s\"%02x\"", "faulterr.txt=", (uint8_t)faultCode); + char setFaultCode[20]; + sprintf(setFaultCode, "%s\"%04x\"", "faulterr.txt=", (uint16_t)faultCode); BSP_UART_Write(DISP_OUT, setFaultCode, strlen(setFaultCode)); BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); From 77b7a558094c0c6d5b6fd690577354e7b696610b Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 7 Aug 2023 08:52:57 +0000 Subject: [PATCH 117/141] Updated Test_DisplayApps to compile with new fault handling system. --- Tests/Test_DisplayApps.c | 41 +++++++--------------------------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/Tests/Test_DisplayApps.c b/Tests/Test_DisplayApps.c index 3952ae85f..010113ad9 100644 --- a/Tests/Test_DisplayApps.c +++ b/Tests/Test_DisplayApps.c @@ -2,12 +2,10 @@ #include "config.h" #include "os.h" #include "Tasks.h" -#include "Display.h" +#include "Display.h" // #include "bsp.h" // #include "Contactors.h" #include "UpdateDisplay.h" -#include "FaultState.h" - static OS_TCB Task1TCB; @@ -50,16 +48,16 @@ void testPercentageComp(UpdateDisplayError_t(*function)(uint8_t)){ void testTriStateComp(UpdateDisplayError_t(*function)(TriState_t)){ OS_ERR e; - function(DISABLED); + function(STATE_0); // DISP_DISABLED & DISP_NEUTRAL OSTimeDlyHMSM(0, 0, 0, 200, OS_OPT_TIME_HMSM_STRICT, &e); - function(ENABLED); + function(STATE_1); // DISP_ENABLED & DISP_FORWARD OSTimeDlyHMSM(0, 0, 0, 200, OS_OPT_TIME_HMSM_STRICT, &e); - function(ACTIVE); + function(STATE_2); // DISP_ACTIVE & DISP_REVERSE OSTimeDlyHMSM(0, 0, 0, 200, OS_OPT_TIME_HMSM_STRICT, &e); - function(DISABLED); + function(STATE_0); OSTimeDlyHMSM(0, 0, 0, 200, OS_OPT_TIME_HMSM_STRICT, &e); } @@ -70,7 +68,6 @@ void Task1(void *arg) CPU_Init(); error = Display_Init(); - assertDisplayError(error); UpdateDisplay_Init(); @@ -126,12 +123,10 @@ void Task1(void *arg) testPercentageComp(&UpdateDisplay_SetAccel); - error = Display_Error(OSErrLocBitmap, FaultBitmap); - assertDisplayError(error); + Display_Error(OSErrLocBitmap, (error_code_t)error); // Testing Display_Error OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &e); - error = Display_Reset(); - assertDisplayError(error); + Display_Reset(); OSTimeDlyHMSM(0, 0, 3, 0, OS_OPT_TIME_HMSM_STRICT, &e); while (1) { @@ -143,28 +138,6 @@ int main() { OS_ERR err; OSInit(&err); - OSSemCreate( // create fault sem4 - &FaultState_Sem4, - "Fault State Semaphore", - 0, - &err); - assertOSError(OS_MAIN_LOC, err); - - OSTaskCreate( // create fault task - (OS_TCB *)&FaultState_TCB, - (CPU_CHAR *)"Fault State", - (OS_TASK_PTR)&Task_FaultState, - (void *)NULL, - (OS_PRIO)1, - (CPU_STK *)FaultState_Stk, - (CPU_STK_SIZE)128 / 10, - (CPU_STK_SIZE)128, - (OS_MSG_QTY)0, - (OS_TICK)NULL, - (void *)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR *)&err); - assertOSError(OS_MAIN_LOC, err); // create tester thread OSTaskCreate( From 0c1f379fc0c212a76aa5d24c32d813b7a5cb3d9b Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Fri, 11 Aug 2023 07:53:27 +0000 Subject: [PATCH 118/141] Addressed review and other comments: added prints to error infinite loop, made all nonrecoverable errors automatically lock the scheduler, renamed arrayMotorKill to EmergencyContactorOpen. --- Apps/Inc/Tasks.h | 4 ++-- Apps/Src/Tasks.c | 36 +++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 087521e39..39d6e3c66 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -182,10 +182,10 @@ typedef enum { } error_recov_opt_t; /** - * @brief For use in error handling: turns off array, array precharge, and motor contactor + * @brief For use in error handling: opens array and motor precharge bypass contactor * and turns on additional brakelight to signal that a critical error happened. */ -void arrayMotorKill(); +void EmergencyContactorOpen(); /** * @brief Assert a task error by setting the location variable and optionally locking the scheduler, diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 1074b0eaf..c837b0ade 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -46,8 +46,8 @@ CPU_STK CommandLine_Stk[TASK_COMMAND_LINE_STACK_SIZE]; os_error_loc_t OSErrLocBitmap = OS_NONE_LOC; // Store the location of the current error // Variables to store error codes, stored and cleared in task error assert functions -error_code_t Error_ReadTritium = T_NONE; // Initialized to no error error_code_t Error_ReadCarCAN = /*READCARCAN_ERR_NONE*/ 0; // TODO: change this back to the error +error_code_t Error_ReadTritium = T_NONE; // Initialized to no error error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. @@ -60,7 +60,7 @@ void _assertOSError(os_error_loc_t OS_err_loc, OS_ERR err) { if (err != OS_ERR_NONE) { - arrayMotorKill(); // Turn off contactors and turn on the brakelight to indicate an emergency + EmergencyContactorOpen(); // Turn off contactors and turn on the brakelight to indicate an emergency Display_Error(OS_err_loc, err); // Display the location and error code while(1){;} //nonrecoverable @@ -72,15 +72,15 @@ void _assertOSError(os_error_loc_t OS_err_loc, OS_ERR err) * and jumping to the error's specified callback function. * Called by task-specific error-assertion functions that are also responsible for setting the error variable. * @param errorLoc the task from which the error originated. Note: should be taken out when last task pointer is integrated - * @param faultCode the enum for the specific error that happened + * @param errorCode the enum for the specific error that happened * @param errorCallback a callback function to a handler for that specific error, - * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately + * @param lockSched whether or not to lock the scheduler to ensure the error is handled immediately. Only applicable for recoverable errors- nonrecoverable errors will always lock * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { OS_ERR err; - if (lockSched == OPT_LOCK_SCHED) { // We want this error to be handled immediately without other tasks being able to interrupt + if (lockSched == OPT_LOCK_SCHED || nonrecoverable == OPT_NONRECOV) { // Prevent other tasks from interrupting the handling of important (includes all nonrecoverable) errors OSSchedLock(&err); assertOSError(OS_TASKS_LOC, err); } @@ -89,7 +89,7 @@ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t OSErrLocBitmap = errorLoc; if (nonrecoverable == OPT_NONRECOV) { - arrayMotorKill(); // Apart from while loop because killing the motor is more important + EmergencyContactorOpen(); // Apart from while loop because killing the motor is more important Display_Error(errorLoc, errorCode); // Needs to happen before callback so that tasks can change the screen // (ex: readCarCAN and evac screen for BPS trip) } @@ -100,8 +100,23 @@ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t } - if (nonrecoverable == OPT_NONRECOV) { // enter an infinite while loop - while(1); + if (nonrecoverable == OPT_NONRECOV) { // Enter an infinite while loop + while(1) { + + // Print the error that caused this fault + printf("\n\rCurrent Error Location: 0x%04x", OSErrLocBitmap); + printf("\n\rCurrent Error Code: 0x%04x\n\r", errorCode); + + // Print the errors for each applications with error data + printf("\n\rAll application errors:\n\r"); + printf("Error_ReadCarCAN: 0x%04x\n\r", Error_ReadCarCAN); + printf("Error_ReadTritium: 0x%04x\n\r", Error_ReadTritium); + printf("Error_UpdateDisplay: 0x%04x\n\r", Error_UpdateDisplay); + + // Delay so that we're not constantly printing + for (int i = 0; i < 9999999; i++) { + } + } } if (lockSched == OPT_LOCK_SCHED) { // Only happens on recoverable errors @@ -117,12 +132,11 @@ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t } /** - * @brief For use in error handling: turns off array and motor contactor + * @brief For use in error handling: opens array and motor precharge bypass contactor * and turns on additional brakelight to signal that a critical error happened. */ -void arrayMotorKill() { +void EmergencyContactorOpen() { // Array motor kill - BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_CONTACTOR_PIN, OFF); BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTACTOR_PIN, OFF); BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_PRECHARGE_PIN, OFF); From 4955c268f7d51358cb7963ec017f994160406aaf Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 26 Aug 2023 20:51:59 +0000 Subject: [PATCH 119/141] Deleted #define NUM_TRITIUM_ERRORS and MotorController_getTritiumError which weren't being used. --- Apps/Inc/ReadTritium.h | 6 ------ Apps/Src/ReadTritium.c | 15 --------------- 2 files changed, 21 deletions(-) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index 5a3cb99ac..917b0ec55 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -26,12 +26,6 @@ typedef enum{ T_INIT_FAIL = (1<<9), //motor controller fails to restart or initialize T_NONE = 0x00, } tritium_error_code_t; -#define NUM_TRITIUM_ERRORS 9 //9 errors, and 1 entry for no error - -/** - * @brief Returns the current error status of the tritium controller - */ -tritium_error_code_t MotorController_getTritiumError(void); float Motor_RPM_Get(); float Motor_Velocity_Get(); diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index c6fc82c7d..64445d86c 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -19,21 +19,6 @@ static float Motor_Velocity = MOTOR_STOPPED; //initialized to 0, car would be "s // Function prototypes static void assertTritiumError(tritium_error_code_t motor_err); -/** - * @brief Returns highest priority tritium error code - * - */ -tritium_error_code_t MotorController_getTritiumError(void){ - //TODO: implement for loop to parse this - for(int i = 0; i < NUM_TRITIUM_ERRORS; ++i){ - if(Motor_FaultBitmap & (1< Date: Sat, 26 Aug 2023 23:18:56 +0000 Subject: [PATCH 120/141] Added a comment about always locking the scheduler on nonrecoverable faults. --- Tests/Test_FaultThread_Exceptions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index a37419d2b..dff5ceb0e 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -43,7 +43,7 @@ enum { // Test menu enum }; /*** Constants ***/ -#define TEST_OPTION TEST_READCARCAN // Decide what to test based on test menu enum +#define TEST_OPTION TEST_GENERAL // Decide what to test based on test menu enum #define READTRITIUM_OPTION T_MOTOR_OVER_SPEED_ERR // The enum for the tritium error we want to test (reference error enum) @@ -107,7 +107,7 @@ void ExceptionTask(callback_t test_callbacks) { // Throw a nonrecoverable error printf("\n\n\rAsserting a nonrecoverable error"); - assertTaskError(OS_SEND_CAN_LOC, 0x03, test_callbacks, OPT_LOCK_SCHED, OPT_NONRECOV); + assertTaskError(OS_SEND_CAN_LOC, 0x03, test_callbacks, OPT_NO_LOCK_SCHED, OPT_NONRECOV); // Should still lock sched b/c nonrecoverable printf("\n\rTest failed: locked nonrecoverable error did not immediately result in an unrecoverable fault"); // Shouldn't print OSTaskDel(NULL, &err); // Self-delete task once finished, though we shouldn't get this far From d40b99e5abd5f947a33351e4395af990d4739d34 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 17 Sep 2023 00:12:54 +0000 Subject: [PATCH 121/141] Added additional comments to the test file. --- Tests/Test_FaultThread_Exceptions.c | 49 ++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index dff5ceb0e..17870c8c8 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -8,8 +8,6 @@ * Choose the task to test using TEST_OPTION. * If testing ReadTritium non-Hall, choose the tritium error using READTRITIUM_OPTION. * Once the task enters an infinite loop, it won't ever exit and you'll need to restart the test. - * Additionally, you'll need to use GDB to inspect the state of the system after a fault - * since nothing else will be run or printed. * * This test is run in LoopBack mode with all messages sent and received by the LeaderBoard. * However, it can be run in conjunction with motor-sim and car-sim @@ -43,8 +41,22 @@ enum { // Test menu enum }; /*** Constants ***/ -#define TEST_OPTION TEST_GENERAL // Decide what to test based on test menu enum -#define READTRITIUM_OPTION T_MOTOR_OVER_SPEED_ERR // The enum for the tritium error we want to test (reference error enum) +#define TEST_OPTION TEST_UPDATEDISPLAY // Decide what to test based on test menu enum +#define READTRITIUM_OPTION T_HARDWARE_OVER_CURRENT_ERR // The enum for the tritium error we want to test (reference error enum) + +/* READTRITIUM_OPTION menu: + T_HARDWARE_OVER_CURRENT_ERR = (1<<0), + T_SOFTWARE_OVER_CURRENT_ERR = (1<<1), + T_DC_BUS_OVERVOLT_ERR = (1<<2), + T_HALL_SENSOR_ERR = (1<<3), + T_WATCHDOG_LAST_RESET_ERR = (1<<4), + T_CONFIG_READ_ERR = (1<<5), + T_UNDER_VOLTAGE_LOCKOUT_ERR = (1<<6), + T_DESAT_FAULT_ERR = (1<<7), + T_MOTOR_OVER_SPEED_ERR = (1<<8), + T_INIT_FAIL = (1<<9), + T_NONE = 0x00, +*/ /*** Task components ***/ @@ -108,6 +120,7 @@ void ExceptionTask(callback_t test_callbacks) { // Throw a nonrecoverable error printf("\n\n\rAsserting a nonrecoverable error"); assertTaskError(OS_SEND_CAN_LOC, 0x03, test_callbacks, OPT_NO_LOCK_SCHED, OPT_NONRECOV); // Should still lock sched b/c nonrecoverable + printf("\n\rTest failed: locked nonrecoverable error did not immediately result in an unrecoverable fault"); // Shouldn't print OSTaskDel(NULL, &err); // Self-delete task once finished, though we shouldn't get this far @@ -134,7 +147,7 @@ void OSErrorTask(void* arg) { static void print_Contactors() { printf("\n\rMotor contactor: %d", Contactors_Get(MOTOR_CONTACTOR)); printf("\n\rArray_precharge contactor: %d", Contactors_Get(ARRAY_PRECHARGE)); - printf("\n\rArray contactor %d", Contactors_Get(ARRAY_CONTACTOR)); + printf("\n\rArray contactor: %d", Contactors_Get(ARRAY_CONTACTOR)); } @@ -155,6 +168,10 @@ void Task_ManagerTask(void* arg) { // Successful if exception message and callback message are printed // and the fail message is not printed (tasks are stopped when they assert an error) printf("\n\n\r=========== Testing general task error assertion ==========="); + + // Expected error info + // Current Error Location: 0x0008 + // Current Error Code: 0x0003 // Test level 1 & 2 exceptions with callbacks createExceptionTask(exceptionCallback); @@ -169,6 +186,8 @@ void Task_ManagerTask(void* arg) { // and doesn't print the fail message (task is stopped by asserting an error) printf("\n\n\r=========== Testing OS assert ==========="); + //Expected output: infinite while loop with no prints + createOSErrorTask(); OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); @@ -180,6 +199,14 @@ void Task_ManagerTask(void* arg) { // Also if the motor is reset three times before the fault for a hall error printf("\n\n\r=========== Testing ReadTritium ==========="); + // Expected error info + // Current Error Location: 0x004 (OS_READ_TRITIUM_LOC) + // Current Error Code: The value of READTRITIUM_OPTION + + // Error_ReadCarCAN: 0x0000 + // Error_ReadTritium: The value of READTRITIUM_OPTION + // Error_UpdateDisplay: 0x0000 + uint16_t tritiumError = READTRITIUM_OPTION; *((uint16_t*)(&canError.data[4])) = tritiumError; canError.ID = MOTOR_STATUS; @@ -301,9 +328,11 @@ void Task_ManagerTask(void* arg) { case TEST_UPDATEDISPLAY: - // Call update display put next to overflow the queue (actual issue) + // Call update display put next to overflow the queue printf("\n\n\r=========== Test UpdateDisplay ==========="); + // Expected output + // The display should fault, but the test will hit an infinite while loop and nothing will be printed createUpdateDisplay(); for (int i = 0; i < 10; i++) { @@ -316,7 +345,10 @@ void Task_ManagerTask(void* arg) { break; } - while(1){;} + while(1){ + printf("Reached end of test."); + OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); + } } @@ -343,7 +375,8 @@ void createReadTritium(void) { (OS_ERR*)&err ); checkOSError(err); - printf("\n\rCreated ReadTritium"); + printf("\n\rCreated ReadTritium"); + createUpdateDisplay(); } // Initializes ReadCarCAN From 0ece51a1cd11644b3536c307370feef9eaac34c3 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 23 Sep 2023 02:10:35 +0000 Subject: [PATCH 122/141] Removed redundant calls to assertUpdateDisplayError. The only ones left are those in UpdateDisplay_PutNext (UPDATEDISPLAY_ERR_FIFO_PUT, UpdateDisplay_PopNext(UPDATEDISPLAY_ERR_FIFO_POP, UPDATEDISPLAY_ERR_DRIVER from display_send), UpdateDisplay_SetComponent(UPDATEDISPLAY_ERR_PARSE_COMP). The rest of the errors that get returned from functions aren't necessary and can be removed in a future issue ticket. --- Apps/Src/UpdateDisplay.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 96a1ebfbf..b988f63d9 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -88,7 +88,6 @@ UpdateDisplayError_t UpdateDisplay_Init(){ assertOSError(OS_DISPLAY_LOC, err); UpdateDisplayError_t ret = UpdateDisplay_SetPage(INFO); - assertUpdateDisplayError(ret); return ret; } @@ -174,7 +173,6 @@ static UpdateDisplayError_t UpdateDisplay_Refresh(){ }; UpdateDisplayError_t ret = UpdateDisplay_PutNext(refreshCmd); - assertUpdateDisplayError(ret); return ret; } @@ -203,7 +201,6 @@ static UpdateDisplayError_t UpdateDisplay_SetComponent(Component_t comp, uint32_ }; ret = UpdateDisplay_PutNext(visCmd); - assertUpdateDisplayError(ret); return ret; } // For components that have a non-boolean value @@ -220,7 +217,6 @@ static UpdateDisplayError_t UpdateDisplay_SetComponent(Component_t comp, uint32_ }; ret = UpdateDisplay_PutNext(setCmd); - assertUpdateDisplayError(ret); return UpdateDisplay_PutNext(setCmd); } else{ @@ -254,11 +250,9 @@ UpdateDisplayError_t UpdateDisplay_SetSOC(uint8_t percent){ // Integer percentag } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SOC, percent); - assertUpdateDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastPercent = percent; return ret; @@ -271,11 +265,9 @@ UpdateDisplayError_t UpdateDisplay_SetSBPV(uint32_t mv){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SUPP_BATT, mv/100); - assertUpdateDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastMv = mv; return ret; @@ -288,7 +280,6 @@ UpdateDisplayError_t UpdateDisplay_SetVelocity(uint32_t mphTenths){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(VELOCITY, mphTenths); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastMphTenths = mphTenths; return ret; @@ -301,7 +292,6 @@ UpdateDisplayError_t UpdateDisplay_SetAccel(uint8_t percent){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ACCEL_METER, percent); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastPercentAccel = percent; return ret; @@ -314,7 +304,6 @@ UpdateDisplayError_t UpdateDisplay_SetArray(bool state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ARRAY, (state)?1:0); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -327,7 +316,6 @@ UpdateDisplayError_t UpdateDisplay_SetMotor(bool state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(MOTOR, (state)?1:0); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -340,11 +328,9 @@ UpdateDisplayError_t UpdateDisplay_SetGear(TriState_t gear){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(GEAR, (uint32_t)gear); - assertUpdateDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastGear = gear; return ret; @@ -357,11 +343,9 @@ UpdateDisplayError_t UpdateDisplay_SetRegenState(TriState_t state){ } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(REGEN_ST, (uint32_t)state); - assertUpdateDisplayError(ret); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -377,7 +361,6 @@ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - assertUpdateDisplayError(ret); if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; @@ -388,8 +371,7 @@ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ */ void Task_UpdateDisplay(void *p_arg) { while (1) { - UpdateDisplayError_t err = UpdateDisplay_PopNext(); - assertUpdateDisplayError(err); + UpdateDisplay_PopNext(); } } From 621fcc9614c1644ccea40188f8c8017351427b4e Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 23 Sep 2023 08:43:26 +0000 Subject: [PATCH 123/141] Changed fault handling for UpdateDisplay to clear the queue and reset the display every time instead of erroring out once a restart threshold has been reached. --- Apps/Src/UpdateDisplay.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index b988f63d9..455121801 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -25,9 +25,6 @@ #define FIFO_NAME disp_fifo #include "fifo.h" -// For fault handling -#define DISPLAY_RESTART_THRESHOLD 3 // number of times to reset before displaying the fault screen - disp_fifo_t msg_queue; static OS_SEM DisplayQ_Sem4; // counting semaphore for queue message availability @@ -386,42 +383,23 @@ void Task_UpdateDisplay(void *p_arg) { * used if we haven't reached the restart limit and encounter an error */ static void handler_UpdateDisplay_Restart() { - Display_Reset(); // Try resetting to fix the display error + disp_fifo_renew(&msg_queue); // Clear the message queue + Display_Reset(); // Try resetting to fix the display error } -/** - * @brief A handler callback function run by the main assertTaskErrorfunction - * to show the error screen if we have reached the restart limit - */ -static void handler_UpdateDisplay_ShowError() { - Display_Error(OS_DISPLAY_LOC, Error_UpdateDisplay); // Try resetting the display -} - - /** * @brief Check for a display error and assert it if it exists. * Stores the error code, calls the main assertion function - * and runs a callback function as a handler to restart the display or show the error. + * and runs a callback function as a handler to restart the display and clear the queue. * @param err variable with display error codes */ static void assertUpdateDisplayError(UpdateDisplayError_t err){ - static uint8_t disp_error_cnt = 0; // Track the number of display errors, doesn't ever reset - Error_UpdateDisplay = (error_code_t)err; // Store the error code for inspection if (err == UPDATEDISPLAY_ERR_NONE) return; // No error, return - - disp_error_cnt++; - if (disp_error_cnt > DISPLAY_RESTART_THRESHOLD){ - // Show error screen if restart attempt limit has been reached - assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_ShowError, - OPT_NO_LOCK_SCHED, OPT_RECOV); - - } else { // Otherwise try resetting the display using the restart callback - assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_Restart, - OPT_NO_LOCK_SCHED, OPT_RECOV); - } + // Otherwise try resetting the display using the restart callback + assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_Restart,OPT_NO_LOCK_SCHED, OPT_RECOV); Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; // Clear the error after handling it } \ No newline at end of file From 7a03bb29a8c79aa32fe1ddf8fc232d08c8ae2300 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 23 Sep 2023 09:10:35 +0000 Subject: [PATCH 124/141] Made print statements and comments a bit clearer/cleaner. --- Tests/Test_FaultThread_Exceptions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 17870c8c8..2ae451a7d 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -332,7 +332,7 @@ void Task_ManagerTask(void* arg) { printf("\n\n\r=========== Test UpdateDisplay ==========="); // Expected output - // The display should fault, but the test will hit an infinite while loop and nothing will be printed + // The display should reset, and then the test will hit an infinite while loop. createUpdateDisplay(); for (int i = 0; i < 10; i++) { @@ -346,7 +346,7 @@ void Task_ManagerTask(void* arg) { } while(1){ - printf("Reached end of test."); + printf("\n\rReached end of test."); OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); } } From 5420d04f324e771277a16101eeca98aebca5c4bb Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 30 Sep 2023 14:00:46 -0500 Subject: [PATCH 125/141] Display fault is now 4 hex digits --- Config/Display/display.HMI | Bin 10736346 -> 10736346 bytes Config/Display/display.tft | Bin 764428 -> 842200 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Config/Display/display.HMI b/Config/Display/display.HMI index 07246ef8a80f095397cb7b3379f971d7f02ffd8b..c3ad5f473909608d19523073cf70650b994542e7 100755 GIT binary patch delta 964 zcmdUpZA{H^6vywsdv7;S+wYd1s6@|H+?1q*qz8&3LP~ik&s`TGdF<<4>Qpy%`{kj8 zd1Jj`%-<$&FtgUYVQV$k7Mr}W^@eP0{;|f!3vZq6vvbaO-+j;Nzu92y*KqjjpEu|l z1ARx^ounKkJ|@~)qWi5r#angBewy&8-KcZEb@?%C>u8V7v+8ok>2%7&hPwkwh(2gk zRQ_VDsucG>jUq>afZ5^>ee^ zfAJ;+%y5SXCc_h6@P-e3F$GiM2Y&=$8UisLGZ2Jegdh}Q2uB2FViqD1g=oyi99R&8 zxrjv^<{=*Qk$?qAL=qMv8H=zOOOS%4NX0UwAsrdW#B!`a7P7GttB`|Sti~GTVJ+4n zAM3FJ8&QBwC`1u9qZlRFg00ww?I=YVc3>xVVK??*FZQ9_aIY)8TNdhtkJHcU<_s3E zTNJC~PgQleSWDxKPj3}vB}+@MxmIbE1J&+{a-`S%QN3MfOIKuIf^d^VVZvW6PZduL zvN&IO$&5^qA|Ggz+L0*&^h&t2L_6+W~)f&s*N4)vBuR4F72ptP9EEo%J z>GBw_PJCvoRETZF2Z#?6A0nmH}Ct-^IW|1zJrgOZG$E)36_yhwpO=m zti1G=sckF+I4}+|7>@~XVj^PULL4R`9toI?DR5&drXdm2k%SqTiDaZ86=_JvEM#Cd zGLeOB%s~$3A{QRyAs_QFA6_iLLM*~!6rd1ASc0V}#xg8N307bwR-qKDu?A&Wi*;C! z4cLfH*o-aMif!1A9oUIo*bN`bu?KrmfqmGI12~97IE+dh!BHGTRbOy-Sz!Ln$bU0?QgV} z1zRhP?jD!d_V6SfP3!ka=}cuRO&*de?lyeqsX>=bqh?+YIYANKIkVDTSZsxLDD diff --git a/Config/Display/display.tft b/Config/Display/display.tft index 35d7b592406368fb0c3abc6e6cac29b830e60f1b..566efd139c510c9370daa5dba35b065201b4f498 100755 GIT binary patch delta 34204 zcmeHQ3w#vSxj!en3mb+E(=HzcgR zf*=TTL_r}B#g`~S}D%+7B1nFsmZpA5{* zng99D_d4I4*UW4l`Q6a>Um3oBbm#Yf-(7+KX$#)qPL$t7)r|etFq5Y5O)>_>au*T`{Jc*zl7M zTgCRDbXa@oaLEUk;^5M4aH%P{)Dm852`{yT-=daq`6fQ6>%g-XjIkIql_j#WKZy;B zCC9y+8=Zk*CFc%07FanK|(E(d5y^969kNG#^jg#GL}dTv z4`#NVWwQN){lz*V`Qr{2_A^$)R-E|J(Fe`gE!aC??}**naP+~%otB0f3#`*j4W$dL zWAtN+^?lyKmfh&wpVBZR#X5_3F0oeca(n9W&$Nl4nY?SlQo5vnZqJTl0bMGDesGN+q*P5gWlZJ0Y}sxf6OG{Phb30ZoXmS2+^vEB^SB2na}w{}=nO7N zL=!J;Pa=YGyswR|I_@uLOsOV-q-?GcHm2Pkv45AvDN0kUUR$Zve9o8|n6BML0>|=< z@&^Jl0(NB4~=8UQCwe^P$d}u}B~W6VI#lF_h=ptaT@v@(hR6tRYz_ zmZ67PI8q~CaY3)Qj|;Y^7=zJB7A`%$j-=-B!ZRDgk%Ysw`W?uNoY@so>NgaVGq02E zfxNhSSE%f0nA_tIf+RlrRLI*S8WYN2bzFwu{SJ62I10m zvis@GXO&nF#nJSHV`s$6=aR;q_-ubKXv}U&S_}6Md`@N307Gxu5~jwo8B0m`4t#F> zjhvB9xO9cD3r^tkY%w>46&LD`pV?izd&04aF`La=5P7c#fIJiBwYyn4kvZA-8_VXD_ORd7W#nLOIraW>Rb#OOv{brzzEsWB( zj^A3D^!VMpZ$_!rv?rji zq)1+Jd&=e#!>qJ~+l=Z2ra=ScF4)Se1M$GC%&o-9k!Ic(i2JV&ohY%2&%WyT_w@A0 z!>9czDl0zKUpP3Gu#{MRZp+*noMXJMJ5HR2+A5RWVLNp5x$Q~B>wLz_JY(6WX>_bn zxz&3Pt|4xp*ljGlD^%Y0bJS4}P2X>8D$9>lTsSHFbE?p}1Jh^vb3&&O_Ezb?jP&f# z6dJmqjx_x!%f_O&u7^F9Ns_C*(W#XWeRg|R<`Lg>S+O;(xJfB+?9Ql`nGX}+vpL(7 zVryd>os#pwSVk}DQ;GNK?8x`2W-)FYIbavt6-)1d<6;=$`UYjfHr_IQaJoC}-K$BU zv)glev9utoCTRL)r1Gah4I4gioQa`HRZEpuOa3{gh@&kZfxlL(Lxq=Y+eK-5qTDZGKI}hPr8a`+2e|C)dW}nf9F7O&)xw@MP4< zaInOR3+QSgF$-P^&Wm(S<4ltI>%v&3)WMw8UL`Akf6C#QW0!a=JVr9#F4|G-j;ow1 zKV7zNSq080eTzzMJXXymxo;N5I=MHNt@oUgZC_U5jwr2lU@5vfdjhos$wx+oUtMWh z%82*|6@|^242*k#WFH#c{1Ly}W@Z&d8Y3CCHKsB2mF>cT(ebTX7`^^)`^>x<#bG|j;>9JMo}W9@sIa!^~GpO?fkO=((ML)39-)@Xa!!Ldde z?yQb|UL6;0^cAkWhNG>=m@{i^U6`d+jV{tzZJBmY3co-bskAZA?ZJowH8gN+q-lz= zM5uJ#33Y&s!C2;`_&W4Z><)X-2;BXOWq{Kf+c+~66T&j&9OcEySbmOaP8^PpiaYbj zQ}zjw<}#5vsJZ5IrEl{OKGdpn1bClwRy|C!K~dLOkqjANvGoOqJw$Wd(`G~=d|VxQkwFs_o&^N zeRA|^S*X&17^Z~9)SN#%E!F{gVEIs2>Ux8Ha^xkGP$ffQ=qR9H-8Ib_vV`JCSnY0E zzf;FGYaq~+t2#y9KHbLRc@EQ*PavXpk@l%A>FkXh(bb`Y+34=)ELZs-IwAcz zt+_)Aqn2v=0G89%cHBBM{^v|hc^Q$3azbUlruoATBR5Lh&(oA?ZO12Pwf35?`vSTH zv_l!!wBEg0@1cc-wH=?h-r1tzTd)_@>-`j9nbTvRgNJ5gL@Q`L019uO9qN&_k+L~y zjHlsX+f1woMtBSzKW7@}ukE;LPNa3x__=B&_*AL&ESt48dSi{NoL^uhv$o^ipA&r$$D!HPUBaS2b^)PN%6x>X5)TJKi;lrksKix98Lp(YVv{$h^{kH#~yr zT5??@XTG-CWpS@{M3<_rpFT1#@z3OTd#Gc>h1^4pczxRqu5<^D5e)uLzXozdHM2)m)oZH3+*Et`o?VGaLQ)8DrwuPD`n)?VHhvPQ3U|z$-vDzZ-;O2qK}f#c$F^ zG}2$^p;H&%38ZfIF3k<%R}=|ValYx$B9ogq!reYjz{^K@svE@7otE#p(pz_ZCUzg4 zJ+Yv!s@hdveQ=|BpF8XecCj;zkJ5fvdO;i^C$#09G@M#)&-krQwJKb`xGb^Ol(*#3 zYB*7ma6T0c<3Z{jRyOMul}Nm!=dC)XMI#fFw^+Kmtm7VVH@Q`!^Jy+c-Eo`G_v%Ru z8)BL1YROj*&C{fMSBZZ}`1t+&GFPLsWsi^J)8oM605>2c@T%d}uCl0aRmLYKI(6+X zLxoUZ)e~`f@tP<+DG3@mNl#31#rp4jh4+Lna;LPQPOop=fG|Am zju_wdjm5HPG+4owcE|P(b2M)8jcopeV>VsBOo-eemMgF{(3(%gBdg%g9ru7w7x9E*8Q`+D z@Rd0~m5M4q_#fjJQm3T0JD zPoS|XYQN=zdQUpdR5#*s6MR2?K%diHj*hHtA8H!}2Mrx+soA1iwb*5D)932pRq*AQ@y4I} zo*S0eqEZK$(OUHMq*O-fNY}-jw}wzZQChg_nEaeN%~dtm-9{#dkljSm1b&R(j4Q;7 zLiF!uV`11#n$EgrtB%W0g!{M>mbRy3>Mi(qNPYRP0ID?8EZwRWmG5R?Gx0p06YuC| z>ESwQYuk4VqNuF+l#*YbAG*iVV8M zpPoiz#b}zPGIJV8# zLNQlzd*9bB3P<&;OFT2hO3KB4X)3_O?d`=D^)UF=1Ub%0&u))Jb={Bc?ZZ*JCUK1v z-SlfY_?|ciYeS9Bs=4j<&((gSrR0KmEpK$vFGGj=?eP-+qr0jT8}6#^v|&Zy?~)sT zqdb;0exWsClVTHpOI6IHzZ&&Gnu*=|#hlCpwmHW#oUu2P*8C4=HZ0mFD%RXwoBDsz zBAfcZsK}RCv}jMEQqz5NvSJY@x+}Mu@`o3TDLs__VtEf`a6)mRsPCcNo>*MyC?4*} z%PSHu^ionNFH=f~#}_I+EN__Ui9=%-rJs1qqI4bF zg-UaCu48zvK~q@&!H9knV+GV>aV*2-fYjz*mVr9h`d%`GDYlvCZ|uM>pHh>?!` zVn+e$OL;shkH3<~H|YqSeobfTk+*yvc^im9dclYQe$pfIW+=*ooZ$}Km*n|R zCD+g7@o)0@xjg=zj*#!L{>t|T;r!(!<(UM!o}yfN8P30-t6u-$CiR?Js-9mfSFTFp zp9;%T<$HW^L&Z|%K2tauHB=JRb0WA0OuyQMx4AxqHSuK&pEO~7B-=nQMO0$VQb zct}Z3EkW`fz`6fYv%C7Tw~1}Y<{vfec}S^F5c~To<^ewdt!5>ef_h*!oN3c>@op-b z8lo4S`zf8dN$}o^O9Cz;)N~;R3WV7R#Ad`vM;ow{5TGeX^j&;7{xC@ZPD&H~pMZNw zN~PCJ^j06A#WJ@%g2P~mX?6jFs zfP9gKG){h8IG4Z|FWQtOxS{NBxB+RaOE(q7$FY)fFbF} z#b^Cs9O%io^fVYpWnCYGMmGcn$UrLFKL{rS3I80sZXhr+knov7I2lOzAEAqGATTnJ za9JTP{N+Gd`7(pP@-0^_LLq-0BU7^ou>8X{@~m5Ab`eLabJ|Rx&+~a87uR}B0MExx zv_r$-`M^OUHzOa6%R=G>z#)oaI8g8iiKqu+bS1_+B$&np9$#G%p5Rkx2yil*Hltv= z4pp^*xX4ITekdyMQ>JyHwp%YCE?b61!6ZJr52L_(ibp77Dw^{NLwRXyREK{!=C;ctPzUiF}-swaFCcHkYM^ zKub3@VOL|vrQ9SgURv0(kE;KSpggK{Dnp^DS2_w)r4v3Y3{HK9QMShCyJ7G-l8@I# zwO&a|6=TRm0_I`whMhLTHAXk#I+TD?;LuraM*1=!dL0`0ln3DAo($zkHua(R8gb}C zcMIW2`uT{)VM_nY2&PRJD?S^hxLgDu2Bud#ic&Zbz5=@ur*I&gLRk+7&{H^s!YLdG ze;@qyZ~#4p1L2R7(*iSOOCU`nJwYco6AEdj5dhD~%_L2eHV{7@207ILVYgt{LjpL3 z1mTOq;Pl;*QLM)2wlMhZ)CQ2Qw2_`#fjd-4$FD?#M}nyt*V_TmQ#(L-1@=&U0Q;*F z^hQ6Zp#rmUqoXqE8>z|JG&%~13yf)~5aCGrnTZ`P#09~$>9R#*CE|kMvB32DM^TCk z!tcUv#3?QazYe<|7oexOAe`D zUbBh-z3!z|Qhj2j!yu=cA&kOW4+-ED5`^C$2LB;&qgag(wF05=%7BnC2wsT-+D7_Q z*Fb{le$qn%IE4h^G>jvgX(M_~FkS1d1aPAt3?YGfJevIkXs@ICXeNoT7p7M)2380rV6N zgdYuPC1i$dC5BKY?VyvJ33=&0)3yN7>z;7gdq_LB1!a*}iOtj4^{_w@3Jb!whrw%r z8%1k;YQx}l6c%2uY9i@Mod*fniCrJu0oNGOgusfOHlo+?UATtMax>yT1)_(AfnJU@ zB{ilGvVd@Y)bSa5J=HFjObi}If`|g-MU+6&&r!@6jbS9{X&8C;7&JFj)^z~1diA3K zg$0!*Hyd#Z3&Q(h*Q+1&6c&Wj*w=_tSP=dJ`0HT-dI}4|4`BxmJ1a4V5RF%0oGgtY z*MLTDCKS+&AwUla)tJ9c!XRJAKuazr=DV@$u>hQ6f$*2Z;Cq1^WompH!r-q0Cq1#b z7%8b0cufW6k#OoYNN_-}0i2o$!e7GfV-&!L80fJ8dZQBpaj|TSav+<$8PI7U@Td&o z6oYyhQ8pIM1i`fFqQ!=>XeJ0w1*X?Kic&lfPIsgcr+6TIK6bs{K~M2OctEECoZ^A- zW#F&J18|B5!jA+r6EZ^`Oi(822|Br%kf)hOfL{O7G-(4B(P5BN?GW}$?0Q%Lr?BwJ z4vD`BdZSp4&s$;ew*z_(gWzK*plzf-^&BKPpyvQiVL|v|>|`@-M6U^^YrQIg8~vc- zFxw<6lLix0$D7$bV7bMHbq5qRvlRAp5|)K>Fed>2zKD$}DY(YOfuhllRgzKtalM|g zv$#eFHgcU@7}~JJELJ_Nr0{iO+r!HLCjJ(=Uay^HiI-MmhVtTSn zjx|a{q8&24*oTNAk0^r@>|D%#MA@6T8cL!e^}Z~6u2lx{)nd$ArNKfi+kA0qozh)& zUZy*8gEx^AZd@$c4x;zTXVYneyi(fqoWSIB|A^U&~7B8&_vQL~?59Ahj z=a+y923jmuK8AI6bE0_RG4OvDP!BO<6DU_~1m&~h@r|IIj$8I; z1P|uZ#e^*`9^Tpz?Ti|YMSMr!G!7lhy zO6KOLl-CnFcNK3urJPGll39fbqhywNXDe!=2e2GbwhdPH=qlE2gOwG49w4Z@nD;b9 zRfz9D4N-dm9}{`cK-6Aw(=$L4F%Pl{z5|4g?Wl&tZer4QFqjAY0O5oAJTYVkC_O+H zh(8nJ5j|^^22*l(M)A;7oUK90#gOWFPr>c0Z7IZg?4{K5KYaq9Z9d%0oE}ybR zYz!-5gLyssS{$oG?jGC~nd0tep~2RArE`}oeiK`UIp8+_BHJVO)Pv+M+&_OLlEM5g zvF%wP$-NkRNZjxokYwS04#+_udBV99$U$+(P9Scq&V4~hcQN{TrK|EhMrkEr`w?@C z>z`L%=}7UOo9eUS_SH&KC;HpGf8yPEZmM|tVddqdC7g}CHJR18ok6*@6_7`YH!SHYR;*Kci`Q2xUB$vWrD)9SAk68lvQbIZqXV}QwIj5B zjMbdaF)jWhU&4sq>n&l^ahyd=llxq+OVJoy$7ZwdvK!c3B1p}i#JkoeE8C&Dlip%=y^@x?p5KGDgG{UkY+{6ay|8|xBY@69^VDx}=(Asp|Q*diROMczgw zx5Ugw&gp}`0J~<9c3vnQqPpcUUxB8x2PUSEGNSi-AHzDG*ZZv0tIu;y3fE(h_B{Iu z+eHMa7*ub;BxM_W5`$l_cfC&jQ>0!%P5zkGO6*Z0A1T9?6|5|BRhbm{|GyXPQdGZO(%a3 zssCp0v;SgmOYBvtm-C7aY~(i(Q;q=C)X~mQ7}TobPa)2SV1#~@5xv)YmVJTazoc5p zU-}Avqciy@`wBNBZ10!-7sTLs_9^>>{T11#*}s`bCBqTj5BGZiA+JwKl|<=AxatV> zDZtYQO&9G+Qn(fm^!Ru@RA-fn?xj%9=VQLn4%mddwaSThtu zl_QMkz1~7T3B0DNx?QD<(lngHr}3-#wdg2FdFVEpkKrZU$;a|5L0q60n1R$xejUGt Re@9}&eY*8GziV2a_kUZd1a1HT delta 3538 zcmeH}{ZCV86vxlKy)A7yl&a8{VM-On1rTjjCND$$&1G3O6K2fJ6c)q?Y&f&vOTaC2 z%*7!oYCKNeoR}F$oKcWo5kzplQbjawQMSnD54w=Jn8oQdYWKZ#i!u8Pmh|47`#jI* zd(J)2ecp1fwa;k0niDK!ZjC1*I~51-6gJPRn_Khq>Z(9Zo7b?8+BUBjWvI3t*6D4E zbb4>Vs_Y@O4IZ`Ye|C94LcODQo40$5S=pe?`t@mnOwcWDGF`XqjXh#x5L*YaZ4f&O zVkcqjB>W$qgv~2Twkiu9n=NMiD-hMJw^G@#Ty~i=8-hwhP;CgBI)d7pbuZk7`itUJ z=&@dI!z{2km{lLHx9vA?FqPSL zQ(1g--B$LwjNUE3w=i9$ZJFj7$nX68Cxtpnxn-QmpO-7CEGteAamTDDv4=4 zMx5h0PIe@5x;kryoJitoqnw(|X)-yLJ%*AhHOah59;C7_+H||P*=RbAH&|tJ5@$)+ z#k-BBQ%aH%aXgOWIFL6p+n?*t&YhJ#TfT7fqH!+t(Uzb+Cs;k4VMJ!hD;^GyfyeWg zUg_gBi(=C^X7G|JC`Vr7-Kx=kgXfGv*08j@^kVdys5}n<)5OB%)$oSS8v8HdhvJVs}ajs)NAO|BA|vf8+{j zf~?%r_if_!>TDv7=0Vz@0#}4+opj}0D2>KeLm&#E#mnF&M z!|YMYrRXrW0O}=K6lQM%s-r7)SV>e4h@+i#+asVKkijGa z?L0+&MDn1WL$*>Z&D@8V3QPI9~8m0>4pkUzQ*mm%J6kUo%UGSm&yCzj(# zU5y|8PvRy18dCRAGqzcP9@0swmfsA^qc@`0ddIM zUXT{q*9%gNfjl7Z^nnyhQy<3t21q30Qzxm$xbHd1-RjK*S@J#Kvfmn&a@G7%>HSmO zXdW>pLe$gvypaT%b{fN2;2@eWBS1=lxXvI+BgkI4at5SPo`P70LGC-G>nvxg!w$K9 z7IA?@qV3Xh4qgEnIET2aAbGO!JjhiEoo8LWGgfN)Imak>_anwX&KU2v!tn6Rr(xFp zmqF$vMQ7ZY^?xs{OI#n0K2K2vy-dZJ$#3YgymtYqb|SwNyeYl|!^s z7F Date: Sun, 1 Oct 2023 04:55:58 +0000 Subject: [PATCH 126/141] Fixes during hardware testing to a) stop the display error from being overwritten by initializing display and update display earlier in the test and b) prevent the UpdateDisplay task from running into FIFO_POP errors by setting the message queue semaphore to zero when resetting the queue. This was also added to assertTaskError to ensure the error doesn't get overwritten, but this really shouldn't happen so we may want to take it out. --- Apps/Inc/UpdateDisplay.h | 7 +++++++ Apps/Src/Tasks.c | 1 + Apps/Src/UpdateDisplay.c | 17 +++++++++++++++-- Tests/Test_FaultThread_Exceptions.c | 23 +++++++++++++++++------ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 1a98fc8d9..6afb41b15 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -130,4 +130,11 @@ UpdateDisplayError_t UpdateDisplay_SetRegenState(TriState_t state); */ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state); +/** + * @brief Clears the display message queue and sets the message counter semaphore value to 0 + * @param none + * @returns none +*/ +void UpdateDisplay_ClearQueue(void); + #endif \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index c837b0ade..50d53f1c9 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -92,6 +92,7 @@ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t EmergencyContactorOpen(); // Apart from while loop because killing the motor is more important Display_Error(errorLoc, errorCode); // Needs to happen before callback so that tasks can change the screen // (ex: readCarCAN and evac screen for BPS trip) + UpdateDisplay_ClearQueue(); // Clear message queue to ensure no other commands overwrite the error screen } diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 455121801..d89aecb99 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -214,7 +214,7 @@ static UpdateDisplayError_t UpdateDisplay_SetComponent(Component_t comp, uint32_ }; ret = UpdateDisplay_PutNext(setCmd); - return UpdateDisplay_PutNext(setCmd); + return ret; } else{ assertUpdateDisplayError(UPDATEDISPLAY_ERR_PARSE_COMP); @@ -363,6 +363,19 @@ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ return ret; } +/** + * @brief Clears the display message queue and sets the message counter semaphore value to 0 +*/ +void UpdateDisplay_ClearQueue(){ + OS_ERR err; + OSSemSet(&DisplayQ_Sem4, 0, &err); // Set the message queue semaphore value to 0 + if (err != OS_ERR_TASK_WAITING) { + assertOSError(OS_DISPLAY_LOC, err); // Don't fault if UpdateDisplay is waiting + } + disp_fifo_renew(&msg_queue); // Clear the message queue + +} + /** * @brief Loops through the display queue and sends all messages */ @@ -383,7 +396,7 @@ void Task_UpdateDisplay(void *p_arg) { * used if we haven't reached the restart limit and encounter an error */ static void handler_UpdateDisplay_Restart() { - disp_fifo_renew(&msg_queue); // Clear the message queue + UpdateDisplay_ClearQueue(); // Clear the message queue Display_Reset(); // Try resetting to fix the display error } diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 2ae451a7d..0fd2cff55 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -41,8 +41,8 @@ enum { // Test menu enum }; /*** Constants ***/ -#define TEST_OPTION TEST_UPDATEDISPLAY // Decide what to test based on test menu enum -#define READTRITIUM_OPTION T_HARDWARE_OVER_CURRENT_ERR // The enum for the tritium error we want to test (reference error enum) +#define TEST_OPTION TEST_READTRITIUM // Decide what to test based on test menu enum +#define READTRITIUM_OPTION T_DC_BUS_OVERVOLT_ERR // The enum for the tritium error we want to test (reference error enum) /* READTRITIUM_OPTION menu: T_HARDWARE_OVER_CURRENT_ERR = (1<<0), @@ -159,6 +159,8 @@ void Task_ManagerTask(void* arg) { CANbus_Init(MOTORCAN, NULL, 0); CANbus_Init(CARCAN, NULL, 0); Contactors_Init(); + Display_Init(); + UpdateDisplay_Init(); CANDATA_t canError; @@ -196,6 +198,7 @@ void Task_ManagerTask(void* arg) { case TEST_READTRITIUM: // Test exceptions in ReadTritium by sending the fault chosen in READTRITIUM_OPTION // Successful we enter a nonrecoverable fault and the fail message is not printed + // And the correct error info is shown on the display // Also if the motor is reset three times before the fault for a hall error printf("\n\n\r=========== Testing ReadTritium ==========="); @@ -212,10 +215,16 @@ void Task_ManagerTask(void* arg) { canError.ID = MOTOR_STATUS; createReadTritium(); + //OSTimeDlyHMSM(0, 0, 10, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the display to initialize + // for (int i = 0x07; i < 0x09; i++){ + // printf("\n\rSending %x", i); + // Display_Error(OS_DISPLAY_LOC, i); + // OSTimeDlyHMSM(0, 0, 0, 104, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the display to initialize + //} + //OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the display to initialize printf("\n\n\rNow sending: %d", tritiumError); // Sending 0 means no Tritium error CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish - printf("\n\rTesting Tritium error %d", READTRITIUM_OPTION); if (tritiumError == T_HALL_SENSOR_ERR) { // Send the message extra times to allow for motor restart for (int i = 0; i < 3; i++) { // Faults if greater than restart threshold (3) CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); @@ -334,6 +343,9 @@ void Task_ManagerTask(void* arg) { // Expected output // The display should reset, and then the test will hit an infinite while loop. createUpdateDisplay(); + + OSTimeDlyHMSM(0, 0, 10, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the display to initialize + printf("\n\rSending display messages to fill queue"); for (int i = 0; i < 10; i++) { UpdateDisplay_SetCruiseState(1 + i); @@ -358,7 +370,7 @@ void Task_ManagerTask(void* arg) { // Initializes ReadTritium void createReadTritium(void) { OS_ERR err; - + OSTaskCreate( (OS_TCB*)&ReadTritium_TCB, (CPU_CHAR*)"ReadTritium", @@ -433,8 +445,6 @@ void createUpdateDisplay(void) { (OS_ERR *)&err ); checkOSError(err); - Display_Init(); - UpdateDisplay_Init(); printf("\n\rCreated and initialized Display and UpdateDisplay"); } @@ -497,6 +507,7 @@ int main(void) { checkOSError(err); + TaskSwHook_Init(); // Create the task manager thread OSTaskCreate( From c64c8034d7ea2e1f88d9649df0faa1bbe1a4824b Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Fri, 6 Oct 2023 05:23:20 +0000 Subject: [PATCH 127/141] Removed unnecessary value assignments from the UpdateDisplay error enum. --- Apps/Inc/UpdateDisplay.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 6afb41b15..f2095da3e 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -26,12 +26,12 @@ * Error types */ typedef enum{ - UPDATEDISPLAY_ERR_NONE =0, - UPDATEDISPLAY_ERR_FIFO_PUT =1, // Error putting command in fifo - UPDATEDISPLAY_ERR_FIFO_POP =2, // Error popping command from fifo - UPDATEDISPLAY_ERR_PARSE_COMP =3, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_NO_CHANGE =4, // No change in component value - UPDATEDISPLAY_ERR_DRIVER =5 // Driver call returned an error + UPDATEDISPLAY_ERR_NONE, + UPDATEDISPLAY_ERR_FIFO_PUT, // Error putting command in fifo + UPDATEDISPLAY_ERR_FIFO_POP, // Error popping command from fifo + UPDATEDISPLAY_ERR_PARSE_COMP, // Error parsing component/val in SetComponent + UPDATEDISPLAY_ERR_NO_CHANGE, // No change in component value + UPDATEDISPLAY_ERR_DRIVER // Driver call returned an error } UpdateDisplayError_t; /** From a87b2d4b5f46ecf9e19f20b0f6d818d60634f8fd Mon Sep 17 00:00:00 2001 From: Madeleine Lee <74027612+KnockbackNemo@users.noreply.github.com> Date: Fri, 6 Oct 2023 00:24:45 -0500 Subject: [PATCH 128/141] Apply suggestions from code review Removing unused macros and correcting documentation Co-authored-by: Diya Rajon <45317290+diyarajon@users.noreply.github.com> --- Apps/Inc/Tasks.h | 2 +- Apps/Src/ReadTritium.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 39d6e3c66..62abfbf3c 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -194,7 +194,7 @@ void EmergencyContactorOpen(); * @param errorLoc the task from which the error originated. Note: should be taken out when last task pointer is integrated * @param errorCode the enum for the specific error that happened * @param errorCallback a callback function to a handler for that specific error, - * @param schedLock whether or not to lock the scheduler to ensure the error is handled immediately + * @param lockSched whether or not to lock the scheduler to ensure the error is handled immediately * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 64445d86c..0b463056e 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -7,8 +7,6 @@ #include //status limit flag masks -#define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor 6 -#define MAX_CAN_LEN 8 #define MOTOR_RESTART_THRESHOLD 3 // Number of times to restart before asserting a nonrecoverable error From af257341bd5e42e344fc00cfa03bf5bb795a6ce0 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 7 Oct 2023 20:15:54 +0000 Subject: [PATCH 129/141] Changed Display fault enum from positive to default values, added a delay in UpdateDisplay_Init since errors wouldn't be displayed unless we waited more than 215 ms before sending them. --- Apps/Src/UpdateDisplay.c | 2 ++ Drivers/Inc/Display.h | 22 +++++++++++----------- Tests/Test_FaultThread_Exceptions.c | 17 +++++------------ 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index d89aecb99..ccaa2a65f 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -85,6 +85,8 @@ UpdateDisplayError_t UpdateDisplay_Init(){ assertOSError(OS_DISPLAY_LOC, err); UpdateDisplayError_t ret = UpdateDisplay_SetPage(INFO); + OSTimeDlyHMSM(0, 0, 0, 300, OS_OPT_TIME_HMSM_STRICT, &err); // Wait >215ms so errors will show on the display + assertOSError(OS_MAIN_LOC, err); return ret; } diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index de483a48f..5b57c8f59 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -23,17 +23,17 @@ * Error types */ typedef enum{ // Currently only ERR_NONE and ERR_PARSE are used - DISPLAY_ERR_NONE = 0, - DISPLAY_ERR_PARSE =-1, // Error parsing command struct passed to Display_Send - DISPLAY_ERR_INV_INSTR =-2, // Invalid instruction passed to nextion (0x00) - DISPLAY_ERR_INV_COMP =-3, // Invalid component id passed to nextion (0x02) - DISPLAY_ERR_INV_PGID =-4, // Invalid page id passed to nextion (0x03) - DISPLAY_ERR_INV_VAR =-5, // Invalid variable name passed to nextion (0x1A) - DISPLAY_ERR_INV_VAROP =-6, // Invalid variable operation passed to nextion (0x1B) - DISPLAY_ERR_ASSIGN =-7, // Assignment failure nextion (0x1C) - DISPLAY_ERR_PARAMS =-8, // Invalid number of parameters passed to nextion (0x1E) - DISPLAY_ERR_MAX_ARGS =-9, // Command arg list exceeded MAX_ARGS elements - DISPLAY_ERR_OTHER =-10 // Other nextion display error + DISPLAY_ERR_NONE, + DISPLAY_ERR_PARSE, // Error parsing command struct passed to Display_Send + DISPLAY_ERR_INV_INSTR, // Invalid instruction passed to nextion (0x00) + DISPLAY_ERR_INV_COMP, // Invalid component id passed to nextion (0x02) + DISPLAY_ERR_INV_PGID, // Invalid page id passed to nextion (0x03) + DISPLAY_ERR_INV_VAR, // Invalid variable name passed to nextion (0x1A) + DISPLAY_ERR_INV_VAROP, // Invalid variable operation passed to nextion (0x1B) + DISPLAY_ERR_ASSIGN, // Assignment failure nextion (0x1C) + DISPLAY_ERR_PARAMS, // Invalid number of parameters passed to nextion (0x1E) + DISPLAY_ERR_MAX_ARGS, // Command arg list exceeded MAX_ARGS elements + DISPLAY_ERR_OTHER // Other nextion display error } DisplayError_t; diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 0fd2cff55..f1c62de16 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -41,8 +41,8 @@ enum { // Test menu enum }; /*** Constants ***/ -#define TEST_OPTION TEST_READTRITIUM // Decide what to test based on test menu enum -#define READTRITIUM_OPTION T_DC_BUS_OVERVOLT_ERR // The enum for the tritium error we want to test (reference error enum) +#define TEST_OPTION TEST_UPDATEDISPLAY // Decide what to test based on test menu enum +#define READTRITIUM_OPTION T_NONE // The enum for the tritium error we want to test (reference error enum) /* READTRITIUM_OPTION menu: T_HARDWARE_OVER_CURRENT_ERR = (1<<0), @@ -184,14 +184,13 @@ void Task_ManagerTask(void* arg) { case TEST_OS_ASSERT: // Test the assertOSError function using the OSErrorTask // Creates an OS error by pending on a mutex that isn't created - // Successful if it prints the OS Error code 24004 - // and doesn't print the fail message (task is stopped by asserting an error) + // Successful if it doesn't print the fail message (task is stopped by asserting an error) printf("\n\n\r=========== Testing OS assert ==========="); //Expected output: infinite while loop with no prints createOSErrorTask(); - OSTimeDlyHMSM(0, 0, 0, 500, OS_OPT_TIME_HMSM_STRICT, &err); + OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_HMSM_STRICT, &err); checkOSError(err); break; @@ -215,13 +214,6 @@ void Task_ManagerTask(void* arg) { canError.ID = MOTOR_STATUS; createReadTritium(); - //OSTimeDlyHMSM(0, 0, 10, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the display to initialize - // for (int i = 0x07; i < 0x09; i++){ - // printf("\n\rSending %x", i); - // Display_Error(OS_DISPLAY_LOC, i); - // OSTimeDlyHMSM(0, 0, 0, 104, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the display to initialize - //} - //OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for the display to initialize printf("\n\n\rNow sending: %d", tritiumError); // Sending 0 means no Tritium error CANbus_Send(canError, CAN_BLOCKING, MOTORCAN); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // Wait for ReadTritium to finish @@ -245,6 +237,7 @@ void Task_ManagerTask(void* arg) { // Tests exceptions in ReadCarCAN by creating the tasks and sending messages // Successful if charging disable and missed messages turns off contactors // And we enter a nonrecoverable fault immediately after receiving the trip message + /* Not tested on hardware due to dependencies on ReadCarCAN fix_ignition_delay branch changes */ printf("\n\n\r=========== Testing ReadCarCAN ==========="); createReadCarCAN(); From 6d674da536faac9901129202094c79105487af6e Mon Sep 17 00:00:00 2001 From: Cam0Cow Date: Sat, 7 Oct 2023 16:13:08 -0500 Subject: [PATCH 130/141] Name change --- Apps/Src/Tasks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index b37740253..941233640 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -55,7 +55,7 @@ error_code_t Error_ReadCarCAN = /*READCARCAN_ERR_NONE*/ 0; // TODO: change this error_code_t Error_ReadTritium = T_NONE; // Initialized to no error error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; -extern const PinInfo_t PINS_LOOKARR[]; // For GPIO writes. Externed from Minions Driver C file. +extern const pinInfo_t PININFO_LUT[]; // For GPIO writes. Externed from Minions Driver C file. /** * Error assertion-related functions @@ -147,7 +147,7 @@ void EmergencyContactorOpen() { BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_PRECHARGE_PIN, OFF); // Turn additional brakelight on to indicate critical error - BSP_GPIO_Write_Pin(PINS_LOOKARR[BRAKELIGHT].port, PINS_LOOKARR[BRAKELIGHT].pinMask, true); + BSP_GPIO_Write_Pin(PININFO_LUT[BRAKELIGHT].port, PININFO_LUT[BRAKELIGHT].pinMask, true); } /** From 128777d780219feafd1cbe72388c1c9fd6cdcfd4 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 14 Oct 2023 21:29:57 +0000 Subject: [PATCH 131/141] Addressed review comments- changed assertTaskError to throwTaskError, changed a bit of throwTaskError logic, removed some comments. --- Apps/Inc/Tasks.h | 2 +- Apps/Src/ReadCarCAN.c | 4 ++-- Apps/Src/ReadTritium.c | 16 +++++++-------- Apps/Src/Tasks.c | 42 ++++++++++++++++++++++++---------------- Apps/Src/UpdateDisplay.c | 6 +++--- 5 files changed, 39 insertions(+), 31 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 11eb36045..2377981c6 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -206,7 +206,7 @@ void EmergencyContactorOpen(); * @param lockSched whether or not to lock the scheduler to ensure the error is handled immediately * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ -void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); +void throwTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); /** * @brief Assert Error if OS function call fails diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index f4b96a463..db7cb476a 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -91,7 +91,7 @@ static inline void chargingDisable(void) { chargeEnable = false; // kill contactors TODO: fill in error code - assertTaskError(OS_READ_CAN_LOC, 0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); + throwTaskError(OS_READ_CAN_LOC, 0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); } // helper function to call if charging should be enabled @@ -213,7 +213,7 @@ void Task_ReadCarCAN(void *p_arg) // kill contactors and enter a nonrecoverable fault // TODO: change error code to real value - assertTaskError(OS_READ_CAN_LOC, 0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); + throwTaskError(OS_READ_CAN_LOC, 0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); } case CHARGE_ENABLE: { diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 35451dc7b..1ec795ca9 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -15,9 +15,9 @@ #define MOTOR_RESTART_THRESHOLD 3 // Number of times to restart before asserting a nonrecoverable error -tritium_error_code_t Motor_FaultBitmap = T_NONE; //initialized to no error, changed when the motor asserts an error -static float Motor_RPM = MOTOR_STOPPED; //initialized to 0, motor would be "stopped" until a motor velocity is read -static float Motor_Velocity = MOTOR_STOPPED; //initialized to 0, car would be "stopped" until a car velocity is read +tritium_error_code_t Motor_FaultBitmap = T_NONE; +static float Motor_RPM = MOTOR_STOPPED; +static float Motor_Velocity = MOTOR_STOPPED; // Function prototypes static void assertTritiumError(tritium_error_code_t motor_err); @@ -113,11 +113,11 @@ float Motor_Velocity_Get(){ //getter function for motor velocity /** * Error handler functions - * Passed as callback functions to the main assertTaskError function by assertTritiumError + * Passed as callback functions to the main throwTaskError function by assertTritiumError */ /** - * @brief A callback function to be run by the main assertTaskError function for hall sensor errors + * @brief A callback function to be run by the main throwTaskError function for hall sensor errors * restart the motor if the number of hall errors is still less than the MOTOR_RESTART_THRESHOLD. */ static inline void handler_ReadTritium_HallError(void) { @@ -142,7 +142,7 @@ static void assertTritiumError(tritium_error_code_t motor_err){ // or combination of errors includes at least one that is nonrecoverable // accidentally fall into this nonrecoverable bucket if(motor_err != T_HALL_SENSOR_ERR){ // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop - assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + throwTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; } @@ -150,12 +150,12 @@ static void assertTritiumError(tritium_error_code_t motor_err){ if(++hall_fault_cnt > MOTOR_RESTART_THRESHOLD){ // Threshold has been exceeded // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop - assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + throwTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; } // Threshold hasn't been exceeded, so assert a recoverable error with the motor restart callback function - assertTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, handler_ReadTritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); + throwTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, handler_ReadTritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); Error_ReadTritium = T_NONE; // Clear the error after handling it } \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 941233640..6fc3cf876 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -12,9 +12,9 @@ #include "Display.h" #include "Minions.h" #include "Pedals.h" -#include "ReadTritium.h" // For ReadTritium error enum -#include "ReadCarCAN.h" // For ReadCarCAN error enum -#include "UpdateDisplay.h" // For update display error enum +#include "ReadTritium.h" +#include "ReadCarCAN.h" +#include "UpdateDisplay.h" /** @@ -82,9 +82,13 @@ void _assertOSError(os_error_loc_t OS_err_loc, OS_ERR err) * @param lockSched whether or not to lock the scheduler to ensure the error is handled immediately. Only applicable for recoverable errors- nonrecoverable errors will always lock * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ -void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { +void throwTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { OS_ERR err; + if (errorCode == 0) { // Exit if there is no error + return; + } + if (lockSched == OPT_LOCK_SCHED || nonrecoverable == OPT_NONRECOV) { // Prevent other tasks from interrupting the handling of important (includes all nonrecoverable) errors OSSchedLock(&err); assertOSError(OS_TASKS_LOC, err); @@ -94,7 +98,7 @@ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t OSErrLocBitmap = errorLoc; if (nonrecoverable == OPT_NONRECOV) { - EmergencyContactorOpen(); // Apart from while loop because killing the motor is more important + EmergencyContactorOpen(); Display_Error(errorLoc, errorCode); // Needs to happen before callback so that tasks can change the screen // (ex: readCarCAN and evac screen for BPS trip) UpdateDisplay_ClearQueue(); // Clear message queue to ensure no other commands overwrite the error screen @@ -109,26 +113,30 @@ void assertTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t if (nonrecoverable == OPT_NONRECOV) { // Enter an infinite while loop while(1) { - // Print the error that caused this fault - printf("\n\rCurrent Error Location: 0x%04x", OSErrLocBitmap); - printf("\n\rCurrent Error Code: 0x%04x\n\r", errorCode); + #if DEBUG == 1 + + // Print the error that caused this fault + printf("\n\rCurrent Error Location: 0x%04x", OSErrLocBitmap); + printf("\n\rCurrent Error Code: 0x%04x\n\r", errorCode); - // Print the errors for each applications with error data - printf("\n\rAll application errors:\n\r"); - printf("Error_ReadCarCAN: 0x%04x\n\r", Error_ReadCarCAN); - printf("Error_ReadTritium: 0x%04x\n\r", Error_ReadTritium); - printf("Error_UpdateDisplay: 0x%04x\n\r", Error_UpdateDisplay); + // Print the errors for each applications with error data + printf("\n\rAll application errors:\n\r"); + printf("Error_ReadCarCAN: 0x%04x\n\r", Error_ReadCarCAN); + printf("Error_ReadTritium: 0x%04x\n\r", Error_ReadTritium); + printf("Error_UpdateDisplay: 0x%04x\n\r", Error_UpdateDisplay); - // Delay so that we're not constantly printing - for (int i = 0; i < 9999999; i++) { - } + // Delay so that we're not constantly printing + for (int i = 0; i < 9999999; i++) { + } + #endif + } } if (lockSched == OPT_LOCK_SCHED) { // Only happens on recoverable errors OSSchedUnlock(&err); // Don't err out if scheduler is still locked because of a timer callback - if (err != OS_ERR_SCHED_LOCKED && OSSchedLockNestingCtr > 1) { // But we don't plan to lock more than one level deep + if (err != OS_ERR_SCHED_LOCKED || OSSchedLockNestingCtr > 1) { // But we don't plan to lock more than one level deep assertOSError(OS_TASKS_LOC, err); } diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 5311b58b5..02508ea98 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -386,11 +386,11 @@ void Task_UpdateDisplay(void *p_arg) { /** * Error handler functions - * Passed as callback functions to the main assertTaskError function by assertUpdateDisplayError + * Passed as callback functions to the main throwTaskError function by assertUpdateDisplayError */ /** - * @brief A handler callback function run by the main assertTaskError function + * @brief A handler callback function run by the main throwTaskError function * used if we haven't reached the restart limit and encounter an error */ static void handler_UpdateDisplay_Restart() { @@ -410,7 +410,7 @@ static void handler_UpdateDisplay_Restart() { if (err == UPDATEDISPLAY_ERR_NONE) return; // No error, return // Otherwise try resetting the display using the restart callback - assertTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_Restart,OPT_NO_LOCK_SCHED, OPT_RECOV); + throwTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_Restart,OPT_NO_LOCK_SCHED, OPT_RECOV); Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; // Clear the error after handling it } From ea59cb6aec532972ee7a71ced3c9154a4aa888a8 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 14 Oct 2023 21:52:03 +0000 Subject: [PATCH 132/141] Renamed assertTaskError to throwTaskError in the test file. --- Tests/Test_FaultThread_Exceptions.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index f1c62de16..6dbd51a71 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -41,7 +41,7 @@ enum { // Test menu enum }; /*** Constants ***/ -#define TEST_OPTION TEST_UPDATEDISPLAY // Decide what to test based on test menu enum +#define TEST_OPTION TEST_READTRITIUM // Decide what to test based on test menu enum #define READTRITIUM_OPTION T_NONE // The enum for the tritium error we want to test (reference error enum) /* READTRITIUM_OPTION menu: @@ -113,13 +113,13 @@ void ExceptionTask(callback_t test_callbacks) { // Throw two recoverable errors printf("\n\n\rAsserting recoverable errors"); // Throw an arbitrary recoverable error w/o locking the scheduler - assertTaskError(OS_MAIN_LOC, 0x01, test_callbacks, OPT_NO_LOCK_SCHED, OPT_RECOV); + throwTaskError(OS_MAIN_LOC, 0x01, test_callbacks, OPT_NO_LOCK_SCHED, OPT_RECOV); // Throw an arbitrary recoverable error w/ locked scheduler - assertTaskError(OS_TASKS_LOC, 0x02, test_callbacks, OPT_LOCK_SCHED, OPT_RECOV); + throwTaskError(OS_TASKS_LOC, 0x02, test_callbacks, OPT_LOCK_SCHED, OPT_RECOV); // Throw a nonrecoverable error printf("\n\n\rAsserting a nonrecoverable error"); - assertTaskError(OS_SEND_CAN_LOC, 0x03, test_callbacks, OPT_NO_LOCK_SCHED, OPT_NONRECOV); // Should still lock sched b/c nonrecoverable + throwTaskError(OS_SEND_CAN_LOC, 0x03, test_callbacks, OPT_NO_LOCK_SCHED, OPT_NONRECOV); // Should still lock sched b/c nonrecoverable printf("\n\rTest failed: locked nonrecoverable error did not immediately result in an unrecoverable fault"); // Shouldn't print From 441745a19b91bb88b7db852d7c2d6d389251f436 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 14 Oct 2023 22:03:50 +0000 Subject: [PATCH 133/141] Changed a print statement so that it still makes sense when sending an error of NONE. --- Tests/Test_FaultThread_Exceptions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index 6dbd51a71..a3ed5dac3 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -42,7 +42,7 @@ enum { // Test menu enum /*** Constants ***/ #define TEST_OPTION TEST_READTRITIUM // Decide what to test based on test menu enum -#define READTRITIUM_OPTION T_NONE // The enum for the tritium error we want to test (reference error enum) +#define READTRITIUM_OPTION T_HALL_SENSOR_ERR // The enum for the tritium error we want to test (reference error enum) /* READTRITIUM_OPTION menu: T_HARDWARE_OVER_CURRENT_ERR = (1<<0), @@ -225,7 +225,7 @@ void Task_ManagerTask(void* arg) { } // Fail message: this should not be reached because we should hit an unrecoverable fault first - printf("\n\rTest failed: error assertion did not lead to an unrecoverable fault"); + printf("\n\rError assertion did not lead to an unrecoverable fault"); OSTaskDel(&ReadTritium_TCB, &err); checkOSError(err); From 27e872501a2666b29d4aac2b12f4e02347b2466d Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 21 Oct 2023 20:37:21 +0000 Subject: [PATCH 134/141] Removed MOTOR_STOPPED macro. --- Apps/Inc/ReadTritium.h | 1 - Apps/Src/ReadTritium.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index f3000e757..f14b20266 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -6,7 +6,6 @@ #include "os.h" #include "common.h" #include "Tasks.h" -#define MOTOR_STOPPED 0 /** * Motor Error States diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 1ec795ca9..fd2331271 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -16,8 +16,8 @@ tritium_error_code_t Motor_FaultBitmap = T_NONE; -static float Motor_RPM = MOTOR_STOPPED; -static float Motor_Velocity = MOTOR_STOPPED; +static float Motor_RPM = 0; +static float Motor_Velocity = 0; // Function prototypes static void assertTritiumError(tritium_error_code_t motor_err); From 657cf3b03e0964a30d43f96a2d304f8870e696a9 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 21 Oct 2023 20:45:18 +0000 Subject: [PATCH 135/141] Removed the ERR_NO_CHANGE in UpdateDisplay and all checks for if things haven't changed since we weren't ever checking them anyways. --- Apps/Inc/UpdateDisplay.h | 1 - Apps/Src/UpdateDisplay.c | 66 ++++------------------------------------ 2 files changed, 6 insertions(+), 61 deletions(-) diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 4157f5949..7afb0a1b4 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -31,7 +31,6 @@ typedef enum{ UPDATEDISPLAY_ERR_FIFO_PUT, // Error putting command in fifo UPDATEDISPLAY_ERR_FIFO_POP, // Error popping command from fifo UPDATEDISPLAY_ERR_PARSE_COMP, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_NO_CHANGE, // No change in component value UPDATEDISPLAY_ERR_DRIVER // Driver call returned an error } UpdateDisplayError_t; diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 02508ea98..ce27c705a 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -240,126 +240,72 @@ UpdateDisplayError_t UpdateDisplay_SetPage(Page_t page){ /* WRAPPERS */ UpdateDisplayError_t UpdateDisplay_SetSOC(uint8_t percent){ // Integer percentage from 0-100 - static uint8_t lastPercent = 0; - if(percent == lastPercent){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SOC, percent); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - - if(ret == UPDATEDISPLAY_ERR_NONE) lastPercent = percent; return ret; } UpdateDisplayError_t UpdateDisplay_SetSBPV(uint32_t mv){ - static uint32_t lastMv = 0; - if(mv == lastMv){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SUPP_BATT, mv/100); + + UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SUPP_BATT, mv/100); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - - if(ret == UPDATEDISPLAY_ERR_NONE) lastMv = mv; return ret; } UpdateDisplayError_t UpdateDisplay_SetVelocity(uint32_t mphTenths){ - static uint32_t lastMphTenths = 0; - if(mphTenths == lastMphTenths){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(VELOCITY, mphTenths); - if(ret == UPDATEDISPLAY_ERR_NONE) lastMphTenths = mphTenths; + UpdateDisplayError_t ret = UpdateDisplay_SetComponent(VELOCITY, mphTenths); return ret; } UpdateDisplayError_t UpdateDisplay_SetAccel(uint8_t percent){ - static uint8_t lastPercentAccel = 0; - if(percent == lastPercentAccel){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ACCEL_METER, percent); - - if(ret == UPDATEDISPLAY_ERR_NONE) lastPercentAccel = percent; return ret; } UpdateDisplayError_t UpdateDisplay_SetArray(bool state){ - static bool lastState = false; - if(state == lastState){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ARRAY, (state)?1:0); - - if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; } UpdateDisplayError_t UpdateDisplay_SetMotor(bool state){ - static bool lastState = false; - if(state == lastState){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(MOTOR, (state)?1:0); - - if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; } UpdateDisplayError_t UpdateDisplay_SetGear(TriState_t gear){ - static TriState_t lastGear = STATE_0; - if(gear == lastGear){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(GEAR, (uint32_t)gear); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - - if(ret == UPDATEDISPLAY_ERR_NONE) lastGear = gear; return ret; } UpdateDisplayError_t UpdateDisplay_SetRegenState(TriState_t state){ - static TriState_t lastState = STATE_0; - if(state == lastState){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } UpdateDisplayError_t ret = UpdateDisplay_SetComponent(REGEN_ST, (uint32_t)state); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; ret = UpdateDisplay_Refresh(); - - if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; return ret; } UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ - static TriState_t lastState = STATE_0; - if(state == lastState){ - return UPDATEDISPLAY_ERR_NO_CHANGE; - } - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(CRUISE_ST, (uint32_t)state); + UpdateDisplayError_t ret = UpdateDisplay_SetComponent(CRUISE_ST, (uint32_t)state); if(ret != UPDATEDISPLAY_ERR_NONE) return ret; - + ret = UpdateDisplay_Refresh(); - - if(ret == UPDATEDISPLAY_ERR_NONE) lastState = state; - return ret; + return ret; } /** From a6817ec1538f9a742e658f0276ae4b984a59d905 Mon Sep 17 00:00:00 2001 From: Madeleine Lee <74027612+KnockbackNemo@users.noreply.github.com> Date: Sat, 21 Oct 2023 16:06:23 -0500 Subject: [PATCH 136/141] Update Tests/Test_FaultThread_Exceptions.c Accepted deletion of unnecessary tab Co-authored-by: Ishan Deshpande --- Tests/Test_FaultThread_Exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index a3ed5dac3..e9b275c06 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -181,7 +181,7 @@ void Task_ManagerTask(void* arg) { checkOSError(err); break; - case TEST_OS_ASSERT: + case TEST_OS_ASSERT: // Test the assertOSError function using the OSErrorTask // Creates an OS error by pending on a mutex that isn't created // Successful if it doesn't print the fail message (task is stopped by asserting an error) From a51a0e05f9b224aa2ccdd20d5e5033fd88334806 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 21 Oct 2023 21:30:01 +0000 Subject: [PATCH 137/141] Moved ReadCarCAN Display_Evac into a callback for the BPSTrip message, changed the recoverability option to nonrecoverable. --- Apps/Src/ReadCarCAN.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index db7cb476a..c4c26e5c1 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -74,7 +74,7 @@ static void updateSaturation(int8_t chargeMessage){ chargeMsgSaturation = newSaturation; } -// exception struct callback for charging disable, kills contactors and turns of display +// exception struct callback for charging disable, kills contactors and turns off display static void callback_disableContactors(void){ // Kill contactors Contactors_Set(ARRAY_CONTACTOR, OFF, true); @@ -84,6 +84,14 @@ static void callback_disableContactors(void){ UpdateDisplay_SetArray(false); } +// exception callback for BPS trip. Kills contactors and displays evac screen. +static void callback_BPSTrip(void){ + + callback_disableContactors(); + Display_Evac(SOC, SBPV); + +} + // helper function to disable charging // Turns off contactors by signaling fault state static inline void chargingDisable(void) { @@ -209,11 +217,9 @@ void Task_ReadCarCAN(void *p_arg) case BPS_TRIP: { // BPS has a fault and we need to enter fault state (probably) - Display_Evac(SOC, SBPV); // Display evacuation message - // kill contactors and enter a nonrecoverable fault // TODO: change error code to real value - throwTaskError(OS_READ_CAN_LOC, 0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); + throwTaskError(OS_READ_CAN_LOC, 0, callback_BPSTrip, OPT_LOCK_SCHED, OPT_NONRECOV); } case CHARGE_ENABLE: { From 2b983c830ca7e41bb26ad37f8d4fa25a969f499c Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 21 Oct 2023 22:07:04 +0000 Subject: [PATCH 138/141] Fixed Doxygen comments. --- Apps/Inc/ReadTritium.h | 9 ++++++++- Apps/Inc/UpdateDisplay.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index f14b20266..c4882e374 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -1,4 +1,11 @@ -/* Copyright (c) 2021 UT Longhorn Racing Solar */ +/* Copyright (c) 2021 UT Longhorn Racing Solar + * @file ReadTritium.h + * @brief + * + * @defgroup ReadTritium + * @addtogroup ReadTritium + * @{ + */ #ifndef __READ_TRITIUM_H #define __READ_TRITIUM_H diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 7afb0a1b4..b2cfc66bf 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -138,3 +138,4 @@ UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state); void UpdateDisplay_ClearQueue(void); #endif +/* @} */ \ No newline at end of file From eb1bf910498a50bcb71366b0c2bff9a0f10509cf Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 23 Oct 2023 20:49:57 +0000 Subject: [PATCH 139/141] Removed references to OS_LOC in new faultstate code. --- Apps/Inc/Tasks.h | 14 +------------- Apps/Src/ReadCarCAN.c | 10 +++++----- Apps/Src/ReadTritium.c | 6 +++--- Apps/Src/Tasks.c | 10 ++-------- Apps/Src/UpdateDisplay.c | 2 +- Tests/Test_FaultThread_Exceptions.c | 6 +++--- 6 files changed, 15 insertions(+), 33 deletions(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 2377981c6..9bce862f0 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -119,12 +119,6 @@ extern OS_Q CANBus_MsgQ; */ void TaskSwHook_Init(void); - -/** - * Global Variables - */ - - /** * OS Error States * @@ -164,11 +158,6 @@ typedef struct { extern task_trace_t PrevTasks; -/** - * Error variables - */ -extern os_error_loc_t OSErrLocBitmap; - // Store error codes that are set in task error assertion functions extern error_code_t Error_ReadTritium; extern error_code_t Error_ReadCarCAN; @@ -200,13 +189,12 @@ void EmergencyContactorOpen(); * @brief Assert a task error by setting the location variable and optionally locking the scheduler, * displaying a fault screen (if nonrecoverable), jumping to a callback function, and entering an infinite loop. * Called by task-specific error-assertion functions that are also responsible for setting the error variable. - * @param errorLoc the task from which the error originated. Note: should be taken out when last task pointer is integrated * @param errorCode the enum for the specific error that happened * @param errorCallback a callback function to a handler for that specific error, * @param lockSched whether or not to lock the scheduler to ensure the error is handled immediately * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ -void throwTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); +void throwTaskError(error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); /** * @brief Assert Error if OS function call fails diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index c4c26e5c1..586e047b0 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -99,7 +99,7 @@ static inline void chargingDisable(void) { chargeEnable = false; // kill contactors TODO: fill in error code - throwTaskError(OS_READ_CAN_LOC, 0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); + throwTaskError(0, callback_disableContactors, OPT_LOCK_SCHED, OPT_RECOV); } // helper function to call if charging should be enabled @@ -132,7 +132,7 @@ static inline void chargingEnable(void) { OSMutexPost(&arrayRestartMutex, OS_OPT_NONE, &err); - assertOSError(OS_READ_CAN_LOC,err); + assertOSError(OS_READ_CAN_LOC, err); } /** @@ -170,7 +170,7 @@ void Task_ReadCarCAN(void *p_arg) CANDATA_t dataBuf; OSMutexCreate(&arrayRestartMutex, "array restart mutex", &err); - assertOSError(OS_READ_CAN_LOC,err); + assertOSError(OS_READ_CAN_LOC, err); // Create the CAN Watchdog (periodic) timer, which disconnects the array and disables regenerative braking @@ -197,7 +197,7 @@ void Task_ReadCarCAN(void *p_arg) NULL, &err ); - assertOSError(OS_READ_CAN_LOC, err); + assertOSError(OS_READ_CAN_LOC,err); //Start CAN Watchdog timer OSTmrStart(&canWatchTimer, &err); @@ -219,7 +219,7 @@ void Task_ReadCarCAN(void *p_arg) // kill contactors and enter a nonrecoverable fault // TODO: change error code to real value - throwTaskError(OS_READ_CAN_LOC, 0, callback_BPSTrip, OPT_LOCK_SCHED, OPT_NONRECOV); + throwTaskError(0, callback_BPSTrip, OPT_LOCK_SCHED, OPT_NONRECOV); } case CHARGE_ENABLE: { diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index fd2331271..cc7438760 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -142,7 +142,7 @@ static void assertTritiumError(tritium_error_code_t motor_err){ // or combination of errors includes at least one that is nonrecoverable // accidentally fall into this nonrecoverable bucket if(motor_err != T_HALL_SENSOR_ERR){ // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop - throwTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + throwTaskError(Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; } @@ -150,12 +150,12 @@ static void assertTritiumError(tritium_error_code_t motor_err){ if(++hall_fault_cnt > MOTOR_RESTART_THRESHOLD){ // Threshold has been exceeded // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop - throwTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); + throwTaskError(Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); return; } // Threshold hasn't been exceeded, so assert a recoverable error with the motor restart callback function - throwTaskError(OS_READ_TRITIUM_LOC, Error_ReadTritium, handler_ReadTritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); + throwTaskError(Error_ReadTritium, handler_ReadTritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); Error_ReadTritium = T_NONE; // Clear the error after handling it } \ No newline at end of file diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 6fc3cf876..6e04aa578 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -76,13 +76,12 @@ void _assertOSError(os_error_loc_t OS_err_loc, OS_ERR err) * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, * and jumping to the error's specified callback function. * Called by task-specific error-assertion functions that are also responsible for setting the error variable. - * @param errorLoc the task from which the error originated. Note: should be taken out when last task pointer is integrated * @param errorCode the enum for the specific error that happened * @param errorCallback a callback function to a handler for that specific error, * @param lockSched whether or not to lock the scheduler to ensure the error is handled immediately. Only applicable for recoverable errors- nonrecoverable errors will always lock * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop */ -void throwTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { +void throwTaskError(error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { OS_ERR err; if (errorCode == 0) { // Exit if there is no error @@ -94,12 +93,9 @@ void throwTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t assertOSError(OS_TASKS_LOC, err); } - // Set the location error variable - OSErrLocBitmap = errorLoc; - if (nonrecoverable == OPT_NONRECOV) { EmergencyContactorOpen(); - Display_Error(errorLoc, errorCode); // Needs to happen before callback so that tasks can change the screen + Display_Error(errorCode); // Needs to happen before callback so that tasks can change the screen // (ex: readCarCAN and evac screen for BPS trip) UpdateDisplay_ClearQueue(); // Clear message queue to ensure no other commands overwrite the error screen } @@ -141,8 +137,6 @@ void throwTaskError(os_error_loc_t errorLoc, error_code_t errorCode, callback_t } } - - OSErrLocBitmap = OS_NONE_LOC; // Clear the location error variable once handled } /** diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index ce27c705a..860d0494f 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -356,7 +356,7 @@ static void handler_UpdateDisplay_Restart() { if (err == UPDATEDISPLAY_ERR_NONE) return; // No error, return // Otherwise try resetting the display using the restart callback - throwTaskError(OS_DISPLAY_LOC, Error_UpdateDisplay, handler_UpdateDisplay_Restart,OPT_NO_LOCK_SCHED, OPT_RECOV); + throwTaskError(Error_UpdateDisplay, handler_UpdateDisplay_Restart,OPT_NO_LOCK_SCHED, OPT_RECOV); Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; // Clear the error after handling it } diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index e9b275c06..cd3cf5c51 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -113,13 +113,13 @@ void ExceptionTask(callback_t test_callbacks) { // Throw two recoverable errors printf("\n\n\rAsserting recoverable errors"); // Throw an arbitrary recoverable error w/o locking the scheduler - throwTaskError(OS_MAIN_LOC, 0x01, test_callbacks, OPT_NO_LOCK_SCHED, OPT_RECOV); + throwTaskError(0x01, test_callbacks, OPT_NO_LOCK_SCHED, OPT_RECOV); // Throw an arbitrary recoverable error w/ locked scheduler - throwTaskError(OS_TASKS_LOC, 0x02, test_callbacks, OPT_LOCK_SCHED, OPT_RECOV); + throwTaskError(0x02, test_callbacks, OPT_LOCK_SCHED, OPT_RECOV); // Throw a nonrecoverable error printf("\n\n\rAsserting a nonrecoverable error"); - throwTaskError(OS_SEND_CAN_LOC, 0x03, test_callbacks, OPT_NO_LOCK_SCHED, OPT_NONRECOV); // Should still lock sched b/c nonrecoverable + throwTaskError(0x03, test_callbacks, OPT_NO_LOCK_SCHED, OPT_NONRECOV); // Should still lock sched b/c nonrecoverable printf("\n\rTest failed: locked nonrecoverable error did not immediately result in an unrecoverable fault"); // Shouldn't print From 084a687f14025c437bc205fc46ac0aa8c748d819 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 23 Oct 2023 21:06:44 +0000 Subject: [PATCH 140/141] Removed one more reference to OS LOC. --- Tests/Test_FaultThread_Exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Test_FaultThread_Exceptions.c b/Tests/Test_FaultThread_Exceptions.c index cd3cf5c51..0c1779696 100644 --- a/Tests/Test_FaultThread_Exceptions.c +++ b/Tests/Test_FaultThread_Exceptions.c @@ -136,7 +136,7 @@ void OSErrorTask(void* arg) { printf("\n\rasserting an OS error"); OSMutexPend(&testMut, 0, OS_OPT_PEND_NON_BLOCKING, &ts, &test_err); - assertOSError(OS_MAIN_LOC, test_err); + assertOSError(test_err); printf("\n\rassertOSError test failed: assertion did not immediately result in an unrecoverable fault"); OSTaskDel(NULL, &err); // Self-delete task once finished From fc5e6b21b94f1a4f1569cf21add3b15931d8d1eb Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 24 Oct 2023 04:29:51 +0000 Subject: [PATCH 141/141] Replaced accidentally-deleted Doxygen comment. --- Apps/Inc/ReadTritium.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index c4882e374..72697e756 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -37,3 +37,6 @@ float Motor_RPM_Get(); float Motor_Velocity_Get(); #endif + + +/* @} */