#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); } }