11064 views|13 replies

1366

Posts

6

Resources
The OP
 

MCP2517 (SPI to CAN) debugging record [Copy link]

 

1. Reasons for debugging:

The project requires four CAN channels, but the MCU used is STM32F105, which only has two channels.

CAN, so we use the Microchip SPI to CAN chip - MCP2517. During the debugging process, we consulted the online

The netizen records are not detailed and are not important when introducing. In fact, only CAN transceiver is needed.

port; in addition, all of them use demo, which can be easily transplanted to STM32, and the transplant source code also needs

When using SPI polling mode for sending and receiving, the sending and receiving performance of CAN is greatly affected.

Correct and debug with the help of official manuals and related source codes.

2. Data Acquisition

The data sheet and demo examples are available on the Microchip official website. Select the example of the pic32 platform.

Can.

MCP2517FD | Microchip Technology

3. Source code transplantation and rectification

After decompressing the obtained source code, go to the driver part.

1. SPI driver platform adaptation

What needs to be done is to adapt the SPI driver file drv_spi to the platform, which is mainly for sending and receiving

Chip selection interface, this can be directly used with STM32 HAL, directly use the polling interface of HAL, but

If it is RTOS, you can use semaphore + interrupt receiving and sending. The initialization interface is directly empty because

Cubemx is initialized when it is generated.

1 #include <stdint.h> 
2 #include <stdbool.h> 
3 #include <stddef.h> 
4 #include <stdlib.h> 
5 #include "drv_spi.h" 
6 #include "spi.h" 
7 #include "gpio.h" 
8 #define DRV_CANFDSPI_INDEX_0 0 
9 #define DRV_CANFDSPI_INDEX_1 1 
10
11 int8_t DRV_SPI_ChipSelectAssert(uint8_t spiSlaveDeviceIndex, bool assert) 
12 { 
13 int8_t error = 0; 
14
15 // Select Chip Select 
16 switch (spiSlaveDeviceIndex) { 
17 case DRV_CANFDSPI_INDEX_0: 
18 if (assert) HAL_GPIO_WritePin(SPI1_NSS_CAN3_GPIO_Port,SPI1_N SS_CAN3_Pin, GPIO_PIN_RESET); 
19 else HAL_GPIO_WritePin(SPI1_NSS_CAN3_GPIO_Port,SPI1_NSS_CAN3 _Pin, GPIO_PIN_SET); 
20 error = 0; 
21 break; 
22 case DRV_CANFDSPI_INDEX_1: 
23 if (assert) HAL_GPIO_WritePin(SPI2_NSS_CAN4_GPIO_Port,SPI2_N SS_CAN4_Pin, GPIO_PIN_RESET);
24 else HAL_GPIO_WritePin(SPI2_NSS_CAN4_GPIO_Port,SPI2_NSS_CAN4 _Pin, GPIO_PIN_SET); 
25 error = 0; 
26 break; 
27 default: 
28 error = ‐1; 
29 break; 
30 } 
31 return error; 
32 } 
33
34 void DRV_SPI_Initialize(void) 
35 { 
36 return; 
37 } 
38
39 int8_t DRV_SPI_TransferData(uint8_t spiSlaveDeviceIndex, uint8_t *SpiTxD ata, uint8_t *SpiRxData, uint16_t spiTransferSize) 
40 { 
41 int8_t error = 0; 
42 // Assert CS 
43 error = DRV_SPI_ChipSelectAssert(spiSlaveDeviceIndex, true); 
44 if (error != 0) return error; 
45
46 switch (spiSlaveDeviceIndex) 
47 { 
48 case DRV_CANFDSPI_INDEX_0: 
49 HAL_SPI_TransmitReceive(&hspi1,SpiTxData,SpiRxData,spiTransferSi ze,1000); 
50 break; 
51 case DRV_CANFDSPI_INDEX_1: 
52 HAL_SPI_TransmitReceive(&hspi2,SpiTxData,SpiRxData,spiTransferSi ze,1000); 
53 break; 
54 default: 
55 break; 
56 } 
57 // De‐assert CS 
58 error = DRV_SPI_ChipSelectAssert(spiSlaveDeviceIndex, false); 
59
60 return error;
61 }

In addition, it is important to note that the SPI initialization requires selecting the corresponding mode according to the SPI chapter of the manual.

The frequency does not need to be too high. I divide it to 9M. The initialization is as follows:

1hspi1.Instance=SPI1;
2hspi1.Init.Mode=SPI_MODE_MASTER;
3hspi1.Init.Direction=SPI_DIRECTION_2LINES;
4hspi1.Init.DataSize=SPI_DATASIZE_8BIT;
5hspi1.Init.CLKPolarity=SPI_POLARITY_HIGH;
6hspi1.Init.CLKPhase=SPI_PHASE_2EDGE;
7hspi1.Init.NSS=SPI_NSS_SOFT;
8hspi1.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8;
9hspi1.Init.FirstBit=SPI_FIRSTBIT_MSB;
10hspi1.Init.TIMode=SPI_TIMODE_DISABLE;
11hspi1.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;
12hspi1.Init.CRCPolynomial=10;
13if(HAL_SPI_Init(&hspi1)!=HAL_OK)
14{
15Error_Handler();
16}

Corresponding cubemx initialization

2. SPI to CAN interface correction

During the migration process, many errors and warnings appeared in the interface implementation in the source code.

Records can only be compared with debugged files and source code. The only thing that needs to be modified is

drv_canfdspi_api.c, the related header files included do not need to be modified, just the macro definitions of some registers

wait.

(1) The SPI send and receive buffer needs to be increased. It is defined as 96 bytes, but the actual sending exceeds 96 bytes.

Bytes, the overflow part overwrites the memory space of other peripherals, causing the system to malfunction. This can be changed

SPI_DEFAULT_BUFFER_LENGTH

(2) cREGADDR_CiFIFOCON is defined as 80, but canControlResetValues

The array definition is 20, and the maximum subscript is 19. 80/4 = 20, which will result in a compilation error, so -1 is needed.

(3) The word array of the CAN_BUS_DIAGNOSTIC structure member is only 2, but when assigning a value

Subscript overflow, needs to be commented out.

(4) Switch problem: since there is a return, there is no need to break. This is probably a code format problem.

4. Optimize sending and receiving

According to official and online transplants, most of the reception is polling to call the receiving interface, and the sending is also not

Determine whether the transmission is successful. In this way, there is a problem that the FIFO is full and the receiving packet is lost, and the transmission result cannot be guaranteed.

However, the official pins use the transmit and receive interrupt pin output, so that the IO pin interrupt can be used.

Quickly respond to CAN transmission and reception, and process transmission and reception within the interrupt.

In this way, we can use three pins to perform external IO interrupts. If the IO pins are sufficient,

You can use these three pins. If the pins are limited, just use the INT global interrupt output pin.

Just configure the relevant interrupt enable.

MCP2517 supports up to 32 bits of depth for transmission and reception, which also meets the requirements of high-speed transmission and reception.

When the FIFO is configured, two FIFOs are allocated to the transmitter and receiver, and the receive interrupt is enabled.

1static voidcan_mcp2517_config(uint8_t index)
2{
3CAN_MODULE_EVENTflags;
4if(index>DRV_CANFDSPI_INDEX_1)
5return;
6CAN_OPERATION_MODEmode;
7// Reset device
8DRV_CANFDSPI_Reset(index);
9mode=DRV_CANFDSPI_OperationModeGet(index);
10printf("[config]can_bms_mcp2517_config mode:%d %d \r\n",mode,index);
11// Oscillator Configuration: divide by 10
12CAN_OSC_CTRLoscCtrl;
13DRV_CANFDSPI_OscillatorControlObjectReset(&oscCtrl);
14oscCtrl.ClkOutDivide=OSC_CLKO_DIV10;
15DRV_CANFDSPI_OscillatorControlSet(index,oscCtrl);
16// Input/Output Configuration: use nINT0 and nINT1
17// DRV_CANFDSPI_GpioModeConfigure(index, GPIO_MODE_GPIO, GPIO_MODE_GP
IO);
18// CAN Configuration: ISO_CRC, enable TEF, enable TXQ
19CAN_CONFIGconfig;
20DRV_CANFDSPI_ConfigureObjectReset(&config);
21config.IsoCrcEnable=1;
22config.StoreInTEF=1;
23config.TXQEnable=1;
24DRV_CANFDSPI_Configure(index,&config);
25// Bit Time Configuration: 500K/2M, 80% sample point
26DRV_CANFDSPI_BitTimeConfigure(index,CAN_1000K_4M,
CAN_SSP_MODE_AUTO,CAN_SYSCLK_20M);27// TEF Configuration: 12 messages, time stamping enabled
28CAN_TEF_CONFIGtefConfig;
29tefConfig.FifoSize=11;
30tefConfig.TimeStampEnable=1;
31DRV_CANFDSPI_TefConfigure(index,&tefConfig);
32// TXQ Configuration: 8 messages, 32 byte maximum payload, high prio
rity
33CAN_TX_QUEUE_CONFIGtxqConfig;
34DRV_CANFDSPI_TransmitQueueConfigureObjectReset(&txqConfig);
35txqConfig.TxPriority=1;
36txqConfig.FifoSize=7;
37txqConfig.PayLoadSize=CAN_PLSIZE_32;
38DRV_CANFDSPI_TransmitQueueConfigure(index,&txqConfig);
39// FIFO 1: Transmit FIFO; 5 messages, 64 byte maximum payload, low p
riority
40CAN_TX_FIFO_CONFIGtxfConfig;
41DRV_CANFDSPI_TransmitChannelConfigureObjectReset(&txfConfig);
42txfConfig.FifoSize=15;
43txfConfig.PayLoadSize=CAN_PLSIZE_8;
44txfConfig.TxPriority=0;
45DRV_CANFDSPI_TransmitChannelConfigure(index,CAN_FIFO_CH1,&txfConfi
g);
46// FIFO 2: Receive FIFO; 16 messages, 64 byte maximum payload, time
stamping enabled
47CAN_RX_FIFO_CONFIGrxfConfig;
48rxfConfig.FifoSize=30;
49rxfConfig.PayLoadSize=CAN_PLSIZE_8;
50rxfConfig.RxTimeStampEnable=1;
51DRV_CANFDSPI_ReceiveChannelConfigure(index,CAN_FIFO_CH2,
&rxfConfig);
52// Double Check RAM Usage: 2040 Bytes out of a maximum of 2048 Bytes
‐> OK.
53// Enable ECC
54DRV_CANFDSPI_EccEnable(index);
55// Initialize RAM
56DRV_CANFDSPI_RamInit(index,0xff);
57
58HAL_Delay(1);
59DRV_CANFDSPI_GpioInterruptPinsOpenDrainConfigure(index,GPIO_PUSH_PUL
L);
60// DRV_CANFDSPI_TransmitChannelEventEnable(index, CAN_FIFO_CH1, CAN_T
X_FIFO_NOT_FULL_EVENT);61DRV_CANFDSPI_ReceiveChannelEventEnable(index,CAN_FIFO_CH2,CAN_RX_F
IFO_NOT_EMPTY_EVENT);
62// DRV_CANFDSPI_ModuleEventEnable(index, CAN_TX_EVENT);//不使能发
送
63DRV_CANFDSPI_ModuleEventEnable(index,CAN_RX_EVENT);
64DRV_CANFDSPI_ModuleEventEnable(index,CAN_RX_OVERFLOW_EVENT);
65HAL_Delay(1);
66DRV_CANFDSPI_ModuleEventEnableGet(index,&flags);
67printf("[config]can_bms_mcp2517_config flag:%d 0x%lx \r\n",index,fla
gs);
68DRV_CANFDSPI_OperationModeSelect(index,CAN_CLASSIC_MODE);
69HAL_Delay(5);
70
71mode=DRV_CANFDSPI_OperationModeGet(index);
72printf("[config]can_bms_mcp2517_config mode~~:%d %d
\r\n",mode,index);
73
74if(can_mcp2517_exit_flag[index])
75{
76can_mcp2517_exit_flag[index]=0;
77DRV_CANFDSPI_ModuleEventGet(index,&flags);
78printf("[config]can_mcp2517_exit_flag11 :%d 0x%lx \r\n",index,fl
ags);
79DRV_CANFDSPI_ModuleEventClear(index,flags);
80// DRV_CANFDSPI_ModuleEventClear(index,CAN_TX_EVENT);
81DRV_CANFDSPI_ModuleEventGet(index,&flags);
82printf("[config]can_mcp2517_exit_flag22 :%d 0x%lx \r\n",index,fl
ags);
83}
84
85
86}

