/* * CAN.c * * Created on: 22.04.2012 * Author: Peter */ #include #include "can.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_can.h" #include "misc.h" #define CAN_EN_Low GPIO_ResetBits(GPIOC, GPIO_Pin_5); #define CAN_EN_High GPIO_SetBits(GPIOC, GPIO_Pin_5); #define CAN_STB_Low GPIO_ResetBits(GPIOC, GPIO_Pin_6); #define CAN_STB_High GPIO_SetBits(GPIOC, GPIO_Pin_6); CAN_DRV_RcvCbk_t rxCbk = NULL; void CAN_DRV_Init(CAN_DRV_Baudrate_e baudrate) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; NVIC_InitTypeDef NVIC_InitStructure; // INIT Interrupts //////////////////////////////// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;// Previously: CAN1_RX1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x2; NVIC_Init(&NVIC_InitStructure); /* Configure CAN1 IOs **********************************************/ /* GPIOA, GPIOC and AFIO clocks enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE); /* Configure CAN1 RX pin */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure CAN1 TX pin */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure EN Pin */ GPIO_WriteBit(GPIOC, GPIO_Pin_5, Bit_SET); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure STB# Pin */ GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure CAN1 ERR# pin */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Remap CAN1 GPIOs (Not required for my project) */ //GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE); /* Configure CAN1 and CAN2 **************************************************/ /* CAN1 and CAN2 Periph clocks enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); // INIT CAN //////////////////////////////// /* CAN1 register init */ CAN_DeInit(CAN1); /* Struct init*/ CAN_StructInit(&CAN_InitStructure); /* CAN1 cell init */ 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_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; switch (baudrate) { case CAN_1000kbaud: CAN_InitStructure.CAN_Prescaler =6; break; case CAN_500kbaud: CAN_InitStructure.CAN_Prescaler =12; break; case CAN_250kbaud: CAN_InitStructure.CAN_Prescaler =24; break; case CAN_125kbaud: CAN_InitStructure.CAN_Prescaler =48; break; } /*Initializes the CAN1 */ CAN_Init(CAN1, &CAN_InitStructure); /* CAN1 filter init */ CAN_FilterInitStructure.CAN_FilterNumber = 1; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x6420; 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 FIFO0 message pending interrupt enable */ CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); /* Enable the transceiver */ CAN_EN_High; CAN_STB_High; } void CAN_DRV_Transmit(CAN_DRV_Message_t *msg) { int i; CanTxMsg txMessage; /* Copy message content */ txMessage.DLC = msg->dlc; txMessage.StdId = msg->id; txMessage.IDE = CAN_ID_STD; txMessage.RTR = CAN_RTR_DATA; txMessage.ExtId = 0x01; for (i = 0; i < msg->dlc; i++) { txMessage.Data[i] = msg->data[i]; } /* Transmit the message */ CAN_Transmit(CAN1, &txMessage); } void CAN_DRV_RegisterRxCbk(CAN_DRV_RcvCbk_t cbk) { rxCbk = cbk; } CAN_DRV_RcvCbk_t CAN_DRV_GetRxCbk( ) { return rxCbk; }