Continue work on Device config
This commit is contained in:
parent
4851bfc50a
commit
11deae5454
2 changed files with 273 additions and 222 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,3 +6,4 @@ dist
|
||||||
__pycache__
|
__pycache__
|
||||||
*.egg-info
|
*.egg-info
|
||||||
_build
|
_build
|
||||||
|
.idea
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
import ctypes
|
import ctypes
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
uint8_t = ctypes.c_uint8
|
uint8_t = ctypes.c_uint8
|
||||||
uint16_t = ctypes.c_uint16
|
uint16_t = ctypes.c_uint16
|
||||||
uint32_t = ctypes.c_uint32
|
uint32_t = ctypes.c_uint32
|
||||||
import spidev
|
import spidev
|
||||||
|
|
||||||
|
|
||||||
class TCAN4550:
|
class TCAN4550:
|
||||||
|
|
||||||
def __init__(self, bus: int, device: int) -> None:
|
def __init__(self, bus: int, device: int) -> None:
|
||||||
|
|
||||||
# SPI initialization
|
# SPI initialization
|
||||||
self.spi = spidev.SpiDev(bus, device)
|
self.spi = spidev.SpiDev(bus, device)
|
||||||
self.spi.max_speed_hz = 2000000
|
self.spi.max_speed_hz = 2000000
|
||||||
|
|
@ -16,36 +17,75 @@ class TCAN4550:
|
||||||
self.spi.mode = 0b00
|
self.spi.mode = 0b00
|
||||||
self.spi.cshigh = True
|
self.spi.cshigh = True
|
||||||
|
|
||||||
|
|
||||||
# TCAN device initialization
|
# TCAN device initialization
|
||||||
|
|
||||||
# Begin by clearing any potential SPI errors
|
# Begin by clearing any potential SPI errors
|
||||||
self.TCAN_clearSPIerr()
|
self.TCAN_clearSPIerr()
|
||||||
|
|
||||||
self.dev_ie = TCAN4550_device_interrupt_enable()
|
self.dev_ie = TCAN4x5x_device_interrupt_enable()
|
||||||
self.dev_ie = 0x0 # Initialize to 0 to all bits are set to 0.
|
self.dev_ie = 0x0 # Initialize to 0 to all bits are set to 0.
|
||||||
self.TCAN_configure_interrupt_enable(self.dev_ie) # Disable all non-MCAN related interrupts for simplicity
|
self.TCAN_configure_interrupt_enable(self.dev_ie) # Disable all non-MCAN related interrupts for simplicity
|
||||||
|
|
||||||
self.dev_ir = TCAN4550_device_interrupt()
|
self.dev_ir = TCAN4x5x_Device_Interrupts()
|
||||||
self.dev.ir = 0x0 # Setup a new MCAN IR object for easy interrupt checking
|
self.dev_ir = 0x0 # Setup a new MCAN IR object for easy interrupt checking
|
||||||
self.TCAN_read_interrupts(self.dev_ir) # Request that the struct be updated with current DEVICE (not MCAN) interrupt values
|
self.TCAN_read_interrupts(
|
||||||
|
self.dev_ir) # Request that the struct be updated with current DEVICE (not MCAN) interrupt values
|
||||||
|
|
||||||
|
if self.dev_ir.b.PWRON:
|
||||||
|
self.TCAN4x5x_Device_ClearInterrupts(self.dev_ir)
|
||||||
|
|
||||||
# Configure the CAN bus speeds
|
# Configure the CAN bus speeds
|
||||||
self.TCANNomTiming = TCAN4550_MCAN_nominal_timing_simple() # 500k arbitration with a 40 MHz crystal ((40E6 / 2) / (32 + 8) = 500E3)
|
self.TCANNomTiming = TCAN4x5x_MCAN_Nominal_Timing_Simple() # 500k arbitration with a 40 MHz crystal ((40E6 / 2) / (32 + 8) = 500E3)
|
||||||
self.TCANNomTiming = 0x0
|
self.TCANNomTiming = 0x0
|
||||||
self.TCANNomTiming.NominalBitRatePrescaler = 2
|
self.TCANNomTiming.NominalBitRatePrescaler = 2
|
||||||
self.TCANNomTiming.NominalTqBeforeSamplePoint = 32
|
self.TCANNomTiming.NominalTqBeforeSamplePoint = 32
|
||||||
self.TCANNomTiming.NominalTqAfterSamplePoint = 8
|
self.TCANNomTiming.NominalTqAfterSamplePoint = 8
|
||||||
|
|
||||||
self.TCANDataTiming = TCAN4550_MCAN_nominal_timing_simple() # 2 Mbps CAN FD with a 40 MHz crystal (40E6 / (15 + 5) = 2E6)
|
self.TCANDataTiming = TCAN4x5x_MCAN_Nominal_Timing_Simple() # 2 Mbps CAN FD with a 40 MHz crystal (40E6 / (15 + 5) = 2E6)
|
||||||
self.TCANDataTiming = 0x0
|
self.TCANDataTiming = 0x0
|
||||||
self.TCANDataTiming.DataBitRatePrescaler = 1;
|
self.TCANDataTiming.DataBitRatePrescaler = 1
|
||||||
self.TCANDataTiming.DataTqBeforeSamplePoint = 15;
|
self.TCANDataTiming.DataTqBeforeSamplePoint = 15
|
||||||
self.TCANDataTiming.DataTqAfterSamplePoint = 5;
|
self.TCANDataTiming.DataTqAfterSamplePoint = 5
|
||||||
|
|
||||||
|
# Configure the MCAN core settings
|
||||||
|
self.cccrConfig = TCAN4x5x_MCAN_CCCR_Config()
|
||||||
|
self.cccrConfig = 0x0 # Remember to initialize to 0, or you'll get random garbage!
|
||||||
|
self.cccrConfig.b.FDOE = 1 # CAN FD mode enable
|
||||||
|
self.cccrConfig.b.BRSE = 1 # CAN FD Bit rate switch enable
|
||||||
|
|
||||||
|
# Configure the default CAN packet filtering settings
|
||||||
|
self.gfc = TCAN4x5x_MCAN_Global_Filter_Configuration()
|
||||||
|
self.gfc.b.RRFE = 1 # Reject remote frames (TCAN4x5x doesn't support this)
|
||||||
|
self.gfc.b.RRFS = 1 # Reject remote frames (TCAN4x5x doesn't support this)
|
||||||
|
self.gfc.b.ANFE = TCAN4x5x_GFC_NO_MATCH_BEHAVIOR.TCAN4x5x_GFC_ACCEPT_INTO_RXFIFO0.value # Default behavior if incoming message doesn't match a filter is to accept into RXFIO0 for extended ID messages (29 bit IDs)
|
||||||
|
self.gfc.b.ANFS = TCAN4x5x_GFC_NO_MATCH_BEHAVIOR.TCAN4x5x_GFC_ACCEPT_INTO_RXFIFO0.value # Default behavior if incoming message doesn't match a filter is to accept into RXFIO0 for standard ID messages (11 bit IDs)
|
||||||
|
|
||||||
|
'''
|
||||||
|
In the next configuration block, we will set the MCAN core up to have:
|
||||||
|
- 1 SID filter element
|
||||||
|
- 1 XID Filter element
|
||||||
|
- 5 RX FIFO 0 elements
|
||||||
|
- RX FIFO 0 supports data payloads up to 64 bytes
|
||||||
|
- RX FIFO 1 and RX Buffer will not have any elements, but we still set their data payload sizes, even though it's not required
|
||||||
|
- No TX Event FIFOs
|
||||||
|
- 2 Transmit buffers supporting up to 64 bytes of data payload
|
||||||
|
'''
|
||||||
|
self.MRAMConfiguration = TCAN4x5x_MRAM_Config()
|
||||||
|
self.MRAMConfiguration = 0x0
|
||||||
|
self.MRAMConfiguration.XIDNumElements = 1 # Extended ID number of elements, you MUST have a filter written to MRAM for each element defined
|
||||||
|
self.MRAMConfiguration.SIDNumElements = 1 # Standard ID number of elements, you MUST have a filter written to MRAM for each element defined
|
||||||
|
self.MRAMConfiguration.Rx0NumElements = 5 # RX0 Number of elements
|
||||||
|
self.MRAMConfiguration.Rx0ElementSize = TCAN4x5x_MRAM_Element_Data_Size.MRAM_64_Byte_Data # RX0 data payload size
|
||||||
|
self.MRAMConfiguration.Rx1NumElements = 0 # RX1 number of elements
|
||||||
|
self.MRAMConfiguration.Rx1ElementSize = TCAN4x5x_MRAM_Element_Data_Size.MRAM_64_Byte_Data # RX1 data payload size
|
||||||
|
self.MRAMConfiguration.RxBufNumElements = 0 # RX buffer number of elements
|
||||||
|
self.MRAMConfiguration.RxBufElementSize = TCAN4x5x_MRAM_Element_Data_Size.MRAM_64_Byte_Data # RX buffer data payload size
|
||||||
|
self.MRAMConfiguration.TxEventFIFONumElements = 0 # TX Event FIFO number of elements
|
||||||
|
self.MRAMConfiguration.TxBufferNumElements = 2 # TX buffer number of elements
|
||||||
|
self.MRAMConfiguration.TxBufferElementSize = TCAN4x5x_MRAM_Element_Data_Size.MRAM_64_Byte_Data # TX buffer data payload size
|
||||||
|
|
||||||
|
def TCAN4x5x_Device_ClearInterrupts(self, ir):
|
||||||
|
pass
|
||||||
|
|
||||||
def TCAN_clearSPIerr(self) -> None:
|
def TCAN_clearSPIerr(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
@ -54,7 +94,6 @@ class TCAN4550:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def TCAN_read_interrupts(self, ir) -> bool:
|
def TCAN_read_interrupts(self, ir) -> bool:
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def TCAN_write_32(self, address, data) -> None:
|
def TCAN_write_32(self, address, data) -> None:
|
||||||
|
|
@ -63,7 +102,6 @@ class TCAN4550:
|
||||||
def TCAN_write(self, data, address, no_words) -> None:
|
def TCAN_write(self, data, address, no_words) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def TCAN_read_32(self, address, data) -> uint32_t:
|
def TCAN_read_32(self, address, data) -> uint32_t:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
@ -71,13 +109,12 @@ class TCAN4550:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_GFC_NO_MATCH_BEHAVIOR(Enum): # No Comments provided in original file
|
class TCAN4x5x_GFC_NO_MATCH_BEHAVIOR(Enum): # No Comments provided in original file
|
||||||
TCAN4x5x_GFC_ACCEPT_INTO_RXFIFO0 = 0,
|
TCAN4x5x_GFC_ACCEPT_INTO_RXFIFO0 = 0,
|
||||||
TCAN4x5x_GFC_ACCEPT_INTO_RXFIFO1 = 1,
|
TCAN4x5x_GFC_ACCEPT_INTO_RXFIFO1 = 1,
|
||||||
TCAN4x5x_GFC_REJECT = 2
|
TCAN4x5x_GFC_REJECT = 2
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MRAM_Element_Data_Size(Enum):
|
class TCAN4x5x_MRAM_Element_Data_Size(Enum):
|
||||||
# 8 bytes of data payload
|
# 8 bytes of data payload
|
||||||
MRAM_8_Byte_Data = 0,
|
MRAM_8_Byte_Data = 0,
|
||||||
|
|
@ -103,6 +140,7 @@ class TCAN4x5x_MRAM_Element_Data_Size(Enum):
|
||||||
# 64 bytes of data payload
|
# 64 bytes of data payload
|
||||||
MRAM_64_Byte_Data = 0x7
|
MRAM_64_Byte_Data = 0x7
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Data_Timing_Simple(ctypes.Structure):
|
class TCAN4x5x_MCAN_Data_Timing_Simple(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# Prescaler value, interpreted as 1:x
|
# Prescaler value, interpreted as 1:x
|
||||||
|
|
@ -118,6 +156,7 @@ class TCAN4x5x_MCAN_Data_Timing_Simple(ctypes.Structure):
|
||||||
("DataTqAfterSamplePoint", uint8_t, 5)
|
("DataTqAfterSamplePoint", uint8_t, 5)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Data_Timing_Raw(ctypes.Structure):
|
class TCAN4x5x_MCAN_Data_Timing_Raw(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# DBRP: The prescaler value from the MCAN system clock. Interpreted by MCAN as the value is this field + 1
|
# DBRP: The prescaler value from the MCAN system clock. Interpreted by MCAN as the value is this field + 1
|
||||||
|
|
@ -145,6 +184,7 @@ class TCAN4x5x_MCAN_Data_Timing_Raw(ctypes.Structure):
|
||||||
("TDCFilter", uint8_t, 7)
|
("TDCFilter", uint8_t, 7)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Nominal_Timing_Simple(ctypes.Structure):
|
class TCAN4x5x_MCAN_Nominal_Timing_Simple(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# NBRP: The prescaler value from the MCAN system clock. Value interpreted as 1:x
|
# NBRP: The prescaler value from the MCAN system clock. Value interpreted as 1:x
|
||||||
|
|
@ -160,6 +200,7 @@ class TCAN4x5x_MCAN_Nominal_Timing_Simple(ctypes.Structure):
|
||||||
("NominalTqAfterSamplePoint", uint8_t, 8)
|
("NominalTqAfterSamplePoint", uint8_t, 8)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Nominal_Timing_Raw(ctypes.Structure):
|
class TCAN4x5x_MCAN_Nominal_Timing_Raw(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# NBRP: The prescaler value from the MCAN system clock. Interpreted by MCAN as the value is this field + 1
|
# NBRP: The prescaler value from the MCAN system clock. Interpreted by MCAN as the value is this field + 1
|
||||||
|
|
@ -179,6 +220,7 @@ class TCAN4x5x_MCAN_Nominal_Timing_Raw(ctypes.Structure):
|
||||||
("NominalSyncJumpWidth", uint8_t, 7)
|
("NominalSyncJumpWidth", uint8_t, 7)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MRAM_Config(ctypes.Structure):
|
class TCAN4x5x_MRAM_Config(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# ************************
|
# ************************
|
||||||
|
|
@ -232,10 +274,9 @@ class TCAN4x5x_MRAM_Config(ctypes.Structure):
|
||||||
# TX Buffers element size: The number of bytes for the TX Buffers (data payload)
|
# TX Buffers element size: The number of bytes for the TX Buffers (data payload)
|
||||||
("TxBufferElementSize", TCAN4x5x_MRAM_Element_Data_Size, 3)
|
("TxBufferElementSize", TCAN4x5x_MRAM_Element_Data_Size, 3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Interrupt_Enable_bits(ctypes.Structure):
|
class TCAN4x5x_MCAN_Interrupt_Enable_bits(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# IE[0] RF0NE: Rx FIFO 0 new message
|
# IE[0] RF0NE: Rx FIFO 0 new message
|
||||||
|
|
@ -332,10 +373,12 @@ class TCAN4x5x_MCAN_Interrupt_Enable_bits(ctypes.Structure):
|
||||||
("reserved", uint8_t, 2)
|
("reserved", uint8_t, 2)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Interrupt_Enable(ctypes.Union):
|
class TCAN4x5x_MCAN_Interrupt_Enable(ctypes.Union):
|
||||||
_fields_ = [("b", TCAN4x5x_MCAN_Interrupt_Enable_bits),
|
_fields_ = [("b", TCAN4x5x_MCAN_Interrupt_Enable_bits),
|
||||||
("word", uint32_t)]
|
("word", uint32_t)]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Interrupts_bits(ctypes.Structure):
|
class TCAN4x5x_MCAN_Interrupts_bits(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# IR[0] RF0N: Rx FIFO 0 new message
|
# IR[0] RF0N: Rx FIFO 0 new message
|
||||||
|
|
@ -432,10 +475,12 @@ class TCAN4x5x_MCAN_Interrupts_bits(ctypes.Structure):
|
||||||
("reserved", uint8_t, 1)
|
("reserved", uint8_t, 1)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Interrupts(ctypes.Union):
|
class TCAN4x5x_MCAN_Interrupts(ctypes.Union):
|
||||||
_fields_ = [("b", TCAN4x5x_MCAN_Interrupts_bits),
|
_fields_ = [("b", TCAN4x5x_MCAN_Interrupts_bits),
|
||||||
("words", uint32_t)]
|
("words", uint32_t)]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_RX_Header(ctypes.Structure):
|
class TCAN4x5x_MCAN_RX_Header(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# CAN ID received
|
# CAN ID received
|
||||||
|
|
@ -472,6 +517,7 @@ class TCAN4x5x_MCAN_RX_Header(ctypes.Structure):
|
||||||
("ANMF", uint8_t, 1)
|
("ANMF", uint8_t, 1)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_Device_Interrupts_bits(ctypes.Structure):
|
class TCAN4x5x_Device_Interrupts_bits(ctypes.Structure):
|
||||||
_fields_ = {
|
_fields_ = {
|
||||||
# DEV_IR[0] VTWD: Global Voltage, Temp, or Watchdog (if equipped) Interrupt
|
# DEV_IR[0] VTWD: Global Voltage, Temp, or Watchdog (if equipped) Interrupt
|
||||||
|
|
@ -571,6 +617,7 @@ class TCAN4x5x_Device_Interrupts_bits(ctypes.Structure):
|
||||||
("CANBUSNORM", uint8_t, 1)
|
("CANBUSNORM", uint8_t, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_Device_Interrupts(ctypes.Union):
|
class TCAN4x5x_Device_Interrupts(ctypes.Union):
|
||||||
_fields_ = [("b", TCAN4x5x_Device_Interrupts_bits),
|
_fields_ = [("b", TCAN4x5x_Device_Interrupts_bits),
|
||||||
("word", uint32_t)]
|
("word", uint32_t)]
|
||||||
|
|
@ -625,12 +672,12 @@ class TCAN4x5x_MCAN_CCCR_Config_bits(ctypes.Structure):
|
||||||
("NISO", uint8_t, 1)
|
("NISO", uint8_t, 1)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_CCCR_Config(ctypes.Union):
|
class TCAN4x5x_MCAN_CCCR_Config(ctypes.Union):
|
||||||
_fields_ = [("b", TCAN4x5x_MCAN_CCCR_Config_bits),
|
_fields_ = [("b", TCAN4x5x_MCAN_CCCR_Config_bits),
|
||||||
("word", uint32_t)]
|
("word", uint32_t)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Global_Filter_Configuration_bits(ctypes.Structure):
|
class TCAN4x5x_MCAN_Global_Filter_Configuration_bits(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# GFC[0] : Reject Remote Frames for Extended IDs
|
# GFC[0] : Reject Remote Frames for Extended IDs
|
||||||
|
|
@ -656,6 +703,8 @@ class TCAN4x5x_MCAN_Global_Filter_Configuration_bits(ctypes.Structure):
|
||||||
# Reserved
|
# Reserved
|
||||||
("reserved", uint32_t, 26)
|
("reserved", uint32_t, 26)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_MCAN_Global_Filter_Configuration(ctypes.Union):
|
class TCAN4x5x_MCAN_Global_Filter_Configuration(ctypes.Union):
|
||||||
_fields_ = [("b", TCAN4x5x_MCAN_Global_Filter_Configuration_bits),
|
_fields_ = [("b", TCAN4x5x_MCAN_Global_Filter_Configuration_bits),
|
||||||
("word", uint32_t)]
|
("word", uint32_t)]
|
||||||
|
|
@ -739,6 +788,7 @@ class TCAN4x5x_device_interrupt_enable_bits(ctypes.BigEndianStructure):
|
||||||
("CANBUSNORMEN", uint8_t, 1)
|
("CANBUSNORMEN", uint8_t, 1)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TCAN4x5x_device_interrupt_enable(ctypes.Union):
|
class TCAN4x5x_device_interrupt_enable(ctypes.Union):
|
||||||
_fields_ = [("b", TCAN4x5x_device_interrupt_enable_bits),
|
_fields_ = [("b", TCAN4x5x_device_interrupt_enable_bits),
|
||||||
("word", uint32_t)]
|
("word", uint32_t)]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue