211 lines
6.8 KiB
C
211 lines
6.8 KiB
C
#include "sys.h"
|
|
#include "delay.h"
|
|
#include "can.h"
|
|
#include "includes.h" //ucos Use
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
//This program is for educational purposes only, without the author's permission, may not be used for any other purpose
|
|
//ALIENTEK STM32F4 Explorer Board
|
|
//Initialize serial port 2
|
|
//Hot Atomic @ALIENTEK
|
|
//Forum: www.openedv.com
|
|
//Date modified: 2015/9/12
|
|
//Version: V1.0
|
|
//All rights reserved pirated reserved.
|
|
//Copyright(C) Guangzhou wing electronic technology limited company 2009-2019
|
|
//All rights reserved
|
|
//********************************************************************************
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/* Defines -------------------------------------------------------------------*/
|
|
#define RX_BUFFER_SIZE 320
|
|
|
|
/* Type declarations ---------------------------------------------------------*/
|
|
typedef struct
|
|
{
|
|
CAN_TypeDef *can;
|
|
volatile u16 RxInPos, RxOutPos;
|
|
volatile uint32_t RxOverflowCount;
|
|
u16 TxInPos, TxOutPos;
|
|
CanRxMsg RxBuf[RX_BUFFER_SIZE];
|
|
} CAN_Info;
|
|
|
|
/* Exported macro ------------------------------------------------------------*/
|
|
CAN_Info Can;
|
|
|
|
//Initializes CAN Port
|
|
//Bound: baud rate
|
|
void can1_init(u32 buadrate)
|
|
{
|
|
//GPIO port settings
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
CAN_InitTypeDef CAN_InitStructure;
|
|
CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
|
|
|
Can.can = CAN1;
|
|
|
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC , ENABLE); //Enable GPIOC clock
|
|
|
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD , ENABLE); //Enable GPIOD clock
|
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Enable CAN1 clock
|
|
|
|
//CAN1 pins reuse maps
|
|
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1); //GPIOD 0 multiplex CAN1 RX
|
|
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1); //GPIOD 1 multiplex CAN1 TX
|
|
|
|
//CAN1 port configuration
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //GPIOD 2
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //Multiplexing function
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed 100MHz
|
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //Non Pull-up
|
|
GPIO_Init(GPIOD, &GPIO_InitStructure); //Initialize PD 0, 1 for CAN1 RX, TX
|
|
|
|
//CAN1 port configuration
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //GPIOC 12
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //Multiplexing function
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed 100MHz
|
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //Non Pull-up
|
|
GPIO_Init(GPIOC, &GPIO_InitStructure); //Initialize PD 0, 1 for CAN1 RX, TX
|
|
|
|
//CAN1 port configuration
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //GPIOD 0, 1
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //Multiplexing function
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed 50MHz
|
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //Push-pull multiplexed output
|
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //Pull-up
|
|
GPIO_Init(GPIOD, &GPIO_InitStructure); //Initialize PD 0, 1 for CAN1 RX, TX
|
|
|
|
//CAN1 Initialization settings
|
|
CAN_DeInit(Can.can);
|
|
|
|
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
|
|
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
|
|
|
|
switch (buadrate)
|
|
{
|
|
case 125000:
|
|
CAN_InitStructure.CAN_BS1 = CAN_BS1_2tq;
|
|
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
|
CAN_InitStructure.CAN_Prescaler = 42;
|
|
break;
|
|
case 250000:
|
|
CAN_InitStructure.CAN_BS1 = CAN_BS1_2tq;
|
|
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
|
CAN_InitStructure.CAN_Prescaler = 21;
|
|
break;
|
|
case 500000:
|
|
CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
|
|
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
|
|
CAN_InitStructure.CAN_Prescaler = 7;
|
|
break;
|
|
case 1000000:
|
|
/* CAN Baudrate = 1MBps*/
|
|
CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
|
|
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
|
CAN_InitStructure.CAN_Prescaler = 4;
|
|
break;
|
|
}
|
|
CAN_InitStructure.CAN_TTCM = DISABLE; //
|
|
CAN_InitStructure.CAN_ABOM = DISABLE; //
|
|
CAN_InitStructure.CAN_AWUM = DISABLE; //
|
|
CAN_InitStructure.CAN_NART = DISABLE; //
|
|
CAN_InitStructure.CAN_RFLM = DISABLE; //
|
|
CAN_InitStructure.CAN_TXFP = ENABLE; //
|
|
|
|
/* CAN filter init */
|
|
CAN_FilterInitStructure.CAN_FilterNumber = 0;
|
|
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
|
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
|
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
|
|
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
|
|
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
|
|
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
|
|
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
|
|
|
CAN_FilterInit(&CAN_FilterInitStructure);
|
|
|
|
CAN_Init(Can.can, &CAN_InitStructure); //Initialize CAN1 port
|
|
|
|
CAN_ITConfig(Can.can, CAN_IT_FMP0, ENABLE);
|
|
}
|
|
|
|
void CAN1_RX0_IRQHandler(void) //CAN 1 interrupt service routine
|
|
{
|
|
CanRxMsg RxMessage;
|
|
|
|
CAN_ClearITPendingBit(Can.can, CAN_IT_FMP0);
|
|
|
|
CAN_Receive(Can.can, CAN_FIFO0, &RxMessage);
|
|
|
|
uint16_t next = (uint16_t)((Can.RxInPos + 1U) % RX_BUFFER_SIZE);
|
|
if (next == Can.RxOutPos) {
|
|
Can.RxOverflowCount++;
|
|
} else {
|
|
memcpy(&Can.RxBuf[Can.RxInPos], &RxMessage, sizeof(CanRxMsg));
|
|
__DMB();
|
|
Can.RxInPos = next;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : u8 CAN_GetPacket(CanRxMsg *packet)
|
|
* Description : Send 1 packet data to CAN Port transmit buffer
|
|
* Parameters : none
|
|
* Return : Transmission result (0: buffer empty, 1: buffer has data)
|
|
*******************************************************************************/
|
|
u8 CAN_GetPacket(CanRxMsg *packet)
|
|
{
|
|
if (Can.RxInPos != Can.RxOutPos)
|
|
{
|
|
memcpy(packet, &Can.RxBuf[Can.RxOutPos], sizeof(CanRxMsg));
|
|
__DMB();
|
|
Can.RxOutPos = (uint16_t)((Can.RxOutPos + 1U) % RX_BUFFER_SIZE);
|
|
return SUCCESS;
|
|
}
|
|
else
|
|
return ERROR;
|
|
}
|
|
|
|
void CAN_SendPacket(CanTxMsg *packet)
|
|
{
|
|
u8 retMsgBox;
|
|
uint8_t result;
|
|
int i;
|
|
|
|
uint32_t wait_box = 10000;
|
|
do {
|
|
retMsgBox = CAN_Transmit(Can.can, packet);
|
|
} while ((retMsgBox == CAN_TxStatus_NoMailBox) && (--wait_box > 0));
|
|
|
|
i = 0;
|
|
|
|
if (retMsgBox != CAN_TxStatus_NoMailBox)
|
|
{
|
|
result = CAN_TransmitStatus(CAN1, retMsgBox);
|
|
|
|
// while (((result == CAN_TxStatus_Failed) || (result == CAN_TxStatus_Pending))&&(i < 0xFFF))
|
|
while (((result == CAN_TxStatus_Failed) )&&(i < 0xFF))
|
|
{
|
|
result = CAN_TransmitStatus(CAN1, retMsgBox);
|
|
i++;
|
|
}
|
|
if(i >= 0xFF)
|
|
{
|
|
// if (result == CAN_TxStatus_Pending)
|
|
// CAN_CancelTransmit(CAN1, retMsgBox);
|
|
|
|
// delay_os_ms(100);
|
|
//
|
|
// if (screenmode == DIAG_MODE)
|
|
// printf("\r\n Tx Error (%d)", retMsgBox);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
can1_init(250000);
|
|
delay_os_ms(10);
|
|
retMsgBox = CAN_Transmit(CAN1, packet);
|
|
}
|
|
}
|
|
|