diff --git a/src/mcp2515.cpp b/src/mcp2515.cpp index c1a7ace..d9f7c1e 100755 --- a/src/mcp2515.cpp +++ b/src/mcp2515.cpp @@ -36,9 +36,9 @@ SPISettings mcpSPISettings(8000000, MSBFIRST, SPI_MODE0); -static TaskHandle_t intDelegateTask = NULL; - -QueueHandle_t callbackQueueM15; +DRAM_ATTR TaskHandle_t intDelegateTask = NULL; +QueueHandle_t callbackQueueM15; +TaskHandle_t taskHandleReset = NULL; void MCP_INTHandler() { BaseType_t xHigherPriorityTaskWoken = pdFALSE; @@ -81,6 +81,20 @@ void task_MCPInt15( void *pvParameters ) } } +//checks every 2 seconds to see if the chip is in error state, and reset it if so. +void task_ResetWatcher(void *pvParameters) +{ + MCP2515* mcpCan = (MCP2515*)pvParameters; + const TickType_t xDelay = 2000 / portTICK_PERIOD_MS; + + while (1) { + vTaskDelay(xDelay); + if(mcpCan->isInErrorState()) { + mcpCan->resetErrors(); + } + } +} + void MCP2515::sendCallback(CAN_FRAME *frame) { //frame buffer @@ -131,8 +145,9 @@ void MCP2515::initializeResources() callbackQueueM15 = xQueueCreate(16, sizeof(CAN_FRAME)); //func desc stack, params, priority, handle to task, core to pin to - xTaskCreatePinnedToCore(&task_MCP15, "CAN_RX_M15", 4096, this, 3, NULL, 0); - xTaskCreatePinnedToCore(&task_MCPInt15, "CAN_INT_M15", 4096, this, 10, &intDelegateTask, 0); + xTaskCreatePinnedToCore(&task_MCP15, "CAN_RX_M15", 4096, this, 8, NULL, 0); + xTaskCreatePinnedToCore(&task_MCPInt15, "CAN_INT_M15", 4096, this, 19, &intDelegateTask, 0); + xTaskCreatePinnedToCore(&task_ResetWatcher, "CAN_RSTWATCH_M15", 1536, this, 7, &taskHandleReset, 0); initializedResources = true; } @@ -1000,3 +1015,19 @@ void MCP2515::handleFrameDispatch(CAN_FRAME *frame, int filterHit) //if none of the callback types caught this frame then queue it in the buffer xQueueSendFromISR(rxQueue, frame, NULL); } + +bool MCP2515::isInErrorState() { + byte errorRegisterContents = Read(EFLG); + if (errorRegisterContents & EFLG_ERRORMASK) { + // Serial.print("MCP2515 is in error state. Register EFLG contains "); + // Serial.println(errorRegisterContents); + return true; + } else { + return false; + } +} + +void MCP2515::resetErrors() { + BitModify(CANINTF, 0xFF, 0); // acknowledge any interrupts + BitModify(EFLG, RX1OVR | RX0OVR, 0); // clear the error flags +} diff --git a/src/mcp2515.h b/src/mcp2515.h index 3fac6c9..42058d6 100755 --- a/src/mcp2515.h +++ b/src/mcp2515.h @@ -91,6 +91,8 @@ class MCP2515 : public CAN_COMMON void GetRXMask(uint8_t mask, uint32_t &filterVal); void sendCallback(CAN_FRAME *frame); void setBuffer0RolloverBUKT(bool enable); + bool isInErrorState(); + void resetErrors(); void InitFilters(bool permissive); void intHandler(); diff --git a/src/mcp2515_defs.h b/src/mcp2515_defs.h index d8ab361..e1ae94a 100755 --- a/src/mcp2515_defs.h +++ b/src/mcp2515_defs.h @@ -60,6 +60,16 @@ #define ERRIF 0x20 #define WAKIF 0x40 #define MERRF 0x80 +// EFLG +#define EFLG_ERRORMASK 0xF8 // the first 5 flags (below) are error, the last 3 are warn +#define RX1OVR 0x80 +#define RX0OVR 0x40 +#define TXBO 0x20 +#define TXEP 0x10 +#define RXEP 0x08 +#define TXWAR 0x04 +#define RXWAR 0x02 +#define EWARN 0x01 // Configuration Registers #define CANSTAT 0x0E