How to ensure the success of the transmission? When the data is inserted into the FIFO, turn on the FIFO to empty it.

Interrupt, enter the interrupt, and the bit is set, which ensures successful transmission.

1
2boolcan_mcp2517_transmit(uint8_t num,uint32_t id,constuint8_t*data,u
int8_t data_len)
3{
4CAN_TX_MSGOBJtxObj;
5uint8_t txd[MAX_DATA_BYTES];
6// Initialize ID and Control bits7txObj.word[0]=0;
8txObj.word[1]=0;
9txObj.bF.id.SID=((id>>18)&0x7ff);// Standard or Base ID
10txObj.bF.id.EID=(id&0x3ffff);
11
12txObj.bF.ctrl.FDF=0;// not CAN FD frame
13txObj.bF.ctrl.BRS=0;// Switch bit rate
14txObj.bF.ctrl.IDE=1;// externd frame
15txObj.bF.ctrl.RTR=0;// Not a remote frame request
16txObj.bF.ctrl.DLC=(data_len&0x0F);
17// Sequence: doesn't get transmitted, but will be stored in TEF
18txObj.bF.ctrl.SEQ=1;
19
20// Initialize transmit data
21uint8_t i;
22for(i=0;i<DRV_CANFDSPI_DlcToDataBytes((CAN_DLC)txObj.bF.ctrl.D
LC);i++) {
23txd=data;
24}
25// Check that FIFO is not full
26CAN_TX_FIFO_EVENTtxFlags;
27bool flush=true;
28DRV_CANFDSPI_TransmitChannelEventGet(num,CAN_FIFO_CH1,&txFlags);
29if(txFlags&CAN_TX_FIFO_NOT_FULL_EVENT) {
30// Load message and transmit
31DRV_CANFDSPI_TransmitChannelLoad(num,CAN_FIFO_CH1,&txObj,txd,
32DRV_CANFDSPI_DlcToDataBytes((CAN_DLC)txObj.bF.ctrl.DLC),
flush);
33can_mcp2517_send_flag[num]=1;
34//使能发送FIFO为空中断
35DRV_CANFDSPI_TransmitChannelEventEnable(num,CAN_FIFO_CH1,CAN_T
X_FIFO_NOT_FULL_EVENT);
36DRV_CANFDSPI_ModuleEventEnable(num,CAN_TX_EVENT);
37returnTRUE;
38}
39else
40{
41returnFALSE;
42}
43
44}

What we need to do in external IO interrupt processing is to determine whether the relevant interrupt flag is set and make the corresponding

After the corresponding processing, the flag must be cleared.


