diff --git a/lib/nmea2000esp32/ESP32_CAN_def.h b/lib/nmea2000esp32/ESP32_CAN_def.h deleted file mode 100644 index 98eede4..0000000 --- a/lib/nmea2000esp32/ESP32_CAN_def.h +++ /dev/null @@ -1,291 +0,0 @@ -/** - * @section License - * - * The MIT License (MIT) - * - * Copyright (c) 2017, Thomas Barth, barth-dev.de - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __DRIVERS_CAN_REGDEF_H_ -#define __DRIVERS_CAN_REGDEF_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - CAN_SPEED_100KBPS=100, /**< \brief CAN Node runs at 100kBit/s. */ - CAN_SPEED_125KBPS=125, /**< \brief CAN Node runs at 125kBit/s. */ - CAN_SPEED_250KBPS=250, /**< \brief CAN Node runs at 250kBit/s. */ - CAN_SPEED_500KBPS=500, /**< \brief CAN Node runs at 500kBit/s. */ - CAN_SPEED_800KBPS=800, /**< \brief CAN Node runs at 800kBit/s. */ - CAN_SPEED_1000KBPS=1000 /**< \brief CAN Node runs at 1000kBit/s. */ -}CAN_speed_t; - -/** - * \brief CAN frame type (standard/extended) - */ -typedef enum { - CAN_frame_std=0, /**< Standard frame, using 11 bit identifer. */ - CAN_frame_ext=1 /**< Extended frame, using 29 bit identifer. */ -}CAN_frame_format_t; - -/** - * \brief CAN RTR - */ -typedef enum { - CAN_no_RTR=0, /**< No RTR frame. */ - CAN_RTR=1 /**< RTR frame. */ -}CAN_RTR_t; - -/** \brief Frame information record type */ -typedef union{uint32_t U; /**< \brief Unsigned access */ - struct { - uint8_t DLC:4; /**< \brief [3:0] DLC, Data length container */ - unsigned int unknown_2:2; /**< \brief \internal unknown */ - CAN_RTR_t RTR:1; /**< \brief [6:6] RTR, Remote Transmission Request */ - CAN_frame_format_t FF:1; /**< \brief [7:7] Frame Format, see# CAN_frame_format_t*/ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; -} CAN_FIR_t; - -/** \brief Start address of CAN registers */ -#define MODULE_CAN ((volatile CAN_Module_t *)0x3ff6b000) - -/** \brief Get standard message ID */ -#define _CAN_GET_STD_ID (((uint32_t)MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[0] << 3) | \ - (MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[1] >> 5)) - -/** \brief Get extended message ID */ -#define _CAN_GET_EXT_ID (((uint32_t)MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[0] << 21) | \ - (MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[1] << 13) | \ - (MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[2] << 5) | \ - (MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[3] >> 3 )) - -/** \brief Set standard message ID */ -#define _CAN_SET_STD_ID(x) MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[0] = ((x) >> 3); \ - MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.STD.ID[1] = ((x) << 5); - -/** \brief Set extended message ID */ -#define _CAN_SET_EXT_ID(x) MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[0] = ((x) >> 21); \ - MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[1] = ((x) >> 13); \ - MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[2] = ((x) >> 5); \ - MODULE_CAN->MBX_CTRL.FCTRL.TX_RX.EXT.ID[3] = ((x) << 3); \ - -/** \brief Interrupt status register */ -typedef enum { - __CAN_IRQ_RX= BIT(0), /**< \brief RX Interrupt */ - __CAN_IRQ_TX= BIT(1), /**< \brief TX Interrupt */ - __CAN_IRQ_ERR= BIT(2), /**< \brief Error Interrupt */ - __CAN_IRQ_DATA_OVERRUN= BIT(3), /**< \brief Date Overrun Interrupt */ - __CAN_IRQ_WAKEUP= BIT(4), /**< \brief Wakeup Interrupt */ - __CAN_IRQ_ERR_PASSIVE= BIT(5), /**< \brief Passive Error Interrupt */ - __CAN_IRQ_ARB_LOST= BIT(6), /**< \brief Arbitration lost interrupt */ - __CAN_IRQ_BUS_ERR= BIT(7), /**< \brief Bus error Interrupt */ -}__CAN_IRQ_t; - - -/** \brief OCMODE options. */ -typedef enum { - __CAN_OC_BOM= 0b00, /**< \brief bi-phase output mode */ - __CAN_OC_TOM= 0b01, /**< \brief test output mode */ - __CAN_OC_NOM= 0b10, /**< \brief normal output mode */ - __CAN_OC_COM= 0b11, /**< \brief clock output mode */ -}__CAN_OCMODE_t; - - -/** - * CAN controller (SJA1000). - */ -typedef struct { - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int RM:1; /**< \brief MOD.0 Reset Mode */ - unsigned int LOM:1; /**< \brief MOD.1 Listen Only Mode */ - unsigned int STM:1; /**< \brief MOD.2 Self Test Mode */ - unsigned int AFM:1; /**< \brief MOD.3 Acceptance Filter Mode */ - unsigned int SM:1; /**< \brief MOD.4 Sleep Mode */ - unsigned int reserved_27:27; /**< \brief \internal Reserved */ - } B; - } MOD; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int TR:1; /**< \brief CMR.0 Transmission Request */ - unsigned int AT:1; /**< \brief CMR.1 Abort Transmission */ - unsigned int RRB:1; /**< \brief CMR.2 Release Receive Buffer */ - unsigned int CDO:1; /**< \brief CMR.3 Clear Data Overrun */ - unsigned int GTS:1; /**< \brief CMR.4 Go To Sleep */ - unsigned int reserved_27:27; /**< \brief \internal Reserved */ - } B; - } CMR; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int RBS:1; /**< \brief SR.0 Receive Buffer Status */ - unsigned int DOS:1; /**< \brief SR.1 Data Overrun Status */ - unsigned int TBS:1; /**< \brief SR.2 Transmit Buffer Status */ - unsigned int TCS:1; /**< \brief SR.3 Transmission Complete Status */ - unsigned int RS:1; /**< \brief SR.4 Receive Status */ - unsigned int TS:1; /**< \brief SR.5 Transmit Status */ - unsigned int ES:1; /**< \brief SR.6 Error Status */ - unsigned int BS:1; /**< \brief SR.7 Bus Status */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } SR; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int RI:1; /**< \brief IR.0 Receive Interrupt */ - unsigned int TI:1; /**< \brief IR.1 Transmit Interrupt */ - unsigned int EI:1; /**< \brief IR.2 Error Interrupt */ - unsigned int DOI:1; /**< \brief IR.3 Data Overrun Interrupt */ - unsigned int WUI:1; /**< \brief IR.4 Wake-Up Interrupt */ - unsigned int EPI:1; /**< \brief IR.5 Error Passive Interrupt */ - unsigned int ALI:1; /**< \brief IR.6 Arbitration Lost Interrupt */ - unsigned int BEI:1; /**< \brief IR.7 Bus Error Interrupt */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } IR; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int RIE:1; /**< \brief IER.0 Receive Interrupt Enable */ - unsigned int TIE:1; /**< \brief IER.1 Transmit Interrupt Enable */ - unsigned int EIE:1; /**< \brief IER.2 Error Interrupt Enable */ - unsigned int DOIE:1; /**< \brief IER.3 Data Overrun Interrupt Enable */ - unsigned int WUIE:1; /**< \brief IER.4 Wake-Up Interrupt Enable */ - unsigned int EPIE:1; /**< \brief IER.5 Error Passive Interrupt Enable */ - unsigned int ALIE:1; /**< \brief IER.6 Arbitration Lost Interrupt Enable */ - unsigned int BEIE:1; /**< \brief IER.7 Bus Error Interrupt Enable */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } IER; - uint32_t RESERVED0; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int BRP:6; /**< \brief BTR0[5:0] Baud Rate Prescaler */ - unsigned int SJW:2; /**< \brief BTR0[7:6] Synchronization Jump Width*/ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } BTR0; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int TSEG1:4; /**< \brief BTR1[3:0] Timing Segment 1 */ - unsigned int TSEG2:3; /**< \brief BTR1[6:4] Timing Segment 2*/ - unsigned int SAM:1; /**< \brief BTR1.7 Sampling*/ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } BTR1; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int OCMODE:2; /**< \brief OCR[1:0] Output Control Mode, see # */ - unsigned int OCPOL0:1; /**< \brief OCR.2 Output Control Polarity 0 */ - unsigned int OCTN0:1; /**< \brief OCR.3 Output Control Transistor N0 */ - unsigned int OCTP0:1; /**< \brief OCR.4 Output Control Transistor P0 */ - unsigned int OCPOL1:1; /**< \brief OCR.5 Output Control Polarity 1 */ - unsigned int OCTN1:1; /**< \brief OCR.6 Output Control Transistor N1 */ - unsigned int OCTP1:1; /**< \brief OCR.7 Output Control Transistor P1 */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } OCR; - uint32_t RESERVED1[2]; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int ALC:8; /**< \brief ALC[7:0] Arbitration Lost Capture */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } ALC; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int ECC:8; /**< \brief ECC[7:0] Error Code Capture */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } ECC; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int EWLR:8; /**< \brief EWLR[7:0] Error Warning Limit */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } EWLR; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int RXERR:8; /**< \brief RXERR[7:0] Receive Error Counter */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } RXERR; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int TXERR:8; /**< \brief TXERR[7:0] Transmit Error Counter */ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } TXERR; - - union { - struct { - uint32_t CODE[4]; /**< \brief Acceptance Message ID */ - uint32_t MASK[4]; /**< \brief Acceptance Mask */ - uint32_t RESERVED2[5]; - } ACC; /**< \brief Acceptance filtering */ - struct { - CAN_FIR_t FIR; /**< \brief Frame information record */ - union{ - struct { - uint32_t ID[2]; /**< \brief Standard frame message-ID*/ - uint32_t data[8]; /**< \brief Standard frame payload */ - uint32_t reserved[2]; - } STD; /**< \brief Standard frame format */ - struct { - uint32_t ID[4]; /**< \brief Extended frame message-ID*/ - uint32_t data[8]; /**< \brief Extended frame payload */ - } EXT; /**< \brief Extended frame format */ - }TX_RX; /**< \brief RX/TX interface */ - }FCTRL; /**< \brief Function control regs */ - } MBX_CTRL; /**< \brief Mailbox control */ - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int RMC:8; /**< \brief RMC[7:0] RX Message Counter */ - unsigned int reserved_24:24; /**< \brief \internal Reserved Enable */ - } B; - } RMC; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int RBSA:8; /**< \brief RBSA[7:0] RX Buffer Start Address */ - unsigned int reserved_24:24; /**< \brief \internal Reserved Enable */ - } B; - } RBSA; - union{uint32_t U; /**< \brief Unsigned access */ - struct { - unsigned int COD:3; /**< \brief CDR[2:0] CLKOUT frequency selector based of fOSC*/ - unsigned int COFF:1; /**< \brief CDR.3 CLKOUT off*/ - unsigned int reserved_1:1; /**< \brief \internal Reserved */ - unsigned int RXINTEN:1; /**< \brief CDR.5 This bit allows the TX1 output to be used as a dedicated receive interrupt output*/ - unsigned int CBP:1; /**< \brief CDR.6 allows to bypass the CAN input comparator and is only possible in reset mode.*/ - unsigned int CAN_M:1; /**< \brief CDR.7 If CDR.7 is at logic 0 the CAN controller operates in BasicCAN mode. If set to logic 1 the CAN controller operates in PeliCAN mode. Write access is only possible in reset mode*/ - unsigned int reserved_24:24; /**< \brief \internal Reserved */ - } B; - } CDR; - uint32_t IRAM[2]; -}CAN_Module_t; - -#ifdef __cplusplus -} -#endif - -#endif /* __DRIVERS_CAN_REGDEF_H_ */ diff --git a/lib/nmea2000esp32/NMEA2000_esp32.cpp b/lib/nmea2000esp32/NMEA2000_esp32.cpp deleted file mode 100644 index 24377f9..0000000 --- a/lib/nmea2000esp32/NMEA2000_esp32.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* -NMEA2000_esp32.cpp - -Copyright (c) 2015-2020 Timo Lappalainen, Kave Oy, www.kave.fi - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Inherited NMEA2000 object for ESP32 modules. See also NMEA2000 library. - -Thanks to Thomas Barth, barth-dev.de, who has written ESP32 CAN code. To avoid extra -libraries, I implemented his code directly to the NMEA2000_esp32 to avoid extra -can.h library, which may cause even naming problem. -*/ - -#include "driver/periph_ctrl.h" - -#include "soc/dport_reg.h" -#include "NMEA2000_esp32.h" - -//time to reinit CAN bus if the queue is full for that time -#define SEND_CANCEL_TIME 2000 -//reinit CAN bis if nothing send/received within this time -#define RECEIVE_REINIT_TIME 60000 - -bool tNMEA2000_esp32::CanInUse=false; -tNMEA2000_esp32 *pNMEA2000_esp32=0; - -void ESP32Can1Interrupt(void *); - -#define ECDEBUG(fmt,args...) if(debugStream){debugStream->printf(fmt, ## args);} - -//***************************************************************************** -tNMEA2000_esp32::tNMEA2000_esp32(gpio_num_t _TxPin, - gpio_num_t _RxPin, - Print *dbg) : - tNMEA2000(), IsOpen(false), - speed(CAN_SPEED_250KBPS), TxPin(_TxPin), RxPin(_RxPin), - RxQueue(NULL), TxQueue(NULL) { - debugStream=dbg; -} -//***************************************************************************** -bool tNMEA2000_esp32::CANSendFrame(unsigned long id, unsigned char len, const unsigned char *buf, bool /*wait_sent*/) { - tCANFrame frame; - unsigned long now=millis(); - if ( uxQueueSpacesAvailable(TxQueue)==0 ) { - if (lastSend && (lastSend + SEND_CANCEL_TIME) < now){ - ECDEBUG("CanSendFrame Aborting and emptying queue\n"); - while (xQueueReceive(TxQueue,&frame,0)){} - errReinit++; - CAN_init(false); - if ( uxQueueSpacesAvailable(TxQueue)==0 ) return false; - } - else{ - ECDEBUG("CanSendFrame queue full\n"); - return false; // can not send to queue - } - } - lastSend=now; - frame.id=id; - frame.len=len>8?8:len; - memcpy(frame.buf,buf,len); - CheckBusOff(); - ECDEBUG("CanSendFrame IntrCnt %d\n",cntIntr); - ECDEBUG("CanSendFrame Error TX/RX %d/%d\n",MODULE_CAN->TXERR.U,MODULE_CAN->RXERR.U); - ECDEBUG("CanSendFrame Error Overrun %d\n",errOverrun); - ECDEBUG("CanSendFrame Error Arbitration %d\n",errArb); - ECDEBUG("CanSendFrame Error Bus %d\n",errBus); - ECDEBUG("CanSendFrame Error Recovery %d\n",errRecovery); - ECDEBUG("CanSendFrame ErrorCount %d\n",errCountTxInternal); - ECDEBUG("CanSendFrame ErrorCancel %d\n",errCancelTransmit); - ECDEBUG("CanSendFrame ErrorReinit %d\n",errReinit); - ECDEBUG("CanSendFrame busOff=%d, errPassive=%d\n",MODULE_CAN->SR.B.BS,MODULE_CAN->SR.B.ES) - xQueueSendToBack(TxQueue,&frame,0); // Add frame to queue - if ( MODULE_CAN->SR.B.TBS==0 ) { - ECDEBUG("CanSendFrame: wait for ISR to send %d\n",frame.id); - return true; // Currently sending, ISR takes care of sending - } - - if ( MODULE_CAN->SR.B.TBS==1 ) { // Check again and restart send, if is not going on - xQueueReceive(TxQueue,&frame,0); - ECDEBUG("CanSendFrame: send direct %d\n",frame.id); - CAN_send_frame(frame); - //return MODULE_CAN->TXERR.U < 127; - } - - return true; -} - -//***************************************************************************** -void tNMEA2000_esp32::InitCANFrameBuffers() { - if (MaxCANReceiveFrames<10 ) MaxCANReceiveFrames=50; // ESP32 has plenty of RAM - if (MaxCANSendFrames<10 ) MaxCANSendFrames=40; - uint16_t CANGlobalBufSize=MaxCANSendFrames-4; - MaxCANSendFrames=4; // we do not need much libary internal buffer since driver has them. - RxQueue=xQueueCreate(MaxCANReceiveFrames,sizeof(tCANFrame)); - TxQueue=xQueueCreate(CANGlobalBufSize,sizeof(tCANFrame)); - - tNMEA2000::InitCANFrameBuffers(); // call main initialization -} - -//***************************************************************************** -bool tNMEA2000_esp32::CANOpen() { - if (IsOpen) return true; - - if (CanInUse) return false; // currently prevent accidental second instance. Maybe possible in future. - - pNMEA2000_esp32=this; - IsOpen=true; - CAN_init(); - - CanInUse=IsOpen; - - return IsOpen; -} - -//***************************************************************************** -bool tNMEA2000_esp32::CANGetFrame(unsigned long &id, unsigned char &len, unsigned char *buf) { - bool HasFrame=false; - tCANFrame frame; - CheckBusOff(); - unsigned long now=millis(); - //receive next CAN frame from queue - if ( xQueueReceive(RxQueue,&frame, 0)==pdTRUE ) { - HasFrame=true; - id=frame.id; - len=frame.len; - memcpy(buf,frame.buf,frame.len); - lastReceive=now; - } - else{ - if (lastReceive != 0 && (lastReceive + RECEIVE_REINIT_TIME) < now && (lastSend + RECEIVE_REINIT_TIME) < now){ - ECDEBUG("Noting received within %d ms, reinit",RECEIVE_REINIT_TIME); - CAN_init(false); - } - } - - return HasFrame; -} - -//***************************************************************************** -void tNMEA2000_esp32::CAN_init(bool installIsr) { - - //Time quantum - double __tq; - - - // A soft reset of the ESP32 leaves it's CAN controller in an undefined state so a reset is needed. - // Reset CAN controller to same state as it would be in after a power down reset. - periph_module_reset(PERIPH_CAN_MODULE); - - - //enable module - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST); - - //configure RX pin - gpio_set_direction(RxPin,GPIO_MODE_INPUT); - gpio_matrix_in(RxPin,CAN_RX_IDX,0); - gpio_pad_select_gpio(RxPin); - - //set to PELICAN mode - MODULE_CAN->CDR.B.CAN_M=0x1; - - //synchronization jump width is the same for all baud rates - MODULE_CAN->BTR0.B.SJW =0x1; - - //TSEG2 is the same for all baud rates - MODULE_CAN->BTR1.B.TSEG2 =0x1; - - //select time quantum and set TSEG1 - switch (speed) { - case CAN_SPEED_1000KBPS: - MODULE_CAN->BTR1.B.TSEG1 =0x4; - __tq = 0.125; - break; - - case CAN_SPEED_800KBPS: - MODULE_CAN->BTR1.B.TSEG1 =0x6; - __tq = 0.125; - break; - default: - MODULE_CAN->BTR1.B.TSEG1 =0xc; - __tq = ((float)1000/speed) / 16; - } - - //set baud rate prescaler - MODULE_CAN->BTR0.B.BRP=(uint8_t)round((((APB_CLK_FREQ * __tq) / 2) - 1)/1000000)-1; - - /* Set sampling - * 1 -> triple; the bus is sampled three times; recommended for low/medium speed buses (class A and B) where filtering spikes on the bus line is beneficial - * 0 -> single; the bus is sampled once; recommended for high speed buses (SAE class C)*/ - MODULE_CAN->BTR1.B.SAM =0x1; - - //enable all interrupts - MODULE_CAN->IER.U = 0xef; // bit 0x10 contains Baud Rate Prescaler Divider (BRP_DIV) bit - - //no acceptance filtering, as we want to fetch all messages - MODULE_CAN->MBX_CTRL.ACC.CODE[0] = 0; - MODULE_CAN->MBX_CTRL.ACC.CODE[1] = 0; - MODULE_CAN->MBX_CTRL.ACC.CODE[2] = 0; - MODULE_CAN->MBX_CTRL.ACC.CODE[3] = 0; - MODULE_CAN->MBX_CTRL.ACC.MASK[0] = 0xff; - MODULE_CAN->MBX_CTRL.ACC.MASK[1] = 0xff; - MODULE_CAN->MBX_CTRL.ACC.MASK[2] = 0xff; - MODULE_CAN->MBX_CTRL.ACC.MASK[3] = 0xff; - - //set to normal mode - MODULE_CAN->OCR.B.OCMODE=__CAN_OC_NOM; - - //clear error counters - MODULE_CAN->TXERR.U = 0; - MODULE_CAN->RXERR.U = 0; - (void)MODULE_CAN->ECC; - - //clear interrupt flags - (void)MODULE_CAN->IR.U; - - //install CAN ISR - if (installIsr) esp_intr_alloc(ETS_CAN_INTR_SOURCE,0,ESP32Can1Interrupt,NULL,NULL); - - //configure TX pin - // We do late configure, since some initialization above caused CAN Tx flash - // shortly causing one error frame on startup. By setting CAN pin here - // it works right. - gpio_set_direction(TxPin,GPIO_MODE_OUTPUT); - gpio_matrix_out(TxPin,CAN_TX_IDX,0,0); - gpio_pad_select_gpio(TxPin); - - //Showtime. Release Reset Mode. - MODULE_CAN->MOD.B.RM = 0; -} - -//***************************************************************************** -void tNMEA2000_esp32::CAN_read_frame() { - tCANFrame frame; - CAN_FIR_t FIR; - - //get FIR - FIR.U=MODULE_CAN->MBX_CTRL.FCTRL.FIR.U; - frame.len=FIR.B.DLC>8?8:FIR.B.DLC; - - // Handle only extended frames - if (FIR.B.FF==CAN_frame_ext) { //extended frame - //Get Message ID - frame.id = _CAN_GET_EXT_ID; - - //deep copy data bytes - for( size_t i=0; iMBX_CTRL.FCTRL.TX_RX.EXT.data[i]; - } - - //send frame to input queue - xQueueSendToBackFromISR(RxQueue,&frame,0); - } - - //Let the hardware know the frame has been read. - MODULE_CAN->CMR.B.RRB=1; -} - -//***************************************************************************** -void tNMEA2000_esp32::CAN_send_frame(tCANFrame &frame) { - CAN_FIR_t FIR; - - FIR.U=0; - FIR.B.DLC=frame.len>8?8:frame.len; - FIR.B.FF=CAN_frame_ext; - - //copy frame information record - MODULE_CAN->MBX_CTRL.FCTRL.FIR.U=FIR.U; - - //Write message ID - _CAN_SET_EXT_ID(frame.id); - - // Copy the frame data to the hardware - for ( size_t i=0; iMBX_CTRL.FCTRL.TX_RX.EXT.data[i]=frame.buf[i]; - } - - // Transmit frame - MODULE_CAN->CMR.B.TR=1; -} -#define CAN_MAX_TX_RETRY 12 -#define RECOVERY_RETRY_MS 1000 -void tNMEA2000_esp32::CAN_bus_off_recovery(){ - unsigned long now=millis(); - if (recoveryStarted && (recoveryStarted + RECOVERY_RETRY_MS) > now ) return; - ECDEBUG("CAN_bus_off_recovery started\n"); - recoveryStarted=now; - errRecovery++; - MODULE_CAN->CMR.B.AT=1; // abort transmission - (void)MODULE_CAN->SR.U; - MODULE_CAN->TXERR.U = 127; - MODULE_CAN->RXERR.U = 0; - MODULE_CAN->MOD.B.RM = 0; -} - -void tNMEA2000_esp32::CheckBusOff(){ - //should we really recover here? - if (MODULE_CAN->SR.B.BS){ - ECDEBUG("Bus off detected, trying recovery\n"); - CAN_bus_off_recovery(); - } - -} - -//***************************************************************************** -void tNMEA2000_esp32::InterruptHandler() { - //Interrupt flag buffer - cntIntr++; - uint32_t interrupt; - - // Read interrupt status and clear flags - interrupt = (MODULE_CAN->IR.U & 0xff); - - // Handle TX complete interrupt - //see http://uglyduck.vajn.icu/PDF/wireless/Espressif/ESP32/Eco_and_Workarounds_for_Bugs_in_ESP32.pdf, 3.13.4 - if ((interrupt & __CAN_IRQ_TX) != 0 || MODULE_CAN->SR.B.TBS) { - tCANFrame frame; - if ( (xQueueReceiveFromISR(TxQueue,&frame,NULL)==pdTRUE) ) { - CAN_send_frame(frame); - } - } - - // Handle RX frame available interrupt - if ((interrupt & __CAN_IRQ_RX) != 0) { - CAN_read_frame(); - } - - // Handle error interrupts. - if ((interrupt & (__CAN_IRQ_ERR //0x4 - - | __CAN_IRQ_WAKEUP //0x10 - | __CAN_IRQ_ERR_PASSIVE //0x20 - - - )) != 0) { - /*handler*/ - - } - //https://www.esp32.com/viewtopic.php?t=5010 - // Handle error interrupts. - if (interrupt & __CAN_IRQ_DATA_OVERRUN ) { //0x08 - errOverrun++; - MODULE_CAN->CMR.B.CDO=1; - (void)MODULE_CAN->SR.U; // read SR after write to CMR to settle register changes - } - if (interrupt & __CAN_IRQ_ARB_LOST ) { //0x40 - errArb++; - (void)MODULE_CAN->ALC.U; // must be read to re-enable interrupt - errCountTxInternal++; - } - if (interrupt & __CAN_IRQ_BUS_ERR ) { //0x80 - errBus++; - (void)MODULE_CAN->ECC.U; // must be read to re-enable interrupt - errCountTxInternal+=2; - } - if (MODULE_CAN->TXERR.U == 0){ - recoveryStarted=0; - } - if (errCountTxInternal >= 2 *CAN_MAX_TX_RETRY){ - MODULE_CAN->CMR.B.AT=1; // abort transmission - (void)MODULE_CAN->SR.U; - errCountTxInternal=0; - } -} - -//***************************************************************************** -void ESP32Can1Interrupt(void *) { - pNMEA2000_esp32->InterruptHandler(); -} diff --git a/lib/nmea2000esp32/NMEA2000_esp32.h b/lib/nmea2000esp32/NMEA2000_esp32.h deleted file mode 100644 index 59d63f9..0000000 --- a/lib/nmea2000esp32/NMEA2000_esp32.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -NMEA2000_esp32.h - -Copyright (c) 2015-2020 Timo Lappalainen, Kave Oy, www.kave.fi - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Inherited NMEA2000 object for ESP32 modules. See also NMEA2000 library. - -Thanks to Thomas Barth, barth-dev.de, who has written ESP32 CAN code. To avoid extra -libraries, I implemented his code directly to the NMEA2000_esp32 to avoid extra -can.h library, which may cause even naming problem. - -The library sets as default CAN Tx pin to GPIO 16 and CAN Rx pint to GPIO 4. If you -want to use other pins (I have not tested can any pins be used), add defines e.g. -#define ESP32_CAN_TX_PIN GPIO_NUM_34 -#define ESP32_CAN_RX_PIN GPIO_NUM_35 -before including NMEA2000_esp32.h or NMEA2000_CAN.h -*/ - -#ifndef _NMEA2000_ESP32_H_ -#define _NMEA2000_ESP32_H_ - -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "driver/gpio.h" -#include "NMEA2000.h" -#include "N2kMsg.h" -#include "ESP32_CAN_def.h" - -#ifndef ESP32_CAN_TX_PIN -#define ESP32_CAN_TX_PIN GPIO_NUM_16 -#endif -#ifndef ESP32_CAN_RX_PIN -#define ESP32_CAN_RX_PIN GPIO_NUM_4 -#endif - -class tNMEA2000_esp32 : public tNMEA2000 -{ -private: - bool IsOpen; - static bool CanInUse; - -protected: - struct tCANFrame { - uint32_t id; // can identifier - uint8_t len; // length of data - uint8_t buf[8]; - }; - -protected: - CAN_speed_t speed; - gpio_num_t TxPin; - gpio_num_t RxPin; - QueueHandle_t RxQueue; - QueueHandle_t TxQueue; - Print *debugStream; - int errOverrun=0; - int errArb=0; - int errBus=0; - int errRecovery=0; - int errCountTxInternal=0; - int errCancelTransmit=0; - int errReinit=0; - unsigned long recoveryStarted=0; - unsigned long lastSend=0; - unsigned long lastReceive=0; - int cntIntr=0; - -protected: - void CAN_read_frame(); // Read frame to queue within interrupt - void CAN_send_frame(tCANFrame &frame); // Send frame - void CAN_init(bool installIsr=true); - void CAN_bus_off_recovery(); //recover from bus off - void CheckBusOff(); - -protected: - bool CANSendFrame(unsigned long id, unsigned char len, const unsigned char *buf, bool wait_sent=true); - bool CANOpen(); - bool CANGetFrame(unsigned long &id, unsigned char &len, unsigned char *buf); - virtual void InitCANFrameBuffers(); - -public: - tNMEA2000_esp32(gpio_num_t _TxPin=ESP32_CAN_TX_PIN, - gpio_num_t _RxPin=ESP32_CAN_RX_PIN, - Print *debugStream=NULL); - - void InterruptHandler(); -}; - -#endif diff --git a/lib/nmea2000esp32/readme.txt b/lib/nmea2000esp32/readme.txt deleted file mode 100644 index 1ff5aa0..0000000 --- a/lib/nmea2000esp32/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -forked from https://github.com/ttlappalainen/NMEA2000_esp32 -with some error handling additions -based on https://www.esp32.com/viewtopic.php?t=5010 \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index ddeaf37..9b3e004 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,7 +12,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "GwAppInfo.h" -#define USE_TWAI // #define GW_MESSAGE_DEBUG_ENABLED //#define FALLBACK_SERIAL //#define CAN_ESP_DEBUG @@ -110,13 +109,8 @@ typedef std::map StringMap; GwLog logger(LOGLEVEL,NULL); GwConfigHandler config(&logger); -#ifndef USE_TWAI -#include // forked from https://github.com/ttlappalainen/NMEA2000_esp32 -tNMEA2000 &NMEA2000=*(new tNMEA2000_esp32(ESP32_CAN_TX_PIN,ESP32_CAN_RX_PIN,CDBS)); -#else #include "Nmea2kTwai.h" tNMEA2000 &NMEA2000=*(new Nmea2kTwai(ESP32_CAN_TX_PIN,ESP32_CAN_RX_PIN,&logger)); -#endif #ifdef GWBUTTON_PIN bool fixedApPass=false;