From 93a895c2f86b5f7823694d08ded3506cd3e8c41a Mon Sep 17 00:00:00 2001 From: bragin-d Date: Fri, 5 Jan 2024 22:57:52 +0100 Subject: [PATCH 01/16] Create header file for registers --- TCAN4550/ti_can_registers.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 TCAN4550/ti_can_registers.h diff --git a/TCAN4550/ti_can_registers.h b/TCAN4550/ti_can_registers.h new file mode 100644 index 0000000..e69de29 From 078cfd5822b792c9eb232b1f16823180ec23af68 Mon Sep 17 00:00:00 2001 From: bragin-d Date: Fri, 5 Jan 2024 22:58:03 +0100 Subject: [PATCH 02/16] Create C file --- TCAN4550/ti_can.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 TCAN4550/ti_can.c diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c new file mode 100644 index 0000000..e69de29 From 306a04c5dd8d7b580ceede34a3a3b041dba297c2 Mon Sep 17 00:00:00 2001 From: bragin-d Date: Fri, 5 Jan 2024 22:58:14 +0100 Subject: [PATCH 03/16] Create main header file --- TCAN4550/ti_can.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 TCAN4550/ti_can.h diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h new file mode 100644 index 0000000..e69de29 From 1e422102360699e12a0c4a1531581e424be10249 Mon Sep 17 00:00:00 2001 From: bragin-d Date: Mon, 5 Feb 2024 22:21:17 +0100 Subject: [PATCH 04/16] Added bit timing and MRAM params --- TCAN4550/ti_can.h | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index e69de29..ae35049 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -0,0 +1,59 @@ +/// ____ ______ __ __ +/// / __ `____ ___ ____ / ____/_ ______ / /_ ____ / / +/// / / / / __ `/ _ `/ __ `/ / / / / / __ `/ __ `/ __ `/ / +/// / /_/ / /_/ / __/ / / / /___/ /_/ / /_/ / / / / /_/ / / +/// `____/ .___/`___/_/ /_/`____/`__, / .___/_/ /_/`__,_/_/ +/// /_/ /____/_/ +/// +/// A low-level driver with the main purpose of helping new hardware revisions or new designs adopt CAN FD +/// without having to port an existing codebase to a new platform. +/// +/// Author: Daniil Bragin +/// + + +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/// 0 - CAN, 1 - CAN FD +#define CAN_MODE 1 + +/// Bit Timing Registers (Addresses) +#define NBTP 0x101C // For CAN +#define DBTP 0x100C // For CAN FD +#define TDCR 0x1048 // Transmissio Delay Compensation Register (for CAN FD only) + + + + +/// CAN Bit Timing Values +typedef struct +{ + uint8_t prescaler; + uint8_t prop_and_phase1; + uint8_t phase2; + uint8_t sync_jump_width; +} BitTimingParams; + + +/// Message RAM Design Parameters +typedef struct +{ + uint8_t sid_filters; /// 11-bit filter size + uint8_t xid_filters; /// 29-bit filter size + uint8_t rx_fifo_0; + uint8_t rx_fifo_1; + uint8_t rx_buffers; + uint8_t tx_event_fifo; + uint8_t tx_buffers; +} TiMRAMParams; + + From c9cbb20053dc032c33963b1d4711e0f8909471bd Mon Sep 17 00:00:00 2001 From: bragin-d Date: Tue, 16 Apr 2024 23:16:52 +0200 Subject: [PATCH 05/16] base file --- TCAN4550/ti_can_registers.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/TCAN4550/ti_can_registers.h b/TCAN4550/ti_can_registers.h index e69de29..407ac4f 100644 --- a/TCAN4550/ti_can_registers.h +++ b/TCAN4550/ti_can_registers.h @@ -0,0 +1,10 @@ +/// +/// Author: Daniil Bragin +/// + +#pragma once + +#include + + + From 21c7804db86ad27289f68157a07853e2f2c4c3ef Mon Sep 17 00:00:00 2001 From: bragin-d Date: Tue, 16 Apr 2024 23:17:19 +0200 Subject: [PATCH 06/16] Added bit timing params and regs --- TCAN4550/ti_can.h | 70 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index ae35049..3e0f634 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -22,29 +22,87 @@ extern "C" { #endif +/////////////////////////////////////////////////////////////////////////////////////////// /// 0 - CAN, 1 - CAN FD #define CAN_MODE 1 -/// Bit Timing Registers (Addresses) -#define NBTP 0x101C // For CAN -#define DBTP 0x100C // For CAN FD -#define TDCR 0x1048 // Transmissio Delay Compensation Register (for CAN FD only) +/////////////////////////////////////////////////////////////////////////////////////////// +/// BIT TIMING VALUES +// FOR CAN +#define NBTP 0x101C +#define CAN_NBTP_NSJW_SHFT (25U) +#define CAN_NBTP_NSJW_MASK (0x7FU << CAN_NBTP_NSJW_SHFT) +#define CAN_SYNC_JUMP_WIDTH(x) ((uint8_t)(x) << CAN_NBTP_NSJW_SHFT) -/// CAN Bit Timing Values +#define CAN_NBTP_NTSEG1_SHFT (8U) +#define CAN_NBTP_NTSEG1_MASK (0xFFU << CAN_NBTP_NTSEG1_SHFT) +#define CAN_TIME_SEG_1(x) ((uint8_t)(x) << CAN_NBTP_NTSEG1_SHFT) + +#define CAN_NBTP_NTSEG2_SHFT (0U) +#define CAN_NBTP_NTSEG2_MASK (0x7FU << CAN_NBTP_NTSEG2_SHFT) +#define CAN_TIME_SEG_2(x) ((uint8_t)(x) << CAN_NBTP_NTSEG2_SHFT) + +#define CAN_NBTP_NBRP_SHFT (0U) +#define CAN_NBTP_NBRP_MASK (0x7FU << CAN_NBTP_NBRP_SHFT) +#define CAN_PRESCALER(x) ((uint8_t)(x) << CAN_NBTP_NBRP_SHFT) + +// FOR CAN-FD +#define DBTP 0x100C +#define TDCR 0x1048 // Transmission Delay Compensation Register + +#define CANFD_DBTP_DSJW_SHFT (0U) +#define CANFD_DBTP_DSJW_MASK (0xFU << CANFD_DBTP_DSJW_SHFT) +#define CANFD_SYNC_JUMP_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DSJW_SHFT) + +#define CANFD_DBTP_DTSEG1_SHFT (8U) +#define CANFD_DBTP_DTSEG1_MASK (0x1FU << CANFD_DBTP_DTSEG1_SHFT) +#define CANFD_TIME_SEG_1_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DTSEG1_SHFT) + +#define CANFD_DBTP_DTSEG2_SHFT (4U) +#define CANFD_DBTP_DTSEG2_MASK (0xFU << CANFD_DBTP_DTSEG2_SHFT) +#define CANFD_TIME_SEG_2_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DTSEG2_SHFT) + +#define CANFD_DBTP_DBRP_SHFT (16U) +#define CANFD_DBTP_DBRP_MASK (0xFU << CANFD_DBTP_DBRP_SHFT) +#define CANFD_PRESCALER(x) ((uint8_t)(x) << CANFD_DBTP_DBRP_SHFT) + +#define CANFD_TDCR_TDCO_SHFT (8U) +#define CANFD_TDCR_TDCO_MASK (0x7FU << CANFD_TDCR_TDCO_SHFT) +#define CANFD_DELAY_COMPENSATION_OFFSET(x) ((uint8_t)(x) << CANFD_TDCR_TDCO_SHFT) + +// Bit Timing Parameters typedef struct { uint8_t prescaler; uint8_t prop_and_phase1; uint8_t phase2; uint8_t sync_jump_width; + uint8_t tdc; } BitTimingParams; +/////////////////////////////////////////////////////////////////////////////////////////// + +/// MESSAGE RAM + +// MRAM Registers' Addresses +#define SIDFC 0x1084 // 11-bit Filter (SID Filter) +#define XIDFC 0x1088 // 29-bit Filter (XID Filter) +#define RXF0C 0x10A0 // Rx FIFO 0 +#define RXF1C 0x10B0 // Rx FIFO 1 +#define RXBC 0x10AC // Rx Buffers +#define RXESC 0x10BC // Rx Element Size Config +#define TXEFC 0x10F0 // Tx Event FIFO +#define TXBC 0x10C0 // Tx Buffers +#define TXESC 0x10C8 // Tx Element Size Config + +// Bits In Registers + -/// Message RAM Design Parameters +// Message RAM Design Parameters typedef struct { uint8_t sid_filters; /// 11-bit filter size From 6af1e70ca2f147c5d78a66a19b2e5c0df5eec7cb Mon Sep 17 00:00:00 2001 From: bragin-d Date: Wed, 17 Apr 2024 01:01:52 +0200 Subject: [PATCH 07/16] Start of .c file --- TCAN4550/ti_can.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c index e69de29..9b8497e 100644 --- a/TCAN4550/ti_can.c +++ b/TCAN4550/ti_can.c @@ -0,0 +1,41 @@ +/// +/// Author: Daniil Bragin +/// + +#include "ti_can.h" +#include "ti_can_registers.h" +#include +#include + + +void spiRegisterWrite(uint16_t addr, + uint32_t regValue) +{ + +} + +void initCAN (const BitTimingParams bTParams) +{ + + // Bit Timing Init + if (CAN_MODE == 0) + { + + } + else if (CAN_MODE == 1) + { + + } + + // MRAM Init + + // Initialization Mode + uint8_t init = CAN_CCCR_CCE | CAN_CCCR_INIT; + spiRegisterWrite(CCCR, (uint32_t)init); + + // SID Filters + + +} + + From 4b31ebb55a9c025ccfe9db713cc18136357fe524 Mon Sep 17 00:00:00 2001 From: bragin-d Date: Wed, 17 Apr 2024 01:02:15 +0200 Subject: [PATCH 08/16] Added partial filter conf --- TCAN4550/ti_can.h | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index 3e0f634..eb342ea 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -101,6 +101,9 @@ typedef struct // Bits In Registers +// +// // +// // Message RAM Design Parameters typedef struct @@ -114,4 +117,49 @@ typedef struct uint8_t tx_buffers; } TiMRAMParams; +// Filters Configuration: SID and XID (Standard and Extended) +// Number of Standard Acceptance Filters +#define CAN_SID_NUM_ACCEPTANCE_FILTERS 14U + +// Number of Extended Acceptance Filters +#define CAN_XID_NUM_ACCEPTANCE_FILTERS 14U + +// SID +typedef struct +{ + uint32_t sid_id; + uint32_t sid_mask; +} CAN_SIDFilterParams; + +#define CAN_SFID1_SHFT (16U) +#define CAN_SFID1_MASK (0x7FF << CAN_SFID1_SHFT) +#define CAN_SID_FILTER_1(x) ((uint8_t)x << CAN_SFID1_SHFT) + +#define CAN_SFID2_SHFT (0U) +#define CAN_SFID2_MASK (0x7FF << CAN_SFID2_SHFT) +#define CAN_SID_FILTER_2(x) ((uint8_t)x << CAN_SFID2_SHFT) + + + + + +// XID +typedef struct +{ + uint32_t xid_id; + uint32_t xid_mask; +} CAN_SIDFilterParams; + +/////////////////////////////////////////////////////////////////////////////////////////// + +/// Device Initialization Mode + +// CC Control Register Address +#define CCCR 0x1018 + +// Bits Necessary For Initialization +#define CAN_CCCR_INIT (1U << 0U) +#define CAN_CCCR_CCE (1U << 1U) + +/////////////////////////////////////////////////////////////////////////////////////////// From 3946aea7ecea0320d937d677efabf12ffb63d23c Mon Sep 17 00:00:00 2001 From: Daniil Bragin Date: Tue, 28 May 2024 22:21:46 +0200 Subject: [PATCH 09/16] Finished CAN and CAN-FD init --- TCAN4550/ti_can.c | 56 ++++++++++++++++++++++++++++++++++++++++------- TCAN4550/ti_can.h | 21 ++++++++++++++---- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c index 9b8497e..b5583e1 100644 --- a/TCAN4550/ti_can.c +++ b/TCAN4550/ti_can.c @@ -8,34 +8,74 @@ #include -void spiRegisterWrite(uint16_t addr, +uint8_t spiRegisterWrite(uint16_t addr, uint32_t regValue) { + /** + * + * TODO: Implement SPI write opration based on the host MCU + * + */ + + return 0; +} + +uint32_t spiRegisterRead(uint16_t addr) +{ + uint32_t regValue = 0; + + /** + * + * TODO: Implement SPI read opration based on the host MCU + * + */ + + return regValue; } -void initCAN (const BitTimingParams bTParams) +uint8_t initCAN (const BitTimingParams bTParams) { + // Standby Mode Check + if ((spiRegisterRead(MODE_SEL)) != STANDBY_MODE) + { + spiRegisterWrite(MODE_SEL, STANDBY_MODE); + } - // Bit Timing Init + // Initialization Mode + // TODO: Check whether CSR needs to be written before CCE and INIT + uint32_t init; + init |= (CAN_CCCR_CCE | CAN_CCCR_INIT); + init &= ~CAN_CCCR_CSR; + + // FD/BRS & Bit Timing Init Cofiguration if (CAN_MODE == 0) { - + init |= + + spiRegisterWrite(CCCR, init); } else if (CAN_MODE == 1) { - + if (BRS) init |= CCCR_BRSE; + if (FD) init |= CCCR_FDOE; + + + + spiRegisterWrite(CCCR, init); } // MRAM Init - // Initialization Mode - uint8_t init = CAN_CCCR_CCE | CAN_CCCR_INIT; - spiRegisterWrite(CCCR, (uint32_t)init); + // SID Filters + // Put the TCAN45xx device into "NORMAL" mode + spiRegisterWrite(MODE_SEL, NORMAL_MODE); + + return 0; } diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index eb342ea..0e733e4 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -25,7 +25,15 @@ extern "C" { /////////////////////////////////////////////////////////////////////////////////////////// /// 0 - CAN, 1 - CAN FD -#define CAN_MODE 1 +#define CAN_MODE 1 + +/// 0 - Bit Rate Switching disabled, 1 - enabled +#define BRS 1 +#define CCCR_BRSE (1U << 9U) + +/// 0 - Flexible Datarate disabled, 1 - enabled +#define FD 1 +#define CCCR_FDOE (1U << 8U) /////////////////////////////////////////////////////////////////////////////////////////// @@ -141,9 +149,6 @@ typedef struct #define CAN_SID_FILTER_2(x) ((uint8_t)x << CAN_SFID2_SHFT) - - - // XID typedef struct { @@ -155,11 +160,19 @@ typedef struct /// Device Initialization Mode +// Device Mode Selection Register Address +#define MODE_SEL 0x0800 + +// Available Device Modes +#define STANDBY_MODE (0b01 << 6U) +#define NORMAL_MODE (0b10 << 6U) + // CC Control Register Address #define CCCR 0x1018 // Bits Necessary For Initialization #define CAN_CCCR_INIT (1U << 0U) #define CAN_CCCR_CCE (1U << 1U) +#define CAN_CCCR_CSR (1U << 4U) /////////////////////////////////////////////////////////////////////////////////////////// From 052233a9c74e14115ede39b9e1c8cc5e3f3d6803 Mon Sep 17 00:00:00 2001 From: Daniil Bragin Date: Fri, 31 May 2024 01:26:34 +0200 Subject: [PATCH 10/16] Finished MRAM config and initCAN --- TCAN4550/ti_can.c | 161 ++++++++++++++++++++++++++++++++++--- TCAN4550/ti_can.h | 199 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 328 insertions(+), 32 deletions(-) diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c index b5583e1..a0652b4 100644 --- a/TCAN4550/ti_can.c +++ b/TCAN4550/ti_can.c @@ -1,6 +1,6 @@ /// /// Author: Daniil Bragin -/// +/// Reference: #include "ti_can.h" #include "ti_can_registers.h" @@ -14,7 +14,7 @@ uint8_t spiRegisterWrite(uint16_t addr, /** * - * TODO: Implement SPI write opration based on the host MCU + * TODO: Implement SPI write operation based on the host MCU * */ @@ -27,15 +27,17 @@ uint32_t spiRegisterRead(uint16_t addr) /** * - * TODO: Implement SPI read opration based on the host MCU + * TODO: Implement SPI read operation based on the host MCU * */ return regValue; } -uint8_t initCAN (const BitTimingParams bTParams) +uint8_t initCAN (const BitTimingParams * bTParams, + const TiMRAMParams * MRAM) { + // Standby Mode Check if ((spiRegisterRead(MODE_SEL)) != STANDBY_MODE) { @@ -44,32 +46,171 @@ uint8_t initCAN (const BitTimingParams bTParams) // Initialization Mode // TODO: Check whether CSR needs to be written before CCE and INIT - uint32_t init; + uint32_t init = spiRegisterRead(CCCR); init |= (CAN_CCCR_CCE | CAN_CCCR_INIT); init &= ~CAN_CCCR_CSR; + uint32_t bit_timing = 0; + uint32_t trans_delay_comp = 0; + + uint8_t prescaler = bTParams -> prescaler; + uint8_t prop_and_phase1 = bTParams -> prop_and_phase1; + uint8_t phase2 = bTParams -> phase2; + uint8_t sync_jump_width = bTParams -> sync_jump_width; + uint8_t tdc = bTParams -> tdc; + + // FD/BRS & Bit Timing Init Cofiguration if (CAN_MODE == 0) { - init |= - spiRegisterWrite(CCCR, init); + + bit_timing = spiRegisterRead(NBTP); + + // Reset the NBTP register values + bit_timing &= ~(CAN_NBTP_NSJW_MASK | + CAN_NBTP_NTSEG1_MASK | + CAN_NBTP_NTSEG2_MASK | + CAN_NBTP_NBRP_MASK); + + // Set the NBTP register values based on the provided settings + bit_timing |= CAN_SYNC_JUMP_WIDTH(sync_jump_width); + bit_timing |= CAN_TIME_SEG_1(prop_and_phase1); + bit_timing |= CAN_TIME_SEG_2(phase2); + bit_timing |= CAN_PRESCALER(prescaler); + + spiRegisterWrite(NBTP, bit_timing); + } else if (CAN_MODE == 1) { + // Check BRS and FD settings if (BRS) init |= CCCR_BRSE; if (FD) init |= CCCR_FDOE; - - spiRegisterWrite(CCCR, init); + + bit_timing = spiRegisterRead(DBTP); + trans_delay_comp = spiRegisterRead(TDCR); + + // Reset the DBTP register values + bit_timing &= ~(CANFD_DBTP_DSJW_MASK | + CANFD_DBTP_DTSEG1_MASK | + CANFD_DBTP_DTSEG2_MASK | + CANFD_DBTP_DBRP_MASK); + + trans_delay_comp &= ~CANFD_TDCR_TDCO_MASK; + + // Set the DBTP register values based on the provided settings + bit_timing |= CANFD_SYNC_JUMP_WIDTH(sync_jump_width); + bit_timing |= CANFD_TIME_SEG_1_WIDTH(prop_and_phase1); + bit_timing |= CANFD_TIME_SEG_2_WIDTH(phase2); + bit_timing |= CANFD_PRESCALER(prescaler); + + trans_delay_comp |= CANFD_DELAY_COMPENSATION_OFFSET(tdc); + + spiRegisterWrite(DBTP, bit_timing); + + spiRegisterWrite(TDCR, trans_delay_comp); } // MRAM Init + uint32_t sid = spiRegisterRead(SIDFC); + uint32_t xid = spiRegisterRead(XIDFC); + uint32_t rxf0 = spiRegisterRead(RXF0C); + uint32_t rxf1 = spiRegisterRead(RXF1C); + uint32_t rxb = spiRegisterRead(RXBC); + uint32_t rx = spiRegisterRead(RXESC); + uint32_t tx_fifo = spiRegisterRead(TXEFC); + uint32_t txb = spiRegisterRead(TXBC); + uint32_t tx = spiRegisterRead(TXESC); + + sid &= ~(SID_LSS_MASK | + SID_FLSS_MASK); + + sid |= SID_LSS(MRAM -> SID_LSS); + sid |= SID_FLSS(MRAM -> SID_FLSS); + + + xid &= ~(XID_LSE_MASK | + XID_FLSEA_MASK); + + xid |= XID_LSE(MRAM -> XID_LSE); + xid |= XID_FLSEA(MRAM -> XID_FLSEA); + + rxf0 &= ~(RXF0_F0OM_MASK | + RXF0_F0WM_MASK | + RXF0_F0S_MASK | + RXF0_F0SA_MASK); + + rxf0 |= RXF0_F0OM(MRAM -> RXF0_F0OM); + rxf0 |= RXF0_F0WM(MRAM -> RXF0_F0WM); + rxf0 |= RXF0_F0S(MRAM -> RXF0_F0S); + rxf0 |= RXF0_F0SA(MRAM -> RXF0_F0SA); + + + rxf1 &= ~(RXF1_F1OM_MASK | + RXF1_F1WM_MASK | + RXF1_F1S_MASK | + RXF1_F1SA_MASK); + + rxf1 |= RXF1_F1OM(MRAM -> RXF1_F1OM); + rxf1 |= RXF1_F1WM(MRAM -> RXF1_F1WM); + rxf1 |= RXF1_F1S(MRAM -> RXF1_F1S); + rxf1 |= RXF1_F1SA(MRAM -> RXF1_F1SA); + + + rxb &= ~(RXB_RBSA_MASK); + + rxb |= RXB_RBSA(MRAM -> RXB_RBSA); + + + rx &= ~(RX_RBDS_MASK | + RX_F1DS_MASK | + RX_F0DS_MASK); + + rx |= RX_RBDS(MRAM -> RX_RBDS); + rx |= RX_F1DS(MRAM -> RX_F1DS); + rx |= RX_F0DS(MRAM -> RX_F0DS); + + + tx_fifo &= ~(TXEVF_EFWM_MASK | + TXEVF_EFS_MASK | + TXEVF_EFSA_MASK); + + tx_fifo |= TXEVF_EFWM(MRAM -> TXEVF_EFWM); + tx_fifo |= TXEVF_EFS(MRAM -> TXEVF_EFS); + tx_fifo |= TXEVF_EFSA(MRAM -> TXEVF_EFSA); + + + txb &= ~(TXB_TFQM_MASK | + TXB_TFQS_MASK | + TXB_NDTB_MASK | + TXB_TBSA_MASK); + + txb |= TXB_TFQM(MRAM -> TXB_TFQM); + txb |= TXB_TFQS(MRAM -> TXB_TFQS); + txb |= TXB_NDTB(MRAM -> TXB_NDTB); + txb |= TXB_TBSA(MRAM -> TXB_TBSA); + + + tx &= ~(TX_TBDS_MASK); + + tx |= TX_TBDS(MRAM -> TX_TBDS); + + + spiRegisterWrite(SIDFC, sid); + spiRegisterWrite(XIDFC, xid); + spiRegisterWrite(RXF0C, rxf0); + spiRegisterWrite(RXF1C, rxf1); + spiRegisterWrite(RXBC, rxb); + spiRegisterWrite(RXESC, rx); + spiRegisterWrite(TXEFC, tx_fifo); + spiRegisterWrite(TXBC, txb); + spiRegisterWrite(TXESC, tx); - // SID Filters // Put the TCAN45xx device into "NORMAL" mode spiRegisterWrite(MODE_SEL, NORMAL_MODE); diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index 0e733e4..45064f3 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -24,16 +24,7 @@ extern "C" { /////////////////////////////////////////////////////////////////////////////////////////// -/// 0 - CAN, 1 - CAN FD -#define CAN_MODE 1 -/// 0 - Bit Rate Switching disabled, 1 - enabled -#define BRS 1 -#define CCCR_BRSE (1U << 9U) - -/// 0 - Flexible Datarate disabled, 1 - enabled -#define FD 1 -#define CCCR_FDOE (1U << 8U) /////////////////////////////////////////////////////////////////////////////////////////// @@ -54,8 +45,8 @@ extern "C" { #define CAN_NBTP_NTSEG2_MASK (0x7FU << CAN_NBTP_NTSEG2_SHFT) #define CAN_TIME_SEG_2(x) ((uint8_t)(x) << CAN_NBTP_NTSEG2_SHFT) -#define CAN_NBTP_NBRP_SHFT (0U) -#define CAN_NBTP_NBRP_MASK (0x7FU << CAN_NBTP_NBRP_SHFT) +#define CAN_NBTP_NBRP_SHFT (24U) +#define CAN_NBTP_NBRP_MASK (0x1U << CAN_NBTP_NBRP_SHFT) #define CAN_PRESCALER(x) ((uint8_t)(x) << CAN_NBTP_NBRP_SHFT) // FOR CAN-FD @@ -107,22 +98,175 @@ typedef struct #define TXBC 0x10C0 // Tx Buffers #define TXESC 0x10C8 // Tx Element Size Config -// Bits In Registers +// MRAM Params Bits + +// TODO: Check the mask values +// SID +#define SID_LSS_SHFT (16U) +#define SID_LSS_MASK (0xFFU << SID_LSS_SHFT) +#define SID_LSS(x) ((uint8_t)(x) << SID_LSS_SHFT) + +#define SID_FLSS_SHFT (0U) +#define SID_FLSS_MASK (0xFFFFU << SID_LSS_SHFT) +#define SID_FLSS(x) ((uint8_t)(x) << SID_LSS_SHFT) + + +// XID +#define XID_LSE_SHFT (16U) +#define XID_LSE_MASK (0x7FU << XID_LSE_SHFT) +#define XID_LSE(x) ((uint8_t)(x) << XID_LSE_SHFT) + + +#define XID_FLSEA_SHFT (16U) +#define XID_FLSEA_MASK (0xFFFFU << XID_FLSEA_SHFT) +#define XID_FLSEA(x) ((uint8_t)(x) << XID_FLSEA_SHFT) + + +// Rx FIFO 0 +#define RXF0_F0OM_SHFT (31U) +#define RXF0_F0OM_MASK (0x1U << RXF0_F0OM_SHFT) +#define RXF0_F0OM(x) ((uint8_t)(x) << RXF0_F0OM_SHFT) + +#define RXF0_F0WM_SHFT (24U) +#define RXF0_F0WM_MASK (0x7FU << RXF0_F0WM_SHFT) +#define RXF0_F0WM(x) ((uint8_t)(x) << RXF0_F0WM_SHFT) + +#define RXF0_F0S_SHFT (16U) +#define RXF0_F0S_MASK (0x7FU << RXF0_F0S_SHFT) +#define RXF0_F0S(x) ((uint8_t)(x) << RXF0_F0S_SHFT) + +#define RXF0_F0SA_SHFT (0U) +#define RXF0_F0SA_MASK (0xFFFFU << RXF0_F0SA_SHFT) +#define RXF0_F0SA(x) ((uint8_t)(x) << RXF0_F0SA_SHFT) + + +// Rx FIFO 1 +#define RXF1_F1OM_SHFT (31U) +#define RXF1_F1OM_MASK (0x1U << RXF1_F1OM_SHFT) +#define RXF1_F1OM(x) ((uint8_t)(x) << RXF1_F1OM_SHFT) + +#define RXF1_F1WM_SHFT (24U) +#define RXF1_F1WM_MASK (0x7FU << RXF1_F1WM_SHFT) +#define RXF1_F1WM(x) ((uint8_t)(x) << RXF1_F1WM_SHFT) + +#define RXF1_F1S_SHFT (16U) +#define RXF1_F1S_MASK (0x7FU << RXF1_F1S_SHFT) +#define RXF1_F1S(x) ((uint8_t)(x) << RXF1_F1S_SHFT) + +#define RXF1_F1SA_SHFT (0U) +#define RXF1_F1SA_MASK (0xFFFFU << RXF1_F1SA_SHFT) +#define RXF1_F1SA(x) ((uint8_t)(x) << RXF1_F1SA_SHFT) + + +// Rx Buffer +#define RXB_RBSA_SHFT (0U) +#define RXB_RBSA_MASK (0xFFFFU << RXB_RBSA_SHFT) +#define RXB_RBSA(x) ((uint8_t)(x) << RXB_RBSA_SHFT) + + +// Rx Element Size Config +#define RX_RBDS_SHFT (8U) +#define RX_RBDS_MASK (0x7U << RX_RBDS_SHFT) +#define RX_RBDS(x) ((uint8_t)(x) << RX_RBDS_SHFT) + +#define RX_F1DS_SHFT (4U) +#define RX_F1DS_MASK (0x7U << RX_F1DS_SHFT) +#define RX_F1DS(x) ((uint8_t)(x) << RX_F1DS_SHFT) + +#define RX_F0DS_SHFT (0U) +#define RX_F0DS_MASK (0x7U << RX_F0DS_SHFT) +#define RX_F0DS(x) ((uint8_t)(x) << RX_F0DS_SHFT) + + +// Tx Event FIFO Config +#define TXEVF_EFWM_SHFT (24U) +#define TXEVF_EFWM_MASK (0x3FU << TXEVF_EFWM_SHFT) +#define TXEVF_EFWM(x) ((uint8_t)(x) << TXEVF_EFWM_SHFT) + +#define TXEVF_EFS_SHFT (16U) +#define TXEVF_EFS_MASK (0x3FU << TXEVF_EFS_SHFT) +#define TXEVF_EFS(x) ((uint8_t)(x) << TXEVF_EFS_SHFT) + +#define TXEVF_EFSA_SHFT (0U) +#define TXEVF_EFSA_MASK (0xFFFFU << TXEVF_EFSA_SHFT) +#define TXEVF_EFSA(x) ((uint8_t)(x) << TXEVF_EFSA_SHFT) + + +// Tx Buffer Config +#define TXB_TFQM_SHFT (30U) +#define TXB_TFQM_MASK (0x1U << TXB_TFQM_SHFT) +#define TXB_TFQM(x) ((uint8_t)(x) << TXB_TFQM_SHFT) + +#define TXB_TFQS_SHFT (24U) +#define TXB_TFQS_MASK (0x3FU << TXB_TFQS_SHFT) +#define TXB_TFQS(x) ((uint8_t)(x) << TXB_TFQS_SHFT) + +#define TXB_NDTB_SHFT (16U) +#define TXB_NDTB_MASK (0x3FU << TXB_NDTB_SHFT) +#define TXB_NDTB(x) ((uint8_t)(x) << TXB_NDTB_SHFT) + +#define TXB_TBSA_SHFT (0U) +#define TXB_TBSA_MASK (0xFFFFU << TXB_TBSA_SHFT) +#define TXB_TBSA(x) ((uint8_t)(x) << TXB_TBSA_SHFT) + + +// TX Element Size Config +#define TX_TBDS_SHFT (0U) +#define TX_TBDS_MASK (0x7U << TX_TBDS_SHFT) +#define TX_TBDS(x) ((uint8_t)(x) << TX_TBDS_SHFT) + -// -// // -// // Message RAM Design Parameters + +// MDS = Maximum Data Size +// BPE = Bytes Per Element +// NOE = Number Of Elements + typedef struct { - uint8_t sid_filters; /// 11-bit filter size - uint8_t xid_filters; /// 29-bit filter size - uint8_t rx_fifo_0; - uint8_t rx_fifo_1; - uint8_t rx_buffers; - uint8_t tx_event_fifo; - uint8_t tx_buffers; + // SID + uint32_t SID_LSS; + uint32_t SID_FLSS; + + // XID + uint32_t XID_LSE; + uint32_t XID_FLSEA; + + // Rx FIFO 0 + uint32_t RXF0_F0OM; + uint32_t RXF0_F0WM; + uint32_t RXF0_F0S; + uint32_t RXF0_F0SA; + + // Rx FIFO 1 + uint32_t RXF1_F1OM; + uint32_t RXF1_F1WM; + uint32_t RXF1_F1S; + uint32_t RXF1_F1SA; + + // Rx Buffer + uint32_t RXB_RBSA; + + // Rx Element Size Config + uint32_t RX_RBDS; + uint32_t RX_F1DS; + uint32_t RX_F0DS; + + // Tx Event FIFO Config + uint32_t TXEVF_EFWM; + uint32_t TXEVF_EFS; + uint32_t TXEVF_EFSA; + + // Tx Buffer Config + uint32_t TXB_TFQM; + uint32_t TXB_TFQS; + uint32_t TXB_NDTB; + uint32_t TXB_TBSA; + + // TX Element Size Config + uint32_t TX_TBDS; + } TiMRAMParams; // Filters Configuration: SID and XID (Standard and Extended) @@ -175,4 +319,15 @@ typedef struct #define CAN_CCCR_CCE (1U << 1U) #define CAN_CCCR_CSR (1U << 4U) +/// 0 - CAN, 1 - CAN FD +#define CAN_MODE 1 + +/// 0 - Bit Rate Switching disabled, 1 - enabled +#define BRS 1 +#define CCCR_BRSE (1U << 9U) + +/// 0 - Flexible Datarate disabled, 1 - enabled +#define FD 1 +#define CCCR_FDOE (1U << 8U) + /////////////////////////////////////////////////////////////////////////////////////////// From ed914ea8a613507d25efa21b23b992333ded5338 Mon Sep 17 00:00:00 2001 From: Daniil Bragin Date: Tue, 4 Jun 2024 22:20:16 +0200 Subject: [PATCH 11/16] Not full version of sending + filter setting --- TCAN4550/ti_can.c | 44 ++++++++++++++++++++++++++++--- TCAN4550/ti_can.h | 67 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c index a0652b4..076d71e 100644 --- a/TCAN4550/ti_can.c +++ b/TCAN4550/ti_can.c @@ -8,8 +8,8 @@ #include -uint8_t spiRegisterWrite(uint16_t addr, - uint32_t regValue) +uint8_t spiRegisterWrite(uint32_t addr, + uint32_t regValue) { /** @@ -21,7 +21,7 @@ uint8_t spiRegisterWrite(uint16_t addr, return 0; } -uint32_t spiRegisterRead(uint16_t addr) +uint32_t spiRegisterRead(uint32_t addr) { uint32_t regValue = 0; @@ -219,4 +219,42 @@ uint8_t initCAN (const BitTimingParams * bTParams, return 0; } +uint8_t setSIDFilters(SID_filter * filters, TiMRAMParams * MRAM) +{ + size_t size = (size_t) MRAM -> SID_LSS; + uint32_t filter_addr = MRAM -> SID_FLSS; + + for (size_t i = 0; i < size; i++) + { + + } + + return 0; +} + +uint8_t setXIDFilters(SID_filter * filters, TiMRAMParams * MRAM) +{ + size_t size = (size_t) MRAM -> XID_LSE; + + + return 0; +} + +uint8_t sendCAN(TiMRAMParams * MRAM) +{} + // Check that any TX Buffer is vacant + uint32_t free_level = spiRegisterRead(TXFQS); + + if (!(TFFL(free_level))) + { + return 1; + } + + uint8_t index = TFQPI(free_level); + + uint16_t memory_offset = ; + + + return 0; +} diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index 45064f3..faf6811 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -100,7 +100,6 @@ typedef struct // MRAM Params Bits -// TODO: Check the mask values // SID #define SID_LSS_SHFT (16U) #define SID_LSS_MASK (0xFFU << SID_LSS_SHFT) @@ -271,7 +270,52 @@ typedef struct // Filters Configuration: SID and XID (Standard and Extended) -// Number of Standard Acceptance Filters +typedef struct +{ + // In classic mode: SFID_1 = ID, SFID_2 = MASK + + uint16_t SFID_1; + uint16_t SFID_2; + uint8_t SFT; + uint8_t SFEC; + +} SID_filter; + + +// SID Filter Type +#define SID_SFT_SHFT (30U) +#define SID_SFT_MASK (0x3 << SID_SFT_SHFT) +#define SID_SFT(x) ((uint8_t)(x) << SID_SFT_SHFT) + +// Options for the SID filter type +#define RANGE_FILTER 0b00U +#define DUAL_ID_FILTER 0b01U +#define CLASSIC_FILTER 0b10U +#define FILTER_ELEMENT_DISABLED 0b11U + +// Standard Element Filter Configuration +#define SID_SFEC_SHFT (30U) +#define SID_SFEC_MASK (0x3 << SID_SFEC_SHFT) +#define SID_SFEC(x) ((uint8_t)(x) << SID_SFEC_SHFT) + +// Options for the element configuration +#define DISABLE_FILTER_ELEMENT 0b000U +#define STORE_RX_FIFO_0 0b000U +#define STORE_RX_FIFO_1 0b000U +#define REJECT_MESSAGE 0b000U +#define SET_AS_PRIO_MSG_DFLT 0b000U +#define SET_AS_PRIO_FIFO_0 0b000U +#define SET_AS_PRIO_FIFO_1 0b000U + +// Store into Rx Buffer or as debug message. If this is used, SFT is ignored and SFID1 is the filter. SFID2[10:9] +// describes where to store message, SFID2[5:0] describes which Rx Buffer to put the message (must be within +// the Rx Buffer configuration +#define STORE_RX_BUF 0b000U + + + + +/*// Number of Standard Acceptance Filters #define CAN_SID_NUM_ACCEPTANCE_FILTERS 14U // Number of Extended Acceptance Filters @@ -298,7 +342,8 @@ typedef struct { uint32_t xid_id; uint32_t xid_mask; -} CAN_SIDFilterParams; +} CAN_SIDFilterParams;*/ + /////////////////////////////////////////////////////////////////////////////////////////// @@ -331,3 +376,19 @@ typedef struct #define CCCR_FDOE (1U << 8U) /////////////////////////////////////////////////////////////////////////////////////////// + +/// Message Sending + +#define TXFQS 0x10C4 // Tx FIFO/Queue Status register + +#define TXBUF_AR 0x10D0 // Tx Buffer Add Request Register + +// Set on of the bits in TXBUF_AR to request the +// data to be sent from the corresponding TX Buffer + + +#define TFFL_MASK 0x1FU +#define TFFL(reg) ((reg) & TFFL_MASK) + +#define TFQPI_MAKS 0x1F0000 +#define TFQPI(reg) (((reg) & TFQPI_MAKS) >> 16U) \ No newline at end of file From a4d2919cdc4f608dd8b2c0afd1de235d9265cf90 Mon Sep 17 00:00:00 2001 From: Daniil Bragin Date: Tue, 4 Jun 2024 23:29:54 +0200 Subject: [PATCH 12/16] Implemented setting of SID and XID filters --- TCAN4550/ti_can.c | 34 +++++++++++++++++++-- TCAN4550/ti_can.h | 78 +++++++++++++++++++++++++---------------------- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c index 076d71e..e39b4d2 100644 --- a/TCAN4550/ti_can.c +++ b/TCAN4550/ti_can.c @@ -222,20 +222,48 @@ uint8_t initCAN (const BitTimingParams * bTParams, uint8_t setSIDFilters(SID_filter * filters, TiMRAMParams * MRAM) { size_t size = (size_t) MRAM -> SID_LSS; - uint32_t filter_addr = MRAM -> SID_FLSS; + uint32_t * filter_addr = (uint32_t *)MRAM -> SID_FLSS; + uint32_t filter = 0; for (size_t i = 0; i < size; i++) { + filter = 0; + + filter |= SID_SFT (filters[i].SFT); + filter |= SID_SFEC (filters[i].SFEC); + filter |= SID_SFID1 (filters[i].SFID_1); + filter |= SID_SFID2 (filters[i].SFID_2); + spiRegisterWrite(filter_addr + i * sizeof(uint32_t), filter); } return 0; } -uint8_t setXIDFilters(SID_filter * filters, TiMRAMParams * MRAM) +uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM) { - size_t size = (size_t) MRAM -> XID_LSE; + size_t size = (size_t) MRAM -> XID_LSE; + uint32_t filter_addr = MRAM -> XID_FLSEA; + uint64_t filter = 0; // Two words needed for XID + uint32_t filter_1 = 0; + uint32_t filter_2 = 0; + + for (size_t i = 0; i < size; i++) + { + filter = 0; + filter_1 = 0; + filter_2 = 0; + + filter_1 |= XID_EFID2(filters[i].EFID2); + filter_1 |= XID_EFT(filters[i].EFT); + + filter_2 |= XID_EFID2(filters[i].EFID2); + filter_2 |= XID_EFEC(filters[i].EFEC); + filter |= (filter_1 | filter_2); + + spiRegisterWrite(filter_addr + i * sizeof(uint32_t), filter); + } return 0; } diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index faf6811..6f520e3 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -273,76 +273,82 @@ typedef struct typedef struct { // In classic mode: SFID_1 = ID, SFID_2 = MASK - + uint16_t SFID_1; uint16_t SFID_2; - uint8_t SFT; - uint8_t SFEC; + uint8_t SFT; + uint8_t SFEC; } SID_filter; // SID Filter Type #define SID_SFT_SHFT (30U) -#define SID_SFT_MASK (0x3 << SID_SFT_SHFT) #define SID_SFT(x) ((uint8_t)(x) << SID_SFT_SHFT) -// Options for the SID filter type +// Options for the SID & XID filter type #define RANGE_FILTER 0b00U #define DUAL_ID_FILTER 0b01U #define CLASSIC_FILTER 0b10U #define FILTER_ELEMENT_DISABLED 0b11U // Standard Element Filter Configuration -#define SID_SFEC_SHFT (30U) -#define SID_SFEC_MASK (0x3 << SID_SFEC_SHFT) +#define SID_SFEC_SHFT (27U) #define SID_SFEC(x) ((uint8_t)(x) << SID_SFEC_SHFT) // Options for the element configuration #define DISABLE_FILTER_ELEMENT 0b000U -#define STORE_RX_FIFO_0 0b000U -#define STORE_RX_FIFO_1 0b000U -#define REJECT_MESSAGE 0b000U -#define SET_AS_PRIO_MSG_DFLT 0b000U -#define SET_AS_PRIO_FIFO_0 0b000U -#define SET_AS_PRIO_FIFO_1 0b000U +#define STORE_RX_FIFO_0 0b001U +#define STORE_RX_FIFO_1 0b010U +#define REJECT_MESSAGE 0b011U +#define SET_AS_PRIO_MSG_DFLT 0b100U +#define SET_AS_PRIO_FIFO_0 0b101U +#define SET_AS_PRIO_FIFO_1 0b110U // Store into Rx Buffer or as debug message. If this is used, SFT is ignored and SFID1 is the filter. SFID2[10:9] // describes where to store message, SFID2[5:0] describes which Rx Buffer to put the message (must be within // the Rx Buffer configuration -#define STORE_RX_BUF 0b000U +#define STORE_RX_BUF 0b111U +#define SID_SFID1_SHFT (16U) +#define SID_SFID1_MASK (0x7FFU) +#define SID_SFID1(x) (((uint32_t)(x) & SID_SFID1_MASK) << SID_SFID1_SHFT) +#define SID_SFID2_SHFT (0U) +#define SID_SFID2_MASK (0x7FFU) +#define SID_SFID2(x) (((uint32_t)(x) & SID_SFID2_MASK) << SID_SFID2_SHFT) -/*// Number of Standard Acceptance Filters -#define CAN_SID_NUM_ACCEPTANCE_FILTERS 14U -// Number of Extended Acceptance Filters -#define CAN_XID_NUM_ACCEPTANCE_FILTERS 14U - -// SID -typedef struct +typedef struct { - uint32_t sid_id; - uint32_t sid_mask; -} CAN_SIDFilterParams; + + uint32_t EFID1; + uint32_t EFID2; + uint8_t EFT; // For type use same options as for SID + uint8_t EFEC; -#define CAN_SFID1_SHFT (16U) -#define CAN_SFID1_MASK (0x7FF << CAN_SFID1_SHFT) -#define CAN_SID_FILTER_1(x) ((uint8_t)x << CAN_SFID1_SHFT) +} XID_filter; -#define CAN_SFID2_SHFT (0U) -#define CAN_SFID2_MASK (0x7FF << CAN_SFID2_SHFT) -#define CAN_SID_FILTER_2(x) ((uint8_t)x << CAN_SFID2_SHFT) +// Word 0 + +#define XID_EFEC_SHFT (29U) +#define XID_EFEC(x) ((uint8_t)(x) << XID_EFEC_SHFT) + +#define XID_EFID1_SHFT (0U) +#define XID_EFID1_MASK (0x1FFFFFFF) +#define XID_EFID1(x) (((uint32_t)(x) & XID_EFID1_MASK) << XID_EFID1_SHFT) + +// Word 1 + +#define XID_EFT_SHFT (30U) +#define XID_EFT(x) ((uint8_t)(x) << XID_EFT_SHFT) + +#define XID_EFID2_SHFT (0U) +#define XID_EFID2_MASK (0x1FFFFFFF) +#define XID_EFID2(x) (((uint32_t)(x) & XID_EFID2_MASK) << XID_EFID2_SHFT) -// XID -typedef struct -{ - uint32_t xid_id; - uint32_t xid_mask; -} CAN_SIDFilterParams;*/ /////////////////////////////////////////////////////////////////////////////////////////// From b934cfdf0f0a1a8b1ed4d3f581a2386518978ba4 Mon Sep 17 00:00:00 2001 From: Daniil Bragin Date: Wed, 5 Jun 2024 23:13:33 +0200 Subject: [PATCH 13/16] Implemented message sending --- TCAN4550/ti_can.c | 56 ++++++++++++++++++++++++++++++++++++++++++----- TCAN4550/ti_can.h | 48 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 97 insertions(+), 7 deletions(-) diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c index e39b4d2..3b75d6c 100644 --- a/TCAN4550/ti_can.c +++ b/TCAN4550/ti_can.c @@ -85,7 +85,7 @@ uint8_t initCAN (const BitTimingParams * bTParams, else if (CAN_MODE == 1) { // Check BRS and FD settings - if (BRS) init |= CCCR_BRSE; + if (BIT_RATE_SWITCH) init |= CCCR_BRSE; if (FD) init |= CCCR_FDOE; spiRegisterWrite(CCCR, init); @@ -268,20 +268,66 @@ uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM) return 0; } -uint8_t sendCAN(TiMRAMParams * MRAM) -{} +uint8_t sendCAN(TiMRAMParams * MRAM, TXElement * TXE) +{ // Check that any TX Buffer is vacant uint32_t free_level = spiRegisterRead(TXFQS); + + uint32_t tx_buffer_start_addr = MRAM -> TXB_TBSA; + uint32_t tx_buffer_element_size = MRAM -> TX_TBDS + 8; // Additional 8 bytes of header + + if (!(TFFL(free_level))) { return 1; } - uint8_t index = TFQPI(free_level); + uint32_t index = TFQPI(free_level); + + uint32_t memory_offset = tx_buffer_start_addr + (tx_buffer_element_size * index); + + + uint32_t word_0 = 0; + uint32_t word_1 = 0; + uint32_t word_2 = 0; + + if (TXE -> ESI) word_0 |= (1 << ESI_SHFT); + if (TXE -> RTR) word_0 |= (1 << RTR_SHFT); + if (TXE -> XTD) + { + word_0 |= (1 << XTD_SHFT); + word_0 |= ((TXE -> ID) << XID_SHFT); + } + else + { + word_0 |= ((TXE -> ID) << SID_SHFT); + } + + spiRegisterWrite(memory_offset, word_0); + + word_1 |= ((TXE -> MM) << MM_SHFT); + + if (TXE -> EFC) word_1 |= (1 << EFC_SHFT); + if (TXE -> FDF) word_1 |= (1 << FDF_SHFT); + if (TXE -> BRS) word_1 |= (1 << BRS_SHFT); + + word_1 |= ((TXE -> DLC) << DLC_SHFT); + + spiRegisterWrite(memory_offset + WORD, word_1); + + word_2 |= ( ((TXE -> data_byte_0) << DB0_SHFT) | + ((TXE -> data_byte_1) << DB1_SHFT) | + ((TXE -> data_byte_2) << DB2_SHFT) | + ((TXE -> data_byte_3) << DB3_SHFT) ); + + spiRegisterWrite(memory_offset + 2*WORD, word_2); + + uint32_t add_request = 0; - uint16_t memory_offset = ; + add_request |= (1U << index); + spiRegisterWrite(TXBUF_AR, add_request); return 0; } diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index 6f520e3..c5f6624 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -374,7 +374,7 @@ typedef struct #define CAN_MODE 1 /// 0 - Bit Rate Switching disabled, 1 - enabled -#define BRS 1 +#define BIT_RATE_SWITCH 1 #define CCCR_BRSE (1U << 9U) /// 0 - Flexible Datarate disabled, 1 - enabled @@ -397,4 +397,48 @@ typedef struct #define TFFL(reg) ((reg) & TFFL_MASK) #define TFQPI_MAKS 0x1F0000 -#define TFQPI(reg) (((reg) & TFQPI_MAKS) >> 16U) \ No newline at end of file +#define TFQPI(reg) (((reg) & TFQPI_MAKS) >> 16U) + + +typedef struct +{ + // Word 0 + bool ESI; + bool XTD; + bool RTR; + uint16_t ID; + + // Word 1 + uint8_t MM; + bool EFC; + bool FDF; + bool BRS; + uint8_t DLC; + + // Word 2 + uint8_t data_byte_3; + uint8_t data_byte_2; + uint8_t data_byte_1; + uint8_t data_byte_0; + +} TXElement; + +#define ESI_SHFT 31U +#define XTD_SHFT 30U +#define RTR_SHFT 29U +#define SID_SHFT 18U +#define XID_SHFT 0U + +#define MM_SHFT 24U +#define EFC_SHFT 23U +#define FDF_SHFT 21U +#define BRS_SHFT 20U +#define DLC_SHFT 16U + +#define DB3_SHFT 24U +#define DB2_SHFT 16U +#define DB1_SHFT 8U +#define DB0_SHFT 0U + +#define WORD 0x4U + From 79fb399a0c72416925ee2802b391b15e2f106be8 Mon Sep 17 00:00:00 2001 From: Daniil Bragin Date: Sat, 15 Jun 2024 00:17:18 +0200 Subject: [PATCH 14/16] Updated main source code and added test dir --- TCAN4550/Testing/sketch_jun08a.ino | 94 ++++++ TCAN4550/Testing/ti_can.c | 316 ++++++++++++++++++++ TCAN4550/Testing/ti_can.h | 459 +++++++++++++++++++++++++++++ TCAN4550/ti_can.c | 14 +- TCAN4550/ti_can.h | 10 +- 5 files changed, 886 insertions(+), 7 deletions(-) create mode 100644 TCAN4550/Testing/sketch_jun08a.ino create mode 100644 TCAN4550/Testing/ti_can.c create mode 100644 TCAN4550/Testing/ti_can.h diff --git a/TCAN4550/Testing/sketch_jun08a.ino b/TCAN4550/Testing/sketch_jun08a.ino new file mode 100644 index 0000000..efc19c0 --- /dev/null +++ b/TCAN4550/Testing/sketch_jun08a.ino @@ -0,0 +1,94 @@ +#include +#include +#include "ti_can.h" +#include + +extern "C" void debug_print(const char* format, ...) { + char buffer[128]; // Adjust size as needed + va_list args; + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + Serial.println(buffer); +} + +extern "C" uint8_t spiRegisterWrite(uint32_t addr, uint32_t regValue) { + // Begin SPI transaction + SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); + + // Select your SPI slave device, if necessary + digitalWrite(SS, LOW); + + // Send address and register value + SPI.transfer(addr >> 8); // Send high byte of address + SPI.transfer(addr & 0xFF); // Send low byte of address + SPI.transfer(regValue >> 24); // Send high byte of register value + SPI.transfer((regValue >> 16) & 0xFF); // Send second byte of register value + SPI.transfer((regValue >> 8) & 0xFF); // Send third byte of register value + SPI.transfer(regValue & 0xFF); // Send low byte of register value + + // Deselect your SPI slave device, if necessary + digitalWrite(SS, HIGH); + + // End SPI transaction + SPI.endTransaction(); + + return 0; +} + +extern "C" uint32_t spiRegisterRead(uint32_t addr) { + uint32_t regValue = 0; + + // Begin SPI transaction + SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); + + // Select your SPI slave device, if necessary + digitalWrite(SS, LOW); + + // Send address to read from + SPI.transfer(addr >> 8); // Send high byte of address + SPI.transfer(addr & 0xFF); // Send low byte of address + + // Receive register value + regValue |= ((uint32_t)SPI.transfer(0) << 24); // Receive high byte of register value + regValue |= ((uint32_t)SPI.transfer(0) << 16); // Receive second byte of register value + regValue |= ((uint32_t)SPI.transfer(0) << 8); // Receive third byte of register value + regValue |= SPI.transfer(0); // Receive low byte of register value + + // Deselect your SPI slave device, if necessary + digitalWrite(SS, HIGH); + + // End SPI transaction + SPI.endTransaction(); + + return regValue; +} + + + +int main(void) +{ + init(); + Serial.begin(9600); + while(!Serial); + + // Test of lib START + + BitTimingParams * bTParams = NULL; + TiMRAMParams * MRAM = NULL; + + bTParams -> prescaler = 3; + bTParams -> prop_and_phase1 = 6; + bTParams -> phase2 = 1; + bTParams -> sync_jump_width = bTParams -> phase2; + //btParams -> tdc = ; + + + + // Test of lib END + + + + delay(1000); + return 0; +}} diff --git a/TCAN4550/Testing/ti_can.c b/TCAN4550/Testing/ti_can.c new file mode 100644 index 0000000..5ecea50 --- /dev/null +++ b/TCAN4550/Testing/ti_can.c @@ -0,0 +1,316 @@ +/// +/// Author: Daniil Bragin +/// Reference: + +#include +#include "ti_can.h" +#include +#include +#include // For testing purposes + +void test_func() +{ + int i = 5; + + debug_print("Test %d", i); +} + + + +uint8_t initCAN (const BitTimingParams * bTParams, + const TiMRAMParams * MRAM) +{ + + // Standby Mode Check + if ((spiRegisterRead(MODE_SEL)) != STANDBY_MODE) + { + spiRegisterWrite(MODE_SEL, STANDBY_MODE); + } + + // Initialization Mode + // TODO: Check whether CSR needs to be written before CCE and INIT + uint32_t init = spiRegisterRead(CCCR); + init |= (CAN_CCCR_CCE | CAN_CCCR_INIT); + init &= ~CAN_CCCR_CSR; + + uint32_t bit_timing = 0; + uint32_t trans_delay_comp = 0; + + uint8_t prescaler = bTParams -> prescaler; + uint8_t prop_and_phase1 = bTParams -> prop_and_phase1; + uint8_t phase2 = bTParams -> phase2; + uint8_t sync_jump_width = bTParams -> sync_jump_width; + uint8_t tdc = bTParams -> tdc; + + + // FD/BRS & Bit Timing Init Cofiguration + if (CAN_MODE == 0) + { + spiRegisterWrite(CCCR, init); + + bit_timing = spiRegisterRead(NBTP); + + // Reset the NBTP register values + bit_timing &= ~(CAN_NBTP_NSJW_MASK | + CAN_NBTP_NTSEG1_MASK | + CAN_NBTP_NTSEG2_MASK | + CAN_NBTP_NBRP_MASK); + + // Set the NBTP register values based on the provided settings + bit_timing |= CAN_SYNC_JUMP_WIDTH(sync_jump_width); + bit_timing |= CAN_TIME_SEG_1(prop_and_phase1); + bit_timing |= CAN_TIME_SEG_2(phase2); + bit_timing |= CAN_PRESCALER(prescaler); + + spiRegisterWrite(NBTP, bit_timing); + + } + else if (CAN_MODE == 1) + { + // Check BRS and FD settings + if (BIT_RATE_SWITCH) init |= CCCR_BRSE; + if (FD) init |= CCCR_FDOE; + + spiRegisterWrite(CCCR, init); + + bit_timing = spiRegisterRead(DBTP); + trans_delay_comp = spiRegisterRead(TDCR); + + // Reset the DBTP register values + bit_timing &= ~(CANFD_DBTP_DSJW_MASK | + CANFD_DBTP_DTSEG1_MASK | + CANFD_DBTP_DTSEG2_MASK | + CANFD_DBTP_DBRP_MASK); + + trans_delay_comp &= ~CANFD_TDCR_TDCO_MASK; + + // Set the DBTP register values based on the provided settings + bit_timing |= CANFD_SYNC_JUMP_WIDTH(sync_jump_width); + bit_timing |= CANFD_TIME_SEG_1_WIDTH(prop_and_phase1); + bit_timing |= CANFD_TIME_SEG_2_WIDTH(phase2); + bit_timing |= CANFD_PRESCALER(prescaler); + + trans_delay_comp |= CANFD_DELAY_COMPENSATION_OFFSET(tdc); + + spiRegisterWrite(DBTP, bit_timing); + + spiRegisterWrite(TDCR, trans_delay_comp); + } + + // MRAM Init + + uint32_t sid = spiRegisterRead(SIDFC); + uint32_t xid = spiRegisterRead(XIDFC); + uint32_t rxf0 = spiRegisterRead(RXF0C); + uint32_t rxf1 = spiRegisterRead(RXF1C); + uint32_t rxb = spiRegisterRead(RXBC); + uint32_t rx = spiRegisterRead(RXESC); + uint32_t tx_fifo = spiRegisterRead(TXEFC); + uint32_t txb = spiRegisterRead(TXBC); + uint32_t tx = spiRegisterRead(TXESC); + + sid &= ~(SID_LSS_MASK | + SID_FLSS_MASK); + + sid |= SID_LSS(MRAM -> SID_LSS); + sid |= SID_FLSS(MRAM -> SID_FLSS); + + + xid &= ~(XID_LSE_MASK | + XID_FLSEA_MASK); + + xid |= XID_LSE(MRAM -> XID_LSE); + xid |= XID_FLSEA(MRAM -> XID_FLSEA); + + + rxf0 &= ~(RXF0_F0OM_MASK | + RXF0_F0WM_MASK | + RXF0_F0S_MASK | + RXF0_F0SA_MASK); + + rxf0 |= RXF0_F0OM(MRAM -> RXF0_F0OM); + rxf0 |= RXF0_F0WM(MRAM -> RXF0_F0WM); + rxf0 |= RXF0_F0S(MRAM -> RXF0_F0S); + rxf0 |= RXF0_F0SA(MRAM -> RXF0_F0SA); + + + rxf1 &= ~(RXF1_F1OM_MASK | + RXF1_F1WM_MASK | + RXF1_F1S_MASK | + RXF1_F1SA_MASK); + + rxf1 |= RXF1_F1OM(MRAM -> RXF1_F1OM); + rxf1 |= RXF1_F1WM(MRAM -> RXF1_F1WM); + rxf1 |= RXF1_F1S(MRAM -> RXF1_F1S); + rxf1 |= RXF1_F1SA(MRAM -> RXF1_F1SA); + + + rxb &= ~(RXB_RBSA_MASK); + + rxb |= RXB_RBSA(MRAM -> RXB_RBSA); + + + rx &= ~(RX_RBDS_MASK | + RX_F1DS_MASK | + RX_F0DS_MASK); + + rx |= RX_RBDS(MRAM -> RX_RBDS); + rx |= RX_F1DS(MRAM -> RX_F1DS); + rx |= RX_F0DS(MRAM -> RX_F0DS); + + + tx_fifo &= ~(TXEVF_EFWM_MASK | + TXEVF_EFS_MASK | + TXEVF_EFSA_MASK); + + tx_fifo |= TXEVF_EFWM(MRAM -> TXEVF_EFWM); + tx_fifo |= TXEVF_EFS(MRAM -> TXEVF_EFS); + tx_fifo |= TXEVF_EFSA(MRAM -> TXEVF_EFSA); + + + txb &= ~(TXB_TFQM_MASK | + TXB_TFQS_MASK | + TXB_NDTB_MASK | + TXB_TBSA_MASK); + + txb |= TXB_TFQM(MRAM -> TXB_TFQM); + txb |= TXB_TFQS(MRAM -> TXB_TFQS); + txb |= TXB_NDTB(MRAM -> TXB_NDTB); + txb |= TXB_TBSA(MRAM -> TXB_TBSA); + + + tx &= ~(TX_TBDS_MASK); + + tx |= TX_TBDS(MRAM -> TX_TBDS); + + + spiRegisterWrite(SIDFC, sid); + spiRegisterWrite(XIDFC, xid); + spiRegisterWrite(RXF0C, rxf0); + spiRegisterWrite(RXF1C, rxf1); + spiRegisterWrite(RXBC, rxb); + spiRegisterWrite(RXESC, rx); + spiRegisterWrite(TXEFC, tx_fifo); + spiRegisterWrite(TXBC, txb); + spiRegisterWrite(TXESC, tx); + + + // Put the TCAN45xx device into "NORMAL" mode + spiRegisterWrite(MODE_SEL, NORMAL_MODE); + + + return 0; +} + +uint8_t setSIDFilters(SID_filter * filters, TiMRAMParams * MRAM) +{ + size_t size = (size_t) MRAM -> SID_LSS; + uint32_t * filter_addr = (uint32_t *)MRAM -> SID_FLSS; + uint32_t filter = 0; + + for (size_t i = 0; i < size; i++) + { + filter = 0; + + filter |= SID_SFT (filters[i].SFT); + filter |= SID_SFEC (filters[i].SFEC); + filter |= SID_SFID1 (filters[i].SFID_1); + filter |= SID_SFID2 (filters[i].SFID_2); + + spiRegisterWrite(filter_addr + i * sizeof(uint32_t), filter); + } + + return 0; +} + +uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM) +{ + size_t size = (size_t) MRAM -> XID_LSE; + uint32_t filter_addr = MRAM -> XID_FLSEA; + uint64_t filter = 0; // Two words needed for XID + uint32_t filter_1 = 0; + uint32_t filter_2 = 0; + + for (size_t i = 0; i < size; i++) + { + filter = 0; + filter_1 = 0; + filter_2 = 0; + + filter_1 |= XID_EFID2(filters[i].EFID2); + filter_1 |= XID_EFT(filters[i].EFT); + + filter_2 |= XID_EFID2(filters[i].EFID2); + filter_2 |= XID_EFEC(filters[i].EFEC); + + filter |= (filter_1 | filter_2); + + spiRegisterWrite(filter_addr + i * sizeof(uint32_t), filter); + } + + return 0; +} + +uint8_t sendCAN(TiMRAMParams * MRAM, TXElement * TXE) +{ + // Check that any TX Buffer is vacant + uint32_t free_level = spiRegisterRead(TXFQS); + + uint32_t tx_buffer_start_addr = MRAM -> TXB_TBSA; + uint32_t tx_buffer_element_size = MRAM -> TX_TBDS + 8; // Additional 8 bytes of header + + + + if (!(TFFL(free_level))) + { + return 1; + } + + uint32_t index = TFQPI(free_level); + + uint32_t memory_offset = tx_buffer_start_addr + (tx_buffer_element_size * index); + + + uint32_t word_0 = 0; + uint32_t word_1 = 0; + uint32_t word_2 = 0; + + if (TXE -> ESI) word_0 |= (1 << ESI_SHFT); + if (TXE -> RTR) word_0 |= (1 << RTR_SHFT); + if (TXE -> XTD) + { + word_0 |= (1 << XTD_SHFT); + word_0 |= ((TXE -> ID) << XID_SHFT); + } + else + { + word_0 |= ((TXE -> ID) << SID_SHFT); + } + + spiRegisterWrite(memory_offset, word_0); + + word_1 |= ((TXE -> MM) << MM_SHFT); + + if (TXE -> EFC) word_1 |= (1 << EFC_SHFT); + if (TXE -> FDF) word_1 |= (1 << FDF_SHFT); + if (TXE -> BRS) word_1 |= (1 << BRS_SHFT); + + word_1 |= ((TXE -> DLC) << DLC_SHFT); + + spiRegisterWrite(memory_offset + WORD, word_1); + + word_2 |= ( ((TXE -> data_byte_0) << DB0_SHFT) | + ((TXE -> data_byte_1) << DB1_SHFT) | + ((TXE -> data_byte_2) << DB2_SHFT) | + ((TXE -> data_byte_3) << DB3_SHFT) ); + + spiRegisterWrite(memory_offset + 2*WORD, word_2); + + uint32_t add_request = 0; + + add_request |= (1U << index); + + spiRegisterWrite(TXBUF_AR, add_request); + + return 0; +} diff --git a/TCAN4550/Testing/ti_can.h b/TCAN4550/Testing/ti_can.h new file mode 100644 index 0000000..e78f370 --- /dev/null +++ b/TCAN4550/Testing/ti_can.h @@ -0,0 +1,459 @@ +/// ____ ______ __ __ +/// / __ `____ ___ ____ / ____/_ ______ / /_ ____ / / +/// / / / / __ `/ _ `/ __ `/ / / / / / __ `/ __ `/ __ `/ / +/// / /_/ / /_/ / __/ / / / /___/ /_/ / /_/ / / / / /_/ / / +/// `____/ .___/`___/_/ /_/`____/`__, / .___/_/ /_/`__,_/_/ +/// /_/ /____/_/ +/// +/// A low-level driver with the main purpose of helping new hardware revisions or new designs adopt CAN FD +/// without having to port an existing codebase to a new platform. +/// +/// Author: Daniil Bragin +/// + + +#pragma once + +#include // For testing purposes +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////// + +/// BIT TIMING VALUES + +// FOR CAN +#define NBTP 0x101C + +#define CAN_NBTP_NSJW_SHFT (25U) +#define CAN_NBTP_NSJW_MASK (0x7FU << CAN_NBTP_NSJW_SHFT) +#define CAN_SYNC_JUMP_WIDTH(x) ((uint8_t)(x) << CAN_NBTP_NSJW_SHFT) + +#define CAN_NBTP_NTSEG1_SHFT (8U) +#define CAN_NBTP_NTSEG1_MASK (0xFFU << CAN_NBTP_NTSEG1_SHFT) +#define CAN_TIME_SEG_1(x) ((uint8_t)(x) << CAN_NBTP_NTSEG1_SHFT) + +#define CAN_NBTP_NTSEG2_SHFT (0U) +#define CAN_NBTP_NTSEG2_MASK (0x7FU << CAN_NBTP_NTSEG2_SHFT) +#define CAN_TIME_SEG_2(x) ((uint8_t)(x) << CAN_NBTP_NTSEG2_SHFT) + +#define CAN_NBTP_NBRP_SHFT (24U) +#define CAN_NBTP_NBRP_MASK (0x1U << CAN_NBTP_NBRP_SHFT) +#define CAN_PRESCALER(x) ((uint8_t)(x) << CAN_NBTP_NBRP_SHFT) + +// FOR CAN-FD +#define DBTP 0x100C +#define TDCR 0x1048 // Transmission Delay Compensation Register + +#define CANFD_DBTP_DSJW_SHFT (0U) +#define CANFD_DBTP_DSJW_MASK (0xFU << CANFD_DBTP_DSJW_SHFT) +#define CANFD_SYNC_JUMP_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DSJW_SHFT) + +#define CANFD_DBTP_DTSEG1_SHFT (8U) +#define CANFD_DBTP_DTSEG1_MASK (0x1FU << CANFD_DBTP_DTSEG1_SHFT) +#define CANFD_TIME_SEG_1_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DTSEG1_SHFT) + +#define CANFD_DBTP_DTSEG2_SHFT (4U) +#define CANFD_DBTP_DTSEG2_MASK (0xFU << CANFD_DBTP_DTSEG2_SHFT) +#define CANFD_TIME_SEG_2_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DTSEG2_SHFT) + +#define CANFD_DBTP_DBRP_SHFT (16U) +#define CANFD_DBTP_DBRP_MASK (0xFU << CANFD_DBTP_DBRP_SHFT) +#define CANFD_PRESCALER(x) ((uint8_t)(x) << CANFD_DBTP_DBRP_SHFT) + +#define CANFD_TDCR_TDCO_SHFT (8U) +#define CANFD_TDCR_TDCO_MASK (0x7FU << CANFD_TDCR_TDCO_SHFT) +#define CANFD_DELAY_COMPENSATION_OFFSET(x) ((uint8_t)(x) << CANFD_TDCR_TDCO_SHFT) + +// Bit Timing Parameters +typedef struct +{ + uint8_t prescaler; + uint8_t prop_and_phase1; + uint8_t phase2; + uint8_t sync_jump_width; + uint8_t tdc; +} BitTimingParams; + +/////////////////////////////////////////////////////////////////////////////////////////// + +/// MESSAGE RAM + +// MRAM Registers' Addresses +#define SIDFC 0x1084 // 11-bit Filter (SID Filter) +#define XIDFC 0x1088 // 29-bit Filter (XID Filter) +#define RXF0C 0x10A0 // Rx FIFO 0 +#define RXF1C 0x10B0 // Rx FIFO 1 +#define RXBC 0x10AC // Rx Buffers +#define RXESC 0x10BC // Rx Element Size Config +#define TXEFC 0x10F0 // Tx Event FIFO +#define TXBC 0x10C0 // Tx Buffers +#define TXESC 0x10C8 // Tx Element Size Config + +// MRAM Params Bits + +// SID +#define SID_LSS_SHFT (16U) +#define SID_LSS_MASK (0xFFU << SID_LSS_SHFT) +#define SID_LSS(x) ((uint8_t)(x) << SID_LSS_SHFT) + +#define SID_FLSS_SHFT (0U) +#define SID_FLSS_MASK (0xFFFFU << SID_LSS_SHFT) +#define SID_FLSS(x) ((uint8_t)(x) << SID_LSS_SHFT) + + +// XID +#define XID_LSE_SHFT (16U) +#define XID_LSE_MASK (0x7FU << XID_LSE_SHFT) +#define XID_LSE(x) ((uint8_t)(x) << XID_LSE_SHFT) + + +#define XID_FLSEA_SHFT (16U) +#define XID_FLSEA_MASK (0xFFFFU << XID_FLSEA_SHFT) +#define XID_FLSEA(x) ((uint8_t)(x) << XID_FLSEA_SHFT) + + +// Rx FIFO 0 +#define RXF0_F0OM_SHFT (31U) +#define RXF0_F0OM_MASK (0x1U << RXF0_F0OM_SHFT) +#define RXF0_F0OM(x) ((uint8_t)(x) << RXF0_F0OM_SHFT) + +#define RXF0_F0WM_SHFT (24U) +#define RXF0_F0WM_MASK (0x7FU << RXF0_F0WM_SHFT) +#define RXF0_F0WM(x) ((uint8_t)(x) << RXF0_F0WM_SHFT) + +#define RXF0_F0S_SHFT (16U) +#define RXF0_F0S_MASK (0x7FU << RXF0_F0S_SHFT) +#define RXF0_F0S(x) ((uint8_t)(x) << RXF0_F0S_SHFT) + +#define RXF0_F0SA_SHFT (0U) +#define RXF0_F0SA_MASK (0xFFFFU << RXF0_F0SA_SHFT) +#define RXF0_F0SA(x) ((uint8_t)(x) << RXF0_F0SA_SHFT) + + +// Rx FIFO 1 +#define RXF1_F1OM_SHFT (31U) +#define RXF1_F1OM_MASK (0x1U << RXF1_F1OM_SHFT) +#define RXF1_F1OM(x) ((uint8_t)(x) << RXF1_F1OM_SHFT) + +#define RXF1_F1WM_SHFT (24U) +#define RXF1_F1WM_MASK (0x7FU << RXF1_F1WM_SHFT) +#define RXF1_F1WM(x) ((uint8_t)(x) << RXF1_F1WM_SHFT) + +#define RXF1_F1S_SHFT (16U) +#define RXF1_F1S_MASK (0x7FU << RXF1_F1S_SHFT) +#define RXF1_F1S(x) ((uint8_t)(x) << RXF1_F1S_SHFT) + +#define RXF1_F1SA_SHFT (0U) +#define RXF1_F1SA_MASK (0xFFFFU << RXF1_F1SA_SHFT) +#define RXF1_F1SA(x) ((uint8_t)(x) << RXF1_F1SA_SHFT) + + +// Rx Buffer +#define RXB_RBSA_SHFT (0U) +#define RXB_RBSA_MASK (0xFFFFU << RXB_RBSA_SHFT) +#define RXB_RBSA(x) ((uint8_t)(x) << RXB_RBSA_SHFT) + + +// Rx Element Size Config +#define RX_RBDS_SHFT (8U) +#define RX_RBDS_MASK (0x7U << RX_RBDS_SHFT) +#define RX_RBDS(x) ((uint8_t)(x) << RX_RBDS_SHFT) + +#define RX_F1DS_SHFT (4U) +#define RX_F1DS_MASK (0x7U << RX_F1DS_SHFT) +#define RX_F1DS(x) ((uint8_t)(x) << RX_F1DS_SHFT) + +#define RX_F0DS_SHFT (0U) +#define RX_F0DS_MASK (0x7U << RX_F0DS_SHFT) +#define RX_F0DS(x) ((uint8_t)(x) << RX_F0DS_SHFT) + + +// Tx Event FIFO Config +#define TXEVF_EFWM_SHFT (24U) +#define TXEVF_EFWM_MASK (0x3FU << TXEVF_EFWM_SHFT) +#define TXEVF_EFWM(x) ((uint8_t)(x) << TXEVF_EFWM_SHFT) + +#define TXEVF_EFS_SHFT (16U) +#define TXEVF_EFS_MASK (0x3FU << TXEVF_EFS_SHFT) +#define TXEVF_EFS(x) ((uint8_t)(x) << TXEVF_EFS_SHFT) + +#define TXEVF_EFSA_SHFT (0U) +#define TXEVF_EFSA_MASK (0xFFFFU << TXEVF_EFSA_SHFT) +#define TXEVF_EFSA(x) ((uint8_t)(x) << TXEVF_EFSA_SHFT) + + +// Tx Buffer Config +#define TXB_TFQM_SHFT (30U) +#define TXB_TFQM_MASK (0x1U << TXB_TFQM_SHFT) +#define TXB_TFQM(x) ((uint8_t)(x) << TXB_TFQM_SHFT) + +#define TXB_TFQS_SHFT (24U) +#define TXB_TFQS_MASK (0x3FU << TXB_TFQS_SHFT) +#define TXB_TFQS(x) ((uint8_t)(x) << TXB_TFQS_SHFT) + +#define TXB_NDTB_SHFT (16U) +#define TXB_NDTB_MASK (0x3FU << TXB_NDTB_SHFT) +#define TXB_NDTB(x) ((uint8_t)(x) << TXB_NDTB_SHFT) + +#define TXB_TBSA_SHFT (0U) +#define TXB_TBSA_MASK (0xFFFFU << TXB_TBSA_SHFT) +#define TXB_TBSA(x) ((uint8_t)(x) << TXB_TBSA_SHFT) + + +// TX Element Size Config +#define TX_TBDS_SHFT (0U) +#define TX_TBDS_MASK (0x7U << TX_TBDS_SHFT) +#define TX_TBDS(x) ((uint8_t)(x) << TX_TBDS_SHFT) + + + +// Message RAM Design Parameters + +// MDS = Maximum Data Size +// BPE = Bytes Per Element +// NOE = Number Of Elements + +typedef struct +{ + // SID + uint32_t SID_LSS; + uint32_t SID_FLSS; + + // XID + uint32_t XID_LSE; + uint32_t XID_FLSEA; + + // Rx FIFO 0 + uint32_t RXF0_F0OM; + uint32_t RXF0_F0WM; + uint32_t RXF0_F0S; + uint32_t RXF0_F0SA; + + // Rx FIFO 1 + uint32_t RXF1_F1OM; + uint32_t RXF1_F1WM; + uint32_t RXF1_F1S; + uint32_t RXF1_F1SA; + + // Rx Buffer + uint32_t RXB_RBSA; + + // Rx Element Size Config + uint32_t RX_RBDS; + uint32_t RX_F1DS; + uint32_t RX_F0DS; + + // Tx Event FIFO Config + uint32_t TXEVF_EFWM; + uint32_t TXEVF_EFS; + uint32_t TXEVF_EFSA; + + // Tx Buffer Config + uint32_t TXB_TFQM; + uint32_t TXB_TFQS; + uint32_t TXB_NDTB; + uint32_t TXB_TBSA; + + // TX Element Size Config + uint32_t TX_TBDS; + +} TiMRAMParams; + +// Filters Configuration: SID and XID (Standard and Extended) + +typedef struct +{ + // In classic mode: SFID_1 = ID, SFID_2 = MASK + + uint16_t SFID_1; + uint16_t SFID_2; + uint8_t SFT; + uint8_t SFEC; + +} SID_filter; + + +// SID Filter Type +#define SID_SFT_SHFT (30U) +#define SID_SFT(x) ((uint8_t)(x) << SID_SFT_SHFT) + +// Options for the SID & XID filter type +#define RANGE_FILTER 0b00U +#define DUAL_ID_FILTER 0b01U +#define CLASSIC_FILTER 0b10U +#define FILTER_ELEMENT_DISABLED 0b11U + +// Standard Element Filter Configuration +#define SID_SFEC_SHFT (27U) +#define SID_SFEC(x) ((uint8_t)(x) << SID_SFEC_SHFT) + +// Options for the element configuration +#define DISABLE_FILTER_ELEMENT 0b000U +#define STORE_RX_FIFO_0 0b001U +#define STORE_RX_FIFO_1 0b010U +#define REJECT_MESSAGE 0b011U +#define SET_AS_PRIO_MSG_DFLT 0b100U +#define SET_AS_PRIO_FIFO_0 0b101U +#define SET_AS_PRIO_FIFO_1 0b110U + +// Store into Rx Buffer or as debug message. If this is used, SFT is ignored and SFID1 is the filter. SFID2[10:9] +// describes where to store message, SFID2[5:0] describes which Rx Buffer to put the message (must be within +// the Rx Buffer configuration +#define STORE_RX_BUF 0b111U + + +#define SID_SFID1_SHFT (16U) +#define SID_SFID1_MASK (0x7FFU) +#define SID_SFID1(x) (((uint32_t)(x) & SID_SFID1_MASK) << SID_SFID1_SHFT) + +#define SID_SFID2_SHFT (0U) +#define SID_SFID2_MASK (0x7FFU) +#define SID_SFID2(x) (((uint32_t)(x) & SID_SFID2_MASK) << SID_SFID2_SHFT) + + +typedef struct +{ + + uint32_t EFID1; + uint32_t EFID2; + uint8_t EFT; // For type use same options as for SID + uint8_t EFEC; + +} XID_filter; + +// Word 0 + +#define XID_EFEC_SHFT (29U) +#define XID_EFEC(x) ((uint8_t)(x) << XID_EFEC_SHFT) + +#define XID_EFID1_SHFT (0U) +#define XID_EFID1_MASK (0x1FFFFFFF) +#define XID_EFID1(x) (((uint32_t)(x) & XID_EFID1_MASK) << XID_EFID1_SHFT) + +// Word 1 + +#define XID_EFT_SHFT (30U) +#define XID_EFT(x) ((uint8_t)(x) << XID_EFT_SHFT) + +#define XID_EFID2_SHFT (0U) +#define XID_EFID2_MASK (0x1FFFFFFF) +#define XID_EFID2(x) (((uint32_t)(x) & XID_EFID2_MASK) << XID_EFID2_SHFT) + + + + +/////////////////////////////////////////////////////////////////////////////////////////// + +/// Device Initialization Mode + +// Device Mode Selection Register Address +#define MODE_SEL 0x0800 + +// Available Device Modes +#define STANDBY_MODE (0b01 << 6U) +#define NORMAL_MODE (0b10 << 6U) + +// CC Control Register Address +#define CCCR 0x1018 + +// Bits Necessary For Initialization +#define CAN_CCCR_INIT (1U << 0U) +#define CAN_CCCR_CCE (1U << 1U) +#define CAN_CCCR_CSR (1U << 4U) + +/// 0 - CAN, 1 - CAN FD +#define CAN_MODE 0 + +/// 0 - Bit Rate Switching disabled, 1 - enabled +#define BIT_RATE_SWITCH 1 +#define CCCR_BRSE (1U << 9U) + +/// 0 - Flexible Datarate disabled, 1 - enabled +#define FD 1 +#define CCCR_FDOE (1U << 8U) + +/////////////////////////////////////////////////////////////////////////////////////////// + +/// Message Sending + +#define TXFQS 0x10C4 // Tx FIFO/Queue Status register + +#define TXBUF_AR 0x10D0 // Tx Buffer Add Request Register + +// Set on of the bits in TXBUF_AR to request the +// data to be sent from the corresponding TX Buffer + + +#define TFFL_MASK 0x1FU +#define TFFL(reg) ((reg) & TFFL_MASK) + +#define TFQPI_MAKS 0x1F0000 +#define TFQPI(reg) (((reg) & TFQPI_MAKS) >> 16U) + + +typedef struct +{ + // Word 0 + bool ESI; + bool XTD; + bool RTR; + uint16_t ID; + + // Word 1 + uint8_t MM; + bool EFC; + bool FDF; + bool BRS; + uint8_t DLC; + + // Word 2 + uint8_t data_byte_3; + uint8_t data_byte_2; + uint8_t data_byte_1; + uint8_t data_byte_0; + +} TXElement; + +#define ESI_SHFT 31U +#define XTD_SHFT 30U +#define RTR_SHFT 29U +#define SID_SHFT 18U +#define XID_SHFT 0U + +#define MM_SHFT 24U +#define EFC_SHFT 23U +#define FDF_SHFT 21U +#define BRS_SHFT 20U +#define DLC_SHFT 16U + +#define DB3_SHFT 24U +#define DB2_SHFT 16U +#define DB1_SHFT 8U +#define DB0_SHFT 0U + +#define WORD 0x4U + +void test_func(); +void debug_print(const char* format, ...); +uint8_t spiRegisterWrite(uint32_t addr, + uint32_t regValue); + +uint32_t spiRegisterRead(uint32_t addr); +uint8_t initCAN (const BitTimingParams * bTParams, + const TiMRAMParams * MRAM); +uint8_t setSIDFilters(SID_filter * filters, TiMRAMParams * MRAM); +uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM); +uint8_t sendCAN(TiMRAMParams * MRAM, TXElement * TXE); diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c index 3b75d6c..f7c9329 100644 --- a/TCAN4550/ti_can.c +++ b/TCAN4550/ti_can.c @@ -18,6 +18,8 @@ uint8_t spiRegisterWrite(uint32_t addr, * */ + // + return 0; } @@ -38,6 +40,8 @@ uint8_t initCAN (const BitTimingParams * bTParams, const TiMRAMParams * MRAM) { + // TODO: Cover edge cases for values in structs + error reporting + // Standby Mode Check if ((spiRegisterRead(MODE_SEL)) != STANDBY_MODE) { @@ -48,7 +52,7 @@ uint8_t initCAN (const BitTimingParams * bTParams, // TODO: Check whether CSR needs to be written before CCE and INIT uint32_t init = spiRegisterRead(CCCR); init |= (CAN_CCCR_CCE | CAN_CCCR_INIT); - init &= ~CAN_CCCR_CSR; + init &= ~CAN_CCCR_CSR; uint32_t bit_timing = 0; uint32_t trans_delay_comp = 0; @@ -254,7 +258,7 @@ uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM) filter_1 = 0; filter_2 = 0; - filter_1 |= XID_EFID2(filters[i].EFID2); + filter_1 |= XID_EFID2(filters[i].EFID1); filter_1 |= XID_EFT(filters[i].EFT); filter_2 |= XID_EFID2(filters[i].EFID2); @@ -262,7 +266,7 @@ uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM) filter |= (filter_1 | filter_2); - spiRegisterWrite(filter_addr + i * sizeof(uint32_t), filter); + spiRegisterWrite(filter_addr + i, filter); } return 0; @@ -314,14 +318,14 @@ uint8_t sendCAN(TiMRAMParams * MRAM, TXElement * TXE) word_1 |= ((TXE -> DLC) << DLC_SHFT); - spiRegisterWrite(memory_offset + WORD, word_1); + spiRegisterWrite(memory_offset + sizeof(word_0), word_1); word_2 |= ( ((TXE -> data_byte_0) << DB0_SHFT) | ((TXE -> data_byte_1) << DB1_SHFT) | ((TXE -> data_byte_2) << DB2_SHFT) | ((TXE -> data_byte_3) << DB3_SHFT) ); - spiRegisterWrite(memory_offset + 2*WORD, word_2); + spiRegisterWrite(memory_offset + sizeof(word_0) + sizeof(word_1), word_2); uint32_t add_request = 0; diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index c5f6624..2c5f9c1 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -9,7 +9,7 @@ /// without having to port an existing codebase to a new platform. /// /// Author: Daniil Bragin -/// +/// Reference: #pragma once @@ -24,7 +24,13 @@ extern "C" { /////////////////////////////////////////////////////////////////////////////////////////// - +// TODO: Fix naming convention +// Naming convention: +// CAN_NBTP_NSJW_MASK: +// NBTP is a register +// NSJW is a bit +// CAN means that it is meant for CAN +// MASK is its purpose /////////////////////////////////////////////////////////////////////////////////////////// From 10fe316c4fde675f0a985a4c2ce775bbe6ed8a23 Mon Sep 17 00:00:00 2001 From: Daniil Bragin Date: Wed, 26 Jun 2024 10:17:04 +0200 Subject: [PATCH 15/16] Deleted arduino tests --- TCAN4550/Testing/sketch_jun08a.ino | 94 ------ TCAN4550/Testing/ti_can.c | 316 -------------------- TCAN4550/Testing/ti_can.h | 459 ----------------------------- 3 files changed, 869 deletions(-) delete mode 100644 TCAN4550/Testing/sketch_jun08a.ino delete mode 100644 TCAN4550/Testing/ti_can.c delete mode 100644 TCAN4550/Testing/ti_can.h diff --git a/TCAN4550/Testing/sketch_jun08a.ino b/TCAN4550/Testing/sketch_jun08a.ino deleted file mode 100644 index efc19c0..0000000 --- a/TCAN4550/Testing/sketch_jun08a.ino +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include "ti_can.h" -#include - -extern "C" void debug_print(const char* format, ...) { - char buffer[128]; // Adjust size as needed - va_list args; - va_start(args, format); - vsnprintf(buffer, sizeof(buffer), format, args); - va_end(args); - Serial.println(buffer); -} - -extern "C" uint8_t spiRegisterWrite(uint32_t addr, uint32_t regValue) { - // Begin SPI transaction - SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); - - // Select your SPI slave device, if necessary - digitalWrite(SS, LOW); - - // Send address and register value - SPI.transfer(addr >> 8); // Send high byte of address - SPI.transfer(addr & 0xFF); // Send low byte of address - SPI.transfer(regValue >> 24); // Send high byte of register value - SPI.transfer((regValue >> 16) & 0xFF); // Send second byte of register value - SPI.transfer((regValue >> 8) & 0xFF); // Send third byte of register value - SPI.transfer(regValue & 0xFF); // Send low byte of register value - - // Deselect your SPI slave device, if necessary - digitalWrite(SS, HIGH); - - // End SPI transaction - SPI.endTransaction(); - - return 0; -} - -extern "C" uint32_t spiRegisterRead(uint32_t addr) { - uint32_t regValue = 0; - - // Begin SPI transaction - SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); - - // Select your SPI slave device, if necessary - digitalWrite(SS, LOW); - - // Send address to read from - SPI.transfer(addr >> 8); // Send high byte of address - SPI.transfer(addr & 0xFF); // Send low byte of address - - // Receive register value - regValue |= ((uint32_t)SPI.transfer(0) << 24); // Receive high byte of register value - regValue |= ((uint32_t)SPI.transfer(0) << 16); // Receive second byte of register value - regValue |= ((uint32_t)SPI.transfer(0) << 8); // Receive third byte of register value - regValue |= SPI.transfer(0); // Receive low byte of register value - - // Deselect your SPI slave device, if necessary - digitalWrite(SS, HIGH); - - // End SPI transaction - SPI.endTransaction(); - - return regValue; -} - - - -int main(void) -{ - init(); - Serial.begin(9600); - while(!Serial); - - // Test of lib START - - BitTimingParams * bTParams = NULL; - TiMRAMParams * MRAM = NULL; - - bTParams -> prescaler = 3; - bTParams -> prop_and_phase1 = 6; - bTParams -> phase2 = 1; - bTParams -> sync_jump_width = bTParams -> phase2; - //btParams -> tdc = ; - - - - // Test of lib END - - - - delay(1000); - return 0; -}} diff --git a/TCAN4550/Testing/ti_can.c b/TCAN4550/Testing/ti_can.c deleted file mode 100644 index 5ecea50..0000000 --- a/TCAN4550/Testing/ti_can.c +++ /dev/null @@ -1,316 +0,0 @@ -/// -/// Author: Daniil Bragin -/// Reference: - -#include -#include "ti_can.h" -#include -#include -#include // For testing purposes - -void test_func() -{ - int i = 5; - - debug_print("Test %d", i); -} - - - -uint8_t initCAN (const BitTimingParams * bTParams, - const TiMRAMParams * MRAM) -{ - - // Standby Mode Check - if ((spiRegisterRead(MODE_SEL)) != STANDBY_MODE) - { - spiRegisterWrite(MODE_SEL, STANDBY_MODE); - } - - // Initialization Mode - // TODO: Check whether CSR needs to be written before CCE and INIT - uint32_t init = spiRegisterRead(CCCR); - init |= (CAN_CCCR_CCE | CAN_CCCR_INIT); - init &= ~CAN_CCCR_CSR; - - uint32_t bit_timing = 0; - uint32_t trans_delay_comp = 0; - - uint8_t prescaler = bTParams -> prescaler; - uint8_t prop_and_phase1 = bTParams -> prop_and_phase1; - uint8_t phase2 = bTParams -> phase2; - uint8_t sync_jump_width = bTParams -> sync_jump_width; - uint8_t tdc = bTParams -> tdc; - - - // FD/BRS & Bit Timing Init Cofiguration - if (CAN_MODE == 0) - { - spiRegisterWrite(CCCR, init); - - bit_timing = spiRegisterRead(NBTP); - - // Reset the NBTP register values - bit_timing &= ~(CAN_NBTP_NSJW_MASK | - CAN_NBTP_NTSEG1_MASK | - CAN_NBTP_NTSEG2_MASK | - CAN_NBTP_NBRP_MASK); - - // Set the NBTP register values based on the provided settings - bit_timing |= CAN_SYNC_JUMP_WIDTH(sync_jump_width); - bit_timing |= CAN_TIME_SEG_1(prop_and_phase1); - bit_timing |= CAN_TIME_SEG_2(phase2); - bit_timing |= CAN_PRESCALER(prescaler); - - spiRegisterWrite(NBTP, bit_timing); - - } - else if (CAN_MODE == 1) - { - // Check BRS and FD settings - if (BIT_RATE_SWITCH) init |= CCCR_BRSE; - if (FD) init |= CCCR_FDOE; - - spiRegisterWrite(CCCR, init); - - bit_timing = spiRegisterRead(DBTP); - trans_delay_comp = spiRegisterRead(TDCR); - - // Reset the DBTP register values - bit_timing &= ~(CANFD_DBTP_DSJW_MASK | - CANFD_DBTP_DTSEG1_MASK | - CANFD_DBTP_DTSEG2_MASK | - CANFD_DBTP_DBRP_MASK); - - trans_delay_comp &= ~CANFD_TDCR_TDCO_MASK; - - // Set the DBTP register values based on the provided settings - bit_timing |= CANFD_SYNC_JUMP_WIDTH(sync_jump_width); - bit_timing |= CANFD_TIME_SEG_1_WIDTH(prop_and_phase1); - bit_timing |= CANFD_TIME_SEG_2_WIDTH(phase2); - bit_timing |= CANFD_PRESCALER(prescaler); - - trans_delay_comp |= CANFD_DELAY_COMPENSATION_OFFSET(tdc); - - spiRegisterWrite(DBTP, bit_timing); - - spiRegisterWrite(TDCR, trans_delay_comp); - } - - // MRAM Init - - uint32_t sid = spiRegisterRead(SIDFC); - uint32_t xid = spiRegisterRead(XIDFC); - uint32_t rxf0 = spiRegisterRead(RXF0C); - uint32_t rxf1 = spiRegisterRead(RXF1C); - uint32_t rxb = spiRegisterRead(RXBC); - uint32_t rx = spiRegisterRead(RXESC); - uint32_t tx_fifo = spiRegisterRead(TXEFC); - uint32_t txb = spiRegisterRead(TXBC); - uint32_t tx = spiRegisterRead(TXESC); - - sid &= ~(SID_LSS_MASK | - SID_FLSS_MASK); - - sid |= SID_LSS(MRAM -> SID_LSS); - sid |= SID_FLSS(MRAM -> SID_FLSS); - - - xid &= ~(XID_LSE_MASK | - XID_FLSEA_MASK); - - xid |= XID_LSE(MRAM -> XID_LSE); - xid |= XID_FLSEA(MRAM -> XID_FLSEA); - - - rxf0 &= ~(RXF0_F0OM_MASK | - RXF0_F0WM_MASK | - RXF0_F0S_MASK | - RXF0_F0SA_MASK); - - rxf0 |= RXF0_F0OM(MRAM -> RXF0_F0OM); - rxf0 |= RXF0_F0WM(MRAM -> RXF0_F0WM); - rxf0 |= RXF0_F0S(MRAM -> RXF0_F0S); - rxf0 |= RXF0_F0SA(MRAM -> RXF0_F0SA); - - - rxf1 &= ~(RXF1_F1OM_MASK | - RXF1_F1WM_MASK | - RXF1_F1S_MASK | - RXF1_F1SA_MASK); - - rxf1 |= RXF1_F1OM(MRAM -> RXF1_F1OM); - rxf1 |= RXF1_F1WM(MRAM -> RXF1_F1WM); - rxf1 |= RXF1_F1S(MRAM -> RXF1_F1S); - rxf1 |= RXF1_F1SA(MRAM -> RXF1_F1SA); - - - rxb &= ~(RXB_RBSA_MASK); - - rxb |= RXB_RBSA(MRAM -> RXB_RBSA); - - - rx &= ~(RX_RBDS_MASK | - RX_F1DS_MASK | - RX_F0DS_MASK); - - rx |= RX_RBDS(MRAM -> RX_RBDS); - rx |= RX_F1DS(MRAM -> RX_F1DS); - rx |= RX_F0DS(MRAM -> RX_F0DS); - - - tx_fifo &= ~(TXEVF_EFWM_MASK | - TXEVF_EFS_MASK | - TXEVF_EFSA_MASK); - - tx_fifo |= TXEVF_EFWM(MRAM -> TXEVF_EFWM); - tx_fifo |= TXEVF_EFS(MRAM -> TXEVF_EFS); - tx_fifo |= TXEVF_EFSA(MRAM -> TXEVF_EFSA); - - - txb &= ~(TXB_TFQM_MASK | - TXB_TFQS_MASK | - TXB_NDTB_MASK | - TXB_TBSA_MASK); - - txb |= TXB_TFQM(MRAM -> TXB_TFQM); - txb |= TXB_TFQS(MRAM -> TXB_TFQS); - txb |= TXB_NDTB(MRAM -> TXB_NDTB); - txb |= TXB_TBSA(MRAM -> TXB_TBSA); - - - tx &= ~(TX_TBDS_MASK); - - tx |= TX_TBDS(MRAM -> TX_TBDS); - - - spiRegisterWrite(SIDFC, sid); - spiRegisterWrite(XIDFC, xid); - spiRegisterWrite(RXF0C, rxf0); - spiRegisterWrite(RXF1C, rxf1); - spiRegisterWrite(RXBC, rxb); - spiRegisterWrite(RXESC, rx); - spiRegisterWrite(TXEFC, tx_fifo); - spiRegisterWrite(TXBC, txb); - spiRegisterWrite(TXESC, tx); - - - // Put the TCAN45xx device into "NORMAL" mode - spiRegisterWrite(MODE_SEL, NORMAL_MODE); - - - return 0; -} - -uint8_t setSIDFilters(SID_filter * filters, TiMRAMParams * MRAM) -{ - size_t size = (size_t) MRAM -> SID_LSS; - uint32_t * filter_addr = (uint32_t *)MRAM -> SID_FLSS; - uint32_t filter = 0; - - for (size_t i = 0; i < size; i++) - { - filter = 0; - - filter |= SID_SFT (filters[i].SFT); - filter |= SID_SFEC (filters[i].SFEC); - filter |= SID_SFID1 (filters[i].SFID_1); - filter |= SID_SFID2 (filters[i].SFID_2); - - spiRegisterWrite(filter_addr + i * sizeof(uint32_t), filter); - } - - return 0; -} - -uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM) -{ - size_t size = (size_t) MRAM -> XID_LSE; - uint32_t filter_addr = MRAM -> XID_FLSEA; - uint64_t filter = 0; // Two words needed for XID - uint32_t filter_1 = 0; - uint32_t filter_2 = 0; - - for (size_t i = 0; i < size; i++) - { - filter = 0; - filter_1 = 0; - filter_2 = 0; - - filter_1 |= XID_EFID2(filters[i].EFID2); - filter_1 |= XID_EFT(filters[i].EFT); - - filter_2 |= XID_EFID2(filters[i].EFID2); - filter_2 |= XID_EFEC(filters[i].EFEC); - - filter |= (filter_1 | filter_2); - - spiRegisterWrite(filter_addr + i * sizeof(uint32_t), filter); - } - - return 0; -} - -uint8_t sendCAN(TiMRAMParams * MRAM, TXElement * TXE) -{ - // Check that any TX Buffer is vacant - uint32_t free_level = spiRegisterRead(TXFQS); - - uint32_t tx_buffer_start_addr = MRAM -> TXB_TBSA; - uint32_t tx_buffer_element_size = MRAM -> TX_TBDS + 8; // Additional 8 bytes of header - - - - if (!(TFFL(free_level))) - { - return 1; - } - - uint32_t index = TFQPI(free_level); - - uint32_t memory_offset = tx_buffer_start_addr + (tx_buffer_element_size * index); - - - uint32_t word_0 = 0; - uint32_t word_1 = 0; - uint32_t word_2 = 0; - - if (TXE -> ESI) word_0 |= (1 << ESI_SHFT); - if (TXE -> RTR) word_0 |= (1 << RTR_SHFT); - if (TXE -> XTD) - { - word_0 |= (1 << XTD_SHFT); - word_0 |= ((TXE -> ID) << XID_SHFT); - } - else - { - word_0 |= ((TXE -> ID) << SID_SHFT); - } - - spiRegisterWrite(memory_offset, word_0); - - word_1 |= ((TXE -> MM) << MM_SHFT); - - if (TXE -> EFC) word_1 |= (1 << EFC_SHFT); - if (TXE -> FDF) word_1 |= (1 << FDF_SHFT); - if (TXE -> BRS) word_1 |= (1 << BRS_SHFT); - - word_1 |= ((TXE -> DLC) << DLC_SHFT); - - spiRegisterWrite(memory_offset + WORD, word_1); - - word_2 |= ( ((TXE -> data_byte_0) << DB0_SHFT) | - ((TXE -> data_byte_1) << DB1_SHFT) | - ((TXE -> data_byte_2) << DB2_SHFT) | - ((TXE -> data_byte_3) << DB3_SHFT) ); - - spiRegisterWrite(memory_offset + 2*WORD, word_2); - - uint32_t add_request = 0; - - add_request |= (1U << index); - - spiRegisterWrite(TXBUF_AR, add_request); - - return 0; -} diff --git a/TCAN4550/Testing/ti_can.h b/TCAN4550/Testing/ti_can.h deleted file mode 100644 index e78f370..0000000 --- a/TCAN4550/Testing/ti_can.h +++ /dev/null @@ -1,459 +0,0 @@ -/// ____ ______ __ __ -/// / __ `____ ___ ____ / ____/_ ______ / /_ ____ / / -/// / / / / __ `/ _ `/ __ `/ / / / / / __ `/ __ `/ __ `/ / -/// / /_/ / /_/ / __/ / / / /___/ /_/ / /_/ / / / / /_/ / / -/// `____/ .___/`___/_/ /_/`____/`__, / .___/_/ /_/`__,_/_/ -/// /_/ /____/_/ -/// -/// A low-level driver with the main purpose of helping new hardware revisions or new designs adopt CAN FD -/// without having to port an existing codebase to a new platform. -/// -/// Author: Daniil Bragin -/// - - -#pragma once - -#include // For testing purposes -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/////////////////////////////////////////////////////////////////////////////////////////// - - - - - - -/////////////////////////////////////////////////////////////////////////////////////////// - -/// BIT TIMING VALUES - -// FOR CAN -#define NBTP 0x101C - -#define CAN_NBTP_NSJW_SHFT (25U) -#define CAN_NBTP_NSJW_MASK (0x7FU << CAN_NBTP_NSJW_SHFT) -#define CAN_SYNC_JUMP_WIDTH(x) ((uint8_t)(x) << CAN_NBTP_NSJW_SHFT) - -#define CAN_NBTP_NTSEG1_SHFT (8U) -#define CAN_NBTP_NTSEG1_MASK (0xFFU << CAN_NBTP_NTSEG1_SHFT) -#define CAN_TIME_SEG_1(x) ((uint8_t)(x) << CAN_NBTP_NTSEG1_SHFT) - -#define CAN_NBTP_NTSEG2_SHFT (0U) -#define CAN_NBTP_NTSEG2_MASK (0x7FU << CAN_NBTP_NTSEG2_SHFT) -#define CAN_TIME_SEG_2(x) ((uint8_t)(x) << CAN_NBTP_NTSEG2_SHFT) - -#define CAN_NBTP_NBRP_SHFT (24U) -#define CAN_NBTP_NBRP_MASK (0x1U << CAN_NBTP_NBRP_SHFT) -#define CAN_PRESCALER(x) ((uint8_t)(x) << CAN_NBTP_NBRP_SHFT) - -// FOR CAN-FD -#define DBTP 0x100C -#define TDCR 0x1048 // Transmission Delay Compensation Register - -#define CANFD_DBTP_DSJW_SHFT (0U) -#define CANFD_DBTP_DSJW_MASK (0xFU << CANFD_DBTP_DSJW_SHFT) -#define CANFD_SYNC_JUMP_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DSJW_SHFT) - -#define CANFD_DBTP_DTSEG1_SHFT (8U) -#define CANFD_DBTP_DTSEG1_MASK (0x1FU << CANFD_DBTP_DTSEG1_SHFT) -#define CANFD_TIME_SEG_1_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DTSEG1_SHFT) - -#define CANFD_DBTP_DTSEG2_SHFT (4U) -#define CANFD_DBTP_DTSEG2_MASK (0xFU << CANFD_DBTP_DTSEG2_SHFT) -#define CANFD_TIME_SEG_2_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DTSEG2_SHFT) - -#define CANFD_DBTP_DBRP_SHFT (16U) -#define CANFD_DBTP_DBRP_MASK (0xFU << CANFD_DBTP_DBRP_SHFT) -#define CANFD_PRESCALER(x) ((uint8_t)(x) << CANFD_DBTP_DBRP_SHFT) - -#define CANFD_TDCR_TDCO_SHFT (8U) -#define CANFD_TDCR_TDCO_MASK (0x7FU << CANFD_TDCR_TDCO_SHFT) -#define CANFD_DELAY_COMPENSATION_OFFSET(x) ((uint8_t)(x) << CANFD_TDCR_TDCO_SHFT) - -// Bit Timing Parameters -typedef struct -{ - uint8_t prescaler; - uint8_t prop_and_phase1; - uint8_t phase2; - uint8_t sync_jump_width; - uint8_t tdc; -} BitTimingParams; - -/////////////////////////////////////////////////////////////////////////////////////////// - -/// MESSAGE RAM - -// MRAM Registers' Addresses -#define SIDFC 0x1084 // 11-bit Filter (SID Filter) -#define XIDFC 0x1088 // 29-bit Filter (XID Filter) -#define RXF0C 0x10A0 // Rx FIFO 0 -#define RXF1C 0x10B0 // Rx FIFO 1 -#define RXBC 0x10AC // Rx Buffers -#define RXESC 0x10BC // Rx Element Size Config -#define TXEFC 0x10F0 // Tx Event FIFO -#define TXBC 0x10C0 // Tx Buffers -#define TXESC 0x10C8 // Tx Element Size Config - -// MRAM Params Bits - -// SID -#define SID_LSS_SHFT (16U) -#define SID_LSS_MASK (0xFFU << SID_LSS_SHFT) -#define SID_LSS(x) ((uint8_t)(x) << SID_LSS_SHFT) - -#define SID_FLSS_SHFT (0U) -#define SID_FLSS_MASK (0xFFFFU << SID_LSS_SHFT) -#define SID_FLSS(x) ((uint8_t)(x) << SID_LSS_SHFT) - - -// XID -#define XID_LSE_SHFT (16U) -#define XID_LSE_MASK (0x7FU << XID_LSE_SHFT) -#define XID_LSE(x) ((uint8_t)(x) << XID_LSE_SHFT) - - -#define XID_FLSEA_SHFT (16U) -#define XID_FLSEA_MASK (0xFFFFU << XID_FLSEA_SHFT) -#define XID_FLSEA(x) ((uint8_t)(x) << XID_FLSEA_SHFT) - - -// Rx FIFO 0 -#define RXF0_F0OM_SHFT (31U) -#define RXF0_F0OM_MASK (0x1U << RXF0_F0OM_SHFT) -#define RXF0_F0OM(x) ((uint8_t)(x) << RXF0_F0OM_SHFT) - -#define RXF0_F0WM_SHFT (24U) -#define RXF0_F0WM_MASK (0x7FU << RXF0_F0WM_SHFT) -#define RXF0_F0WM(x) ((uint8_t)(x) << RXF0_F0WM_SHFT) - -#define RXF0_F0S_SHFT (16U) -#define RXF0_F0S_MASK (0x7FU << RXF0_F0S_SHFT) -#define RXF0_F0S(x) ((uint8_t)(x) << RXF0_F0S_SHFT) - -#define RXF0_F0SA_SHFT (0U) -#define RXF0_F0SA_MASK (0xFFFFU << RXF0_F0SA_SHFT) -#define RXF0_F0SA(x) ((uint8_t)(x) << RXF0_F0SA_SHFT) - - -// Rx FIFO 1 -#define RXF1_F1OM_SHFT (31U) -#define RXF1_F1OM_MASK (0x1U << RXF1_F1OM_SHFT) -#define RXF1_F1OM(x) ((uint8_t)(x) << RXF1_F1OM_SHFT) - -#define RXF1_F1WM_SHFT (24U) -#define RXF1_F1WM_MASK (0x7FU << RXF1_F1WM_SHFT) -#define RXF1_F1WM(x) ((uint8_t)(x) << RXF1_F1WM_SHFT) - -#define RXF1_F1S_SHFT (16U) -#define RXF1_F1S_MASK (0x7FU << RXF1_F1S_SHFT) -#define RXF1_F1S(x) ((uint8_t)(x) << RXF1_F1S_SHFT) - -#define RXF1_F1SA_SHFT (0U) -#define RXF1_F1SA_MASK (0xFFFFU << RXF1_F1SA_SHFT) -#define RXF1_F1SA(x) ((uint8_t)(x) << RXF1_F1SA_SHFT) - - -// Rx Buffer -#define RXB_RBSA_SHFT (0U) -#define RXB_RBSA_MASK (0xFFFFU << RXB_RBSA_SHFT) -#define RXB_RBSA(x) ((uint8_t)(x) << RXB_RBSA_SHFT) - - -// Rx Element Size Config -#define RX_RBDS_SHFT (8U) -#define RX_RBDS_MASK (0x7U << RX_RBDS_SHFT) -#define RX_RBDS(x) ((uint8_t)(x) << RX_RBDS_SHFT) - -#define RX_F1DS_SHFT (4U) -#define RX_F1DS_MASK (0x7U << RX_F1DS_SHFT) -#define RX_F1DS(x) ((uint8_t)(x) << RX_F1DS_SHFT) - -#define RX_F0DS_SHFT (0U) -#define RX_F0DS_MASK (0x7U << RX_F0DS_SHFT) -#define RX_F0DS(x) ((uint8_t)(x) << RX_F0DS_SHFT) - - -// Tx Event FIFO Config -#define TXEVF_EFWM_SHFT (24U) -#define TXEVF_EFWM_MASK (0x3FU << TXEVF_EFWM_SHFT) -#define TXEVF_EFWM(x) ((uint8_t)(x) << TXEVF_EFWM_SHFT) - -#define TXEVF_EFS_SHFT (16U) -#define TXEVF_EFS_MASK (0x3FU << TXEVF_EFS_SHFT) -#define TXEVF_EFS(x) ((uint8_t)(x) << TXEVF_EFS_SHFT) - -#define TXEVF_EFSA_SHFT (0U) -#define TXEVF_EFSA_MASK (0xFFFFU << TXEVF_EFSA_SHFT) -#define TXEVF_EFSA(x) ((uint8_t)(x) << TXEVF_EFSA_SHFT) - - -// Tx Buffer Config -#define TXB_TFQM_SHFT (30U) -#define TXB_TFQM_MASK (0x1U << TXB_TFQM_SHFT) -#define TXB_TFQM(x) ((uint8_t)(x) << TXB_TFQM_SHFT) - -#define TXB_TFQS_SHFT (24U) -#define TXB_TFQS_MASK (0x3FU << TXB_TFQS_SHFT) -#define TXB_TFQS(x) ((uint8_t)(x) << TXB_TFQS_SHFT) - -#define TXB_NDTB_SHFT (16U) -#define TXB_NDTB_MASK (0x3FU << TXB_NDTB_SHFT) -#define TXB_NDTB(x) ((uint8_t)(x) << TXB_NDTB_SHFT) - -#define TXB_TBSA_SHFT (0U) -#define TXB_TBSA_MASK (0xFFFFU << TXB_TBSA_SHFT) -#define TXB_TBSA(x) ((uint8_t)(x) << TXB_TBSA_SHFT) - - -// TX Element Size Config -#define TX_TBDS_SHFT (0U) -#define TX_TBDS_MASK (0x7U << TX_TBDS_SHFT) -#define TX_TBDS(x) ((uint8_t)(x) << TX_TBDS_SHFT) - - - -// Message RAM Design Parameters - -// MDS = Maximum Data Size -// BPE = Bytes Per Element -// NOE = Number Of Elements - -typedef struct -{ - // SID - uint32_t SID_LSS; - uint32_t SID_FLSS; - - // XID - uint32_t XID_LSE; - uint32_t XID_FLSEA; - - // Rx FIFO 0 - uint32_t RXF0_F0OM; - uint32_t RXF0_F0WM; - uint32_t RXF0_F0S; - uint32_t RXF0_F0SA; - - // Rx FIFO 1 - uint32_t RXF1_F1OM; - uint32_t RXF1_F1WM; - uint32_t RXF1_F1S; - uint32_t RXF1_F1SA; - - // Rx Buffer - uint32_t RXB_RBSA; - - // Rx Element Size Config - uint32_t RX_RBDS; - uint32_t RX_F1DS; - uint32_t RX_F0DS; - - // Tx Event FIFO Config - uint32_t TXEVF_EFWM; - uint32_t TXEVF_EFS; - uint32_t TXEVF_EFSA; - - // Tx Buffer Config - uint32_t TXB_TFQM; - uint32_t TXB_TFQS; - uint32_t TXB_NDTB; - uint32_t TXB_TBSA; - - // TX Element Size Config - uint32_t TX_TBDS; - -} TiMRAMParams; - -// Filters Configuration: SID and XID (Standard and Extended) - -typedef struct -{ - // In classic mode: SFID_1 = ID, SFID_2 = MASK - - uint16_t SFID_1; - uint16_t SFID_2; - uint8_t SFT; - uint8_t SFEC; - -} SID_filter; - - -// SID Filter Type -#define SID_SFT_SHFT (30U) -#define SID_SFT(x) ((uint8_t)(x) << SID_SFT_SHFT) - -// Options for the SID & XID filter type -#define RANGE_FILTER 0b00U -#define DUAL_ID_FILTER 0b01U -#define CLASSIC_FILTER 0b10U -#define FILTER_ELEMENT_DISABLED 0b11U - -// Standard Element Filter Configuration -#define SID_SFEC_SHFT (27U) -#define SID_SFEC(x) ((uint8_t)(x) << SID_SFEC_SHFT) - -// Options for the element configuration -#define DISABLE_FILTER_ELEMENT 0b000U -#define STORE_RX_FIFO_0 0b001U -#define STORE_RX_FIFO_1 0b010U -#define REJECT_MESSAGE 0b011U -#define SET_AS_PRIO_MSG_DFLT 0b100U -#define SET_AS_PRIO_FIFO_0 0b101U -#define SET_AS_PRIO_FIFO_1 0b110U - -// Store into Rx Buffer or as debug message. If this is used, SFT is ignored and SFID1 is the filter. SFID2[10:9] -// describes where to store message, SFID2[5:0] describes which Rx Buffer to put the message (must be within -// the Rx Buffer configuration -#define STORE_RX_BUF 0b111U - - -#define SID_SFID1_SHFT (16U) -#define SID_SFID1_MASK (0x7FFU) -#define SID_SFID1(x) (((uint32_t)(x) & SID_SFID1_MASK) << SID_SFID1_SHFT) - -#define SID_SFID2_SHFT (0U) -#define SID_SFID2_MASK (0x7FFU) -#define SID_SFID2(x) (((uint32_t)(x) & SID_SFID2_MASK) << SID_SFID2_SHFT) - - -typedef struct -{ - - uint32_t EFID1; - uint32_t EFID2; - uint8_t EFT; // For type use same options as for SID - uint8_t EFEC; - -} XID_filter; - -// Word 0 - -#define XID_EFEC_SHFT (29U) -#define XID_EFEC(x) ((uint8_t)(x) << XID_EFEC_SHFT) - -#define XID_EFID1_SHFT (0U) -#define XID_EFID1_MASK (0x1FFFFFFF) -#define XID_EFID1(x) (((uint32_t)(x) & XID_EFID1_MASK) << XID_EFID1_SHFT) - -// Word 1 - -#define XID_EFT_SHFT (30U) -#define XID_EFT(x) ((uint8_t)(x) << XID_EFT_SHFT) - -#define XID_EFID2_SHFT (0U) -#define XID_EFID2_MASK (0x1FFFFFFF) -#define XID_EFID2(x) (((uint32_t)(x) & XID_EFID2_MASK) << XID_EFID2_SHFT) - - - - -/////////////////////////////////////////////////////////////////////////////////////////// - -/// Device Initialization Mode - -// Device Mode Selection Register Address -#define MODE_SEL 0x0800 - -// Available Device Modes -#define STANDBY_MODE (0b01 << 6U) -#define NORMAL_MODE (0b10 << 6U) - -// CC Control Register Address -#define CCCR 0x1018 - -// Bits Necessary For Initialization -#define CAN_CCCR_INIT (1U << 0U) -#define CAN_CCCR_CCE (1U << 1U) -#define CAN_CCCR_CSR (1U << 4U) - -/// 0 - CAN, 1 - CAN FD -#define CAN_MODE 0 - -/// 0 - Bit Rate Switching disabled, 1 - enabled -#define BIT_RATE_SWITCH 1 -#define CCCR_BRSE (1U << 9U) - -/// 0 - Flexible Datarate disabled, 1 - enabled -#define FD 1 -#define CCCR_FDOE (1U << 8U) - -/////////////////////////////////////////////////////////////////////////////////////////// - -/// Message Sending - -#define TXFQS 0x10C4 // Tx FIFO/Queue Status register - -#define TXBUF_AR 0x10D0 // Tx Buffer Add Request Register - -// Set on of the bits in TXBUF_AR to request the -// data to be sent from the corresponding TX Buffer - - -#define TFFL_MASK 0x1FU -#define TFFL(reg) ((reg) & TFFL_MASK) - -#define TFQPI_MAKS 0x1F0000 -#define TFQPI(reg) (((reg) & TFQPI_MAKS) >> 16U) - - -typedef struct -{ - // Word 0 - bool ESI; - bool XTD; - bool RTR; - uint16_t ID; - - // Word 1 - uint8_t MM; - bool EFC; - bool FDF; - bool BRS; - uint8_t DLC; - - // Word 2 - uint8_t data_byte_3; - uint8_t data_byte_2; - uint8_t data_byte_1; - uint8_t data_byte_0; - -} TXElement; - -#define ESI_SHFT 31U -#define XTD_SHFT 30U -#define RTR_SHFT 29U -#define SID_SHFT 18U -#define XID_SHFT 0U - -#define MM_SHFT 24U -#define EFC_SHFT 23U -#define FDF_SHFT 21U -#define BRS_SHFT 20U -#define DLC_SHFT 16U - -#define DB3_SHFT 24U -#define DB2_SHFT 16U -#define DB1_SHFT 8U -#define DB0_SHFT 0U - -#define WORD 0x4U - -void test_func(); -void debug_print(const char* format, ...); -uint8_t spiRegisterWrite(uint32_t addr, - uint32_t regValue); - -uint32_t spiRegisterRead(uint32_t addr); -uint8_t initCAN (const BitTimingParams * bTParams, - const TiMRAMParams * MRAM); -uint8_t setSIDFilters(SID_filter * filters, TiMRAMParams * MRAM); -uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM); -uint8_t sendCAN(TiMRAMParams * MRAM, TXElement * TXE); From b7e0d4a3d6d7dec9d44b95e1e5b59988b853e3e3 Mon Sep 17 00:00:00 2001 From: Daniil Bragin Date: Sun, 30 Jun 2024 16:15:39 +0200 Subject: [PATCH 16/16] Push last working version of .c and .h --- TCAN4550/ti_can.c | 85 ++++++++++++++++++++++++++++++++++++------ TCAN4550/ti_can.h | 95 ++++++++++++++++++++++++++++------------------- 2 files changed, 129 insertions(+), 51 deletions(-) diff --git a/TCAN4550/ti_can.c b/TCAN4550/ti_can.c index f7c9329..53bf9e3 100644 --- a/TCAN4550/ti_can.c +++ b/TCAN4550/ti_can.c @@ -8,6 +8,15 @@ #include +void spi_init() +{ + +/** + * TODO: Implement SPI init +*/ + +} + uint8_t spiRegisterWrite(uint32_t addr, uint32_t regValue) { @@ -42,34 +51,63 @@ uint8_t initCAN (const BitTimingParams * bTParams, // TODO: Cover edge cases for values in structs + error reporting + // spi_init(); + // Standby Mode Check - if ((spiRegisterRead(MODE_SEL)) != STANDBY_MODE) + uint32_t mode = 0; + + mode = spiRegisterRead(MODE_SEL); + + // Standby Mode Check + if ((mode & 0xC0) != STANDBY_MODE) + { + printf("Device not in STANDBY_MODE, MODE: %lu, setting STANDBY_MODE\n", mode & 0xC0); + + mode &= ~CLEAN_MODE; + mode |= STANDBY_MODE; + + spiRegisterWrite(MODE_SEL, mode); + printf("STANDBY_MODE set successfully\n"); + + mode = spiRegisterRead(MODE_SEL); + printf("New device mode: %lX, NEEDED: %X\n", mode & 0xC0, STANDBY_MODE); + } + else { - spiRegisterWrite(MODE_SEL, STANDBY_MODE); + printf("Device in STANDBY_MODE, mode: %lX\n", mode); } // Initialization Mode // TODO: Check whether CSR needs to be written before CCE and INIT + uint32_t init = spiRegisterRead(CCCR); + + printf("Initial CCCR content: %lX\n", init); + + init &= ~(CAN_CCCR_CCE | CAN_CCCR_INIT); init |= (CAN_CCCR_CCE | CAN_CCCR_INIT); init &= ~CAN_CCCR_CSR; + uint32_t bit_timing = 0; uint32_t trans_delay_comp = 0; - uint8_t prescaler = bTParams -> prescaler; + uint8_t prescaler = bTParams -> prescaler; uint8_t prop_and_phase1 = bTParams -> prop_and_phase1; - uint8_t phase2 = bTParams -> phase2; + uint8_t phase2 = bTParams -> phase2; uint8_t sync_jump_width = bTParams -> sync_jump_width; - uint8_t tdc = bTParams -> tdc; + uint8_t tdc = bTParams -> tdc; // FD/BRS & Bit Timing Init Cofiguration if (CAN_MODE == 0) { - spiRegisterWrite(CCCR, init); + printf("Device in CAN mode\n"); + spiRegisterWrite(CCCR, init); - bit_timing = spiRegisterRead(NBTP); + bit_timing = spiRegisterRead(NBTP); + + printf("Initial NBTP content: %lu\n", bit_timing); // Reset the NBTP register values bit_timing &= ~(CAN_NBTP_NSJW_MASK | @@ -83,6 +121,8 @@ uint8_t initCAN (const BitTimingParams * bTParams, bit_timing |= CAN_TIME_SEG_2(phase2); bit_timing |= CAN_PRESCALER(prescaler); + printf("Intended NBTP value: %lX\n", bit_timing); + spiRegisterWrite(NBTP, bit_timing); } @@ -118,8 +158,20 @@ uint8_t initCAN (const BitTimingParams * bTParams, spiRegisterWrite(TDCR, trans_delay_comp); } - // MRAM Init + // Zero out MRAM + + spiRegisterWrite(SIDFC, 0x0); + spiRegisterWrite(XIDFC, 0x0); + spiRegisterWrite(RXF0C, 0x0); + spiRegisterWrite(RXF1C, 0x0); + spiRegisterWrite(RXBC, 0x0); + spiRegisterWrite(RXESC, 0x0); + spiRegisterWrite(TXEFC, 0x0); + spiRegisterWrite(TXBC, 0x0); + spiRegisterWrite(TXESC, 0x0); + // MRAM Init + uint32_t sid = spiRegisterRead(SIDFC); uint32_t xid = spiRegisterRead(XIDFC); uint32_t rxf0 = spiRegisterRead(RXF0C); @@ -215,10 +267,18 @@ uint8_t initCAN (const BitTimingParams * bTParams, spiRegisterWrite(TXBC, txb); spiRegisterWrite(TXESC, tx); - - // Put the TCAN45xx device into "NORMAL" mode - spiRegisterWrite(MODE_SEL, NORMAL_MODE); + uint32_t selected_mode = spiRegisterRead(MODE_SEL); + + printf("Initial device mode: %lX\n", selected_mode); + + selected_mode &= ~CLEAN_MODE; + selected_mode |= NORMAL_MODE; + + printf("Intended mode: %lX\n", selected_mode); + + spiRegisterWrite(MODE_SEL, selected_mode); + printf("Device in NORMAL_MODE, init_can successful\n"); return 0; } @@ -272,7 +332,7 @@ uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM) return 0; } -uint8_t sendCAN(TiMRAMParams * MRAM, TXElement * TXE) +uint8_t sendCAN(TiMRAMParams * MRAM, TXFIFOElement * TXE) { // Check that any TX Buffer is vacant uint32_t free_level = spiRegisterRead(TXFQS); @@ -284,6 +344,7 @@ uint8_t sendCAN(TiMRAMParams * MRAM, TXElement * TXE) if (!(TFFL(free_level))) { + printf("ERROR: No TX BUffers Available, return 1\n"); return 1; } diff --git a/TCAN4550/ti_can.h b/TCAN4550/ti_can.h index 2c5f9c1..97d332c 100644 --- a/TCAN4550/ti_can.h +++ b/TCAN4550/ti_can.h @@ -41,19 +41,19 @@ extern "C" { #define CAN_NBTP_NSJW_SHFT (25U) #define CAN_NBTP_NSJW_MASK (0x7FU << CAN_NBTP_NSJW_SHFT) -#define CAN_SYNC_JUMP_WIDTH(x) ((uint8_t)(x) << CAN_NBTP_NSJW_SHFT) +#define CAN_SYNC_JUMP_WIDTH(x) ((uint32_t)(x) << CAN_NBTP_NSJW_SHFT) #define CAN_NBTP_NTSEG1_SHFT (8U) #define CAN_NBTP_NTSEG1_MASK (0xFFU << CAN_NBTP_NTSEG1_SHFT) -#define CAN_TIME_SEG_1(x) ((uint8_t)(x) << CAN_NBTP_NTSEG1_SHFT) +#define CAN_TIME_SEG_1(x) ((uint32_t)(x) << CAN_NBTP_NTSEG1_SHFT) #define CAN_NBTP_NTSEG2_SHFT (0U) #define CAN_NBTP_NTSEG2_MASK (0x7FU << CAN_NBTP_NTSEG2_SHFT) -#define CAN_TIME_SEG_2(x) ((uint8_t)(x) << CAN_NBTP_NTSEG2_SHFT) +#define CAN_TIME_SEG_2(x) ((uint32_t)(x) << CAN_NBTP_NTSEG2_SHFT) #define CAN_NBTP_NBRP_SHFT (24U) #define CAN_NBTP_NBRP_MASK (0x1U << CAN_NBTP_NBRP_SHFT) -#define CAN_PRESCALER(x) ((uint8_t)(x) << CAN_NBTP_NBRP_SHFT) +#define CAN_PRESCALER(x) ((uint32_t)(x) << CAN_NBTP_NBRP_SHFT) // FOR CAN-FD #define DBTP 0x100C @@ -61,23 +61,23 @@ extern "C" { #define CANFD_DBTP_DSJW_SHFT (0U) #define CANFD_DBTP_DSJW_MASK (0xFU << CANFD_DBTP_DSJW_SHFT) -#define CANFD_SYNC_JUMP_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DSJW_SHFT) +#define CANFD_SYNC_JUMP_WIDTH(x) ((uint32_t)(x) << CANFD_DBTP_DSJW_SHFT) #define CANFD_DBTP_DTSEG1_SHFT (8U) #define CANFD_DBTP_DTSEG1_MASK (0x1FU << CANFD_DBTP_DTSEG1_SHFT) -#define CANFD_TIME_SEG_1_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DTSEG1_SHFT) +#define CANFD_TIME_SEG_1_WIDTH(x) ((uint32_t)(x) << CANFD_DBTP_DTSEG1_SHFT) #define CANFD_DBTP_DTSEG2_SHFT (4U) #define CANFD_DBTP_DTSEG2_MASK (0xFU << CANFD_DBTP_DTSEG2_SHFT) -#define CANFD_TIME_SEG_2_WIDTH(x) ((uint8_t)(x) << CANFD_DBTP_DTSEG2_SHFT) +#define CANFD_TIME_SEG_2_WIDTH(x) ((uint32_t)(x) << CANFD_DBTP_DTSEG2_SHFT) #define CANFD_DBTP_DBRP_SHFT (16U) #define CANFD_DBTP_DBRP_MASK (0xFU << CANFD_DBTP_DBRP_SHFT) -#define CANFD_PRESCALER(x) ((uint8_t)(x) << CANFD_DBTP_DBRP_SHFT) +#define CANFD_PRESCALER(x) ((uint32_t)(x) << CANFD_DBTP_DBRP_SHFT) #define CANFD_TDCR_TDCO_SHFT (8U) #define CANFD_TDCR_TDCO_MASK (0x7FU << CANFD_TDCR_TDCO_SHFT) -#define CANFD_DELAY_COMPENSATION_OFFSET(x) ((uint8_t)(x) << CANFD_TDCR_TDCO_SHFT) +#define CANFD_DELAY_COMPENSATION_OFFSET(x) ((uint32_t)(x) << CANFD_TDCR_TDCO_SHFT) // Bit Timing Parameters typedef struct @@ -109,116 +109,116 @@ typedef struct // SID #define SID_LSS_SHFT (16U) #define SID_LSS_MASK (0xFFU << SID_LSS_SHFT) -#define SID_LSS(x) ((uint8_t)(x) << SID_LSS_SHFT) +#define SID_LSS(x) ((uint32_t)(x) << SID_LSS_SHFT) #define SID_FLSS_SHFT (0U) #define SID_FLSS_MASK (0xFFFFU << SID_LSS_SHFT) -#define SID_FLSS(x) ((uint8_t)(x) << SID_LSS_SHFT) +#define SID_FLSS(x) ((uint32_t)(x) << SID_FLSS_SHFT) // XID #define XID_LSE_SHFT (16U) #define XID_LSE_MASK (0x7FU << XID_LSE_SHFT) -#define XID_LSE(x) ((uint8_t)(x) << XID_LSE_SHFT) +#define XID_LSE(x) ((uint32_t)(x) << XID_LSE_SHFT) #define XID_FLSEA_SHFT (16U) #define XID_FLSEA_MASK (0xFFFFU << XID_FLSEA_SHFT) -#define XID_FLSEA(x) ((uint8_t)(x) << XID_FLSEA_SHFT) +#define XID_FLSEA(x) ((uint32_t)(x) << XID_FLSEA_SHFT) // Rx FIFO 0 #define RXF0_F0OM_SHFT (31U) #define RXF0_F0OM_MASK (0x1U << RXF0_F0OM_SHFT) -#define RXF0_F0OM(x) ((uint8_t)(x) << RXF0_F0OM_SHFT) +#define RXF0_F0OM(x) ((uint32_t)(x) << RXF0_F0OM_SHFT) #define RXF0_F0WM_SHFT (24U) #define RXF0_F0WM_MASK (0x7FU << RXF0_F0WM_SHFT) -#define RXF0_F0WM(x) ((uint8_t)(x) << RXF0_F0WM_SHFT) +#define RXF0_F0WM(x) ((uint32_t)(x) << RXF0_F0WM_SHFT) #define RXF0_F0S_SHFT (16U) #define RXF0_F0S_MASK (0x7FU << RXF0_F0S_SHFT) -#define RXF0_F0S(x) ((uint8_t)(x) << RXF0_F0S_SHFT) +#define RXF0_F0S(x) ((uint32_t)(x) << RXF0_F0S_SHFT) #define RXF0_F0SA_SHFT (0U) #define RXF0_F0SA_MASK (0xFFFFU << RXF0_F0SA_SHFT) -#define RXF0_F0SA(x) ((uint8_t)(x) << RXF0_F0SA_SHFT) +#define RXF0_F0SA(x) ((uint32_t)(x) << RXF0_F0SA_SHFT) // Rx FIFO 1 #define RXF1_F1OM_SHFT (31U) #define RXF1_F1OM_MASK (0x1U << RXF1_F1OM_SHFT) -#define RXF1_F1OM(x) ((uint8_t)(x) << RXF1_F1OM_SHFT) +#define RXF1_F1OM(x) ((uint32_t)(x) << RXF1_F1OM_SHFT) #define RXF1_F1WM_SHFT (24U) #define RXF1_F1WM_MASK (0x7FU << RXF1_F1WM_SHFT) -#define RXF1_F1WM(x) ((uint8_t)(x) << RXF1_F1WM_SHFT) +#define RXF1_F1WM(x) ((uint32_t)(x) << RXF1_F1WM_SHFT) #define RXF1_F1S_SHFT (16U) #define RXF1_F1S_MASK (0x7FU << RXF1_F1S_SHFT) -#define RXF1_F1S(x) ((uint8_t)(x) << RXF1_F1S_SHFT) +#define RXF1_F1S(x) ((uint32_t)(x) << RXF1_F1S_SHFT) #define RXF1_F1SA_SHFT (0U) #define RXF1_F1SA_MASK (0xFFFFU << RXF1_F1SA_SHFT) -#define RXF1_F1SA(x) ((uint8_t)(x) << RXF1_F1SA_SHFT) +#define RXF1_F1SA(x) ((uint32_t)(x) << RXF1_F1SA_SHFT) // Rx Buffer #define RXB_RBSA_SHFT (0U) #define RXB_RBSA_MASK (0xFFFFU << RXB_RBSA_SHFT) -#define RXB_RBSA(x) ((uint8_t)(x) << RXB_RBSA_SHFT) +#define RXB_RBSA(x) ((uint32_t)(x) << RXB_RBSA_SHFT) // Rx Element Size Config #define RX_RBDS_SHFT (8U) #define RX_RBDS_MASK (0x7U << RX_RBDS_SHFT) -#define RX_RBDS(x) ((uint8_t)(x) << RX_RBDS_SHFT) +#define RX_RBDS(x) ((uint32_t)(x) << RX_RBDS_SHFT) #define RX_F1DS_SHFT (4U) #define RX_F1DS_MASK (0x7U << RX_F1DS_SHFT) -#define RX_F1DS(x) ((uint8_t)(x) << RX_F1DS_SHFT) +#define RX_F1DS(x) ((uint32_t)(x) << RX_F1DS_SHFT) #define RX_F0DS_SHFT (0U) #define RX_F0DS_MASK (0x7U << RX_F0DS_SHFT) -#define RX_F0DS(x) ((uint8_t)(x) << RX_F0DS_SHFT) +#define RX_F0DS(x) ((uint32_t)(x) << RX_F0DS_SHFT) // Tx Event FIFO Config #define TXEVF_EFWM_SHFT (24U) #define TXEVF_EFWM_MASK (0x3FU << TXEVF_EFWM_SHFT) -#define TXEVF_EFWM(x) ((uint8_t)(x) << TXEVF_EFWM_SHFT) +#define TXEVF_EFWM(x) ((uint32_t)(x) << TXEVF_EFWM_SHFT) #define TXEVF_EFS_SHFT (16U) #define TXEVF_EFS_MASK (0x3FU << TXEVF_EFS_SHFT) -#define TXEVF_EFS(x) ((uint8_t)(x) << TXEVF_EFS_SHFT) +#define TXEVF_EFS(x) ((uint32_t)(x) << TXEVF_EFS_SHFT) #define TXEVF_EFSA_SHFT (0U) #define TXEVF_EFSA_MASK (0xFFFFU << TXEVF_EFSA_SHFT) -#define TXEVF_EFSA(x) ((uint8_t)(x) << TXEVF_EFSA_SHFT) +#define TXEVF_EFSA(x) ((uint32_t)(x) << TXEVF_EFSA_SHFT) // Tx Buffer Config #define TXB_TFQM_SHFT (30U) #define TXB_TFQM_MASK (0x1U << TXB_TFQM_SHFT) -#define TXB_TFQM(x) ((uint8_t)(x) << TXB_TFQM_SHFT) +#define TXB_TFQM(x) ((uint32_t)(x) << TXB_TFQM_SHFT) #define TXB_TFQS_SHFT (24U) #define TXB_TFQS_MASK (0x3FU << TXB_TFQS_SHFT) -#define TXB_TFQS(x) ((uint8_t)(x) << TXB_TFQS_SHFT) +#define TXB_TFQS(x) ((uint32_t)(x) << TXB_TFQS_SHFT) #define TXB_NDTB_SHFT (16U) #define TXB_NDTB_MASK (0x3FU << TXB_NDTB_SHFT) -#define TXB_NDTB(x) ((uint8_t)(x) << TXB_NDTB_SHFT) +#define TXB_NDTB(x) ((uint32_t)(x) << TXB_NDTB_SHFT) #define TXB_TBSA_SHFT (0U) #define TXB_TBSA_MASK (0xFFFFU << TXB_TBSA_SHFT) -#define TXB_TBSA(x) ((uint8_t)(x) << TXB_TBSA_SHFT) +#define TXB_TBSA(x) ((uint32_t)(x) << TXB_TBSA_SHFT) // TX Element Size Config #define TX_TBDS_SHFT (0U) #define TX_TBDS_MASK (0x7U << TX_TBDS_SHFT) -#define TX_TBDS(x) ((uint8_t)(x) << TX_TBDS_SHFT) +#define TX_TBDS(x) ((uint32_t)(x) << TX_TBDS_SHFT) @@ -290,7 +290,7 @@ typedef struct // SID Filter Type #define SID_SFT_SHFT (30U) -#define SID_SFT(x) ((uint8_t)(x) << SID_SFT_SHFT) +#define SID_SFT(x) ((uint32_t)(x) << SID_SFT_SHFT) // Options for the SID & XID filter type #define RANGE_FILTER 0b00U @@ -300,7 +300,7 @@ typedef struct // Standard Element Filter Configuration #define SID_SFEC_SHFT (27U) -#define SID_SFEC(x) ((uint8_t)(x) << SID_SFEC_SHFT) +#define SID_SFEC(x) ((uint32_t)(x) << SID_SFEC_SHFT) // Options for the element configuration #define DISABLE_FILTER_ELEMENT 0b000U @@ -339,7 +339,7 @@ typedef struct // Word 0 #define XID_EFEC_SHFT (29U) -#define XID_EFEC(x) ((uint8_t)(x) << XID_EFEC_SHFT) +#define XID_EFEC(x) ((uint32_t)(x) << XID_EFEC_SHFT) #define XID_EFID1_SHFT (0U) #define XID_EFID1_MASK (0x1FFFFFFF) @@ -348,7 +348,7 @@ typedef struct // Word 1 #define XID_EFT_SHFT (30U) -#define XID_EFT(x) ((uint8_t)(x) << XID_EFT_SHFT) +#define XID_EFT(x) ((uint32_t)(x) << XID_EFT_SHFT) #define XID_EFID2_SHFT (0U) #define XID_EFID2_MASK (0x1FFFFFFF) @@ -367,6 +367,7 @@ typedef struct // Available Device Modes #define STANDBY_MODE (0b01 << 6U) #define NORMAL_MODE (0b10 << 6U) +#define CLEAN_MODE (0b11 << 6U) // CC Control Register Address #define CCCR 0x1018 @@ -377,7 +378,7 @@ typedef struct #define CAN_CCCR_CSR (1U << 4U) /// 0 - CAN, 1 - CAN FD -#define CAN_MODE 1 +#define CAN_MODE 0 /// 0 - Bit Rate Switching disabled, 1 - enabled #define BIT_RATE_SWITCH 1 @@ -427,7 +428,7 @@ typedef struct uint8_t data_byte_1; uint8_t data_byte_0; -} TXElement; +} TXFIFOElement; #define ESI_SHFT 31U #define XTD_SHFT 30U @@ -448,3 +449,19 @@ typedef struct #define WORD 0x4U +#define SPI_WRITE_OPCODE 0x61 +#define SPI_READ_OPCODE 0x41 + +#define LENGTH_BYTE 0x4 + +#define ENDIAN_REGISTER_TEST 0x1004 + +void spi_init(); +uint8_t spiRegisterWrite(uint16_t reg_addr, uint32_t reg_value, uint32_t * pointer); +uint32_t spiRegisterRead(uint16_t reg_addr); +uint8_t initCAN (const BitTimingParams * bTParams, + const TiMRAMParams * MRAM); +uint8_t setSIDFilters(SID_filter * filters, TiMRAMParams * MRAM); +uint8_t setXIDFilters(XID_filter * filters, TiMRAMParams * MRAM); +uint8_t sendCAN(TiMRAMParams * MRAM, TXFIFOElement * TXE); +