1voidcan_mcp2517_rtx_handler(uint8_t index)
2{
3CAN_MODULE_EVENTflags;
4can_mcp2517_exit_flag[index]=1;
5
6DRV_CANFDSPI_ModuleEventGet(index,&flags);
7//发送成功
8if(((flags&CAN_TX_EVENT)==CAN_TX_EVENT)&&
(can_mcp2517_send_flag[index]))
9{
10can_mcp2517_send_flag[index]=0;
11DRV_CANFDSPI_TransmitChannelEventDisable(index,CAN_FIFO_CH1,CAN
_TX_FIFO_EMPTY_EVENT);
12DRV_CANFDSPI_ModuleEventDisable(index,CAN_TX_EVENT);
13DRV_CANFDSPI_ModuleEventClear(index,CAN_TX_EVENT);
14if(index==DRV_CANFDSPI_INDEX_0)
15{
16can_info.tx_cb(2);
17}
18else if(index==DRV_CANFDSPI_INDEX_1)
19{
20can_info.tx_cb(3);
21}
22}
23//有接收
24if((flags&CAN_RX_EVENT)==CAN_RX_EVENT)
25{
26DRV_CANFDSPI_ModuleEventClear(index,CAN_RX_EVENT);
27can_mcp2517_receive(index);
28}
29if((flags&CAN_RX_OVERFLOW_EVENT)==CAN_RX_OVERFLOW_EVENT)30{
31DRV_CANFDSPI_ModuleEventClear(index,CAN_RX_OVERFLOW_EVENT);
32can_mcp2517_receive(index);
33
DRV_CANFDSPI_ReceiveChannelEventOverflowClear(index,CAN_FIFO_CH2);
34}
35if((flags&CAN_TEF_EVENT)==CAN_TEF_EVENT)
36{
37//清除相关中断标志
38DRV_CANFDSPI_ModuleEventClear(index,CAN_TEF_EVENT);
39}
40if((flags&CAN_TX_ATTEMPTS_EVENT)==CAN_TX_ATTEMPTS_EVENT)
41{
42DRV_CANFDSPI_ModuleEventClear(index,CAN_TX_ATTEMPTS_EVENT);
43}
44if((flags&CAN_SYSTEM_ERROR_EVENT)==CAN_SYSTEM_ERROR_EVENT)
45{
46DRV_CANFDSPI_ModuleEventClear(index,CAN_SYSTEM_ERROR_EVENT);
47}
48if((flags&CAN_BUS_ERROR_EVENT)==CAN_BUS_ERROR_EVENT)
49{
50DRV_CANFDSPI_ModuleEventClear(index,CAN_BUS_ERROR_EVENT);
51}
52if((flags&CAN_BUS_WAKEUP_EVENT)==CAN_BUS_WAKEUP_EVENT)
53{
54DRV_CANFDSPI_ModuleEventClear(index,CAN_BUS_WAKEUP_EVENT);
55}
56if((flags&CAN_RX_INVALID_MESSAGE_EVENT)==CAN_RX_INVALID_MESSAGE
_EVENT)
57{
58
DRV_CANFDSPI_ModuleEventClear(index,CAN_RX_INVALID_MESSAGE_EVENT);
59}
60DRV_CANFDSPI_ModuleEventClear(index,flags);
61}

It is important to note that when a receive interrupt arrives, the FIFO may have several depths.

According to the conditions, it is necessary to determine whether the FIFO is empty.


This content is originally created by RCSN , a user of EEWORLD forum . If you want to reprint or use it for commercial purposes, you need to obtain the author's consent and indicate the source

This post is from stm32/stm8

Latest reply

Can you upload the source code?  Details Published on 2023-7-11 12:21
Personal signature

1084534438 欢迎交流  [加油,一切皆有可能]

 

1366

Posts

6

Resources
2
 

The attachments are as follows:

MCP2517FD数据手册.pdf

1.48 MB, 阅读权限: 5, downloads: 52

MCP2517FD canfdspi API for PIC32MX470 _v1.0.zip

1.18 MB, 阅读权限: 5, downloads: 60

官方demo

This post is from stm32/stm8
 
Personal signature

1084534438 欢迎交流  [加油,一切皆有可能]

 

368

Posts

0

Resources
3
 

The company has used MCP2518FD. There seems to be a bug in 2517. This chip is seriously out of stock. The email sent by the original manufacturer said it is 52 weeks.

This post is from stm32/stm8

Comments

Is there any bug in 2517? We seem to have enough stock.  Details Published on 2022-3-23 20:05
 
 

1366

Posts

6

Resources
4
 
1399866558 Published on 2022-3-23 19:23 The company has used MCP2518FD. 2517 seems to have a bug. This chip is seriously out of stock. The original factory sent an email saying that it is 52 weeks.

Is there any bug in 2517? We seem to have enough stock.

This post is from stm32/stm8

Comments

The microchip manufacturer said that the products we use are automotive grade.  Details Published on 2022-3-24 11:09
 
Personal signature

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

368

Posts

0

Resources
5
 
RCSN posted on 2022-3-23 20:05 Is there any bug in 2517? We seem to have enough goods. .

The microchip manufacturer said that the products we use are automotive grade.

This post is from stm32/stm8
 
 
 

2870

Posts

4

Resources
6
 

What is the maximum speed of the Brother CAN?

This post is from stm32/stm8
 
 
 

6841

Posts

11

Resources
7
 

stm32f105 processes four CAN channels. If the transmission and reception are 1ms, can it handle it? I used to do the processing on the automotive ECU, which is a bit difficult.

This post is from stm32/stm8

Comments

If you only use 1ms receive/send buffer processing and no logic processing, I think there is no problem with using interrupts for receiving/sending. If you need to do logic processing, that's another matter.  Details Published on 2022-4-1 09:49
 
 
 

1582

Posts

0

Resources
8
 

SPI to CAN, this is the first time I see it, can it be used in automotive products?

I have saved your tutorial, thank you.

This post is from stm32/stm8

Comments

The material of mcp2517 is quite stable. In addition, it has more than 30 fifo depths inside, so there is no problem in using it in automotive products.  Details Published on 2022-4-1 09:50
 
 
 

7452

Posts

2

Resources
9
 

Why do we have to transfer it again? Wouldn't it be better to just use a can?

This post is from stm32/stm8

Comments

MCP2517 (SPI to CAN) debugging record 1. Debugging reason: The project requires four CAN channels, but the MCU used is STM32F105, which has only two CAN channels, so Microchip's SPI to CAN chip - MCP2517 is used.  Details Published on 2022-4-1 09:50
 
Personal signature

默认摸鱼,再摸鱼。2022、9、28

 
 

1366

Posts

6

Resources
10
 
lugl4313820 posted on 2022-3-31 08:43 Can stm32f105 handle four-way CAN if the transmission and reception are 1ms? I used to do processing in automotive ECU, which is a bit difficult. .

If you only use 1ms receive/send buffer processing and no logic processing, I think there is no problem with using interrupts for receiving/sending. If you need to do logic processing, that's another matter.

This post is from stm32/stm8
 
Personal signature

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

1366

Posts

6

Resources
11
 
se7ens posted on 2022-3-31 17:59 SPI to CAN, this is the first time I see it, can it be used in automotive products? I have saved the tutorial of the OP, thank you

The material of mcp2517 is quite stable. In addition, it has more than 30 fifo depths inside, so there is no problem in using it in automotive products.

This post is from stm32/stm8
 
Personal signature

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

1366

Posts

6

Resources
12
 
freebsder posted on 2022-3-31 19:34 Why do you have to transfer it again? Isn't it better to just use can?

MCP2517 (SPI to CAN) debugging record

1. Reasons for debugging:

The project requires four CAN channels, but the MCU used is STM32F105, which only has two channels.

CAN, so we use Microchip's SPI to CAN chip - MCP2517.

You didn't even watch the beginning.

This post is from stm32/stm8
 
Personal signature

1084534438 欢迎交流  [加油,一切皆有可能]

 
 

1

Posts

0

Resources
13
 

Questioner, your error variable is init8_t, how can you assign -1? There is something wrong with this code

This post is from stm32/stm8
 
 
 

2

Posts

0

Resources
14
 

Can you upload the source code?


This post is from stm32/stm8
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list