diff --git a/f1/can/include/can.h b/f1/can/include/can.h new file mode 100644 index 0000000000000000000000000000000000000000..0d65b11d627dc2c0a2e72762879d16a62ed3123e --- /dev/null +++ b/f1/can/include/can.h @@ -0,0 +1,19 @@ +#ifndef CAN_F1_H +#define CAN_F1_H + +#include "stm32f1xx_hal.h" +#include "comm.h" + +/* public functions */ +void can_init(TComm *comm_dev,CAN_InitTypeDef *conf,TCAN_IRQ_Priorities *priorities); +void can_config(TComm *comm_dev,CAN_InitTypeDef *conf); +void can_set_priorities(TComm *comm_dev,TCAN_IRQ_Priorities *priorities); +void can_set_bitrate(TComm *comm_dev,unsigned int bitrate); +void can_set_filter(TComm *comm_dev,CAN_FilterTypeDef *filter) +/* IRQ functions */ +unsigned char can_send_irq(unsigned char first_byte); +unsigned char can_enable_tx_irq(void); +unsigned char can_receive_irq(void); +unsigned char can_cancel_receive_irq(void); + +#endif diff --git a/f1/can/include/can_common.h b/f1/can/include/can_common.h new file mode 100644 index 0000000000000000000000000000000000000000..f7eabaff39d5986f886369ab1df4663a2b8ff2ad --- /dev/null +++ b/f1/can/include/can_common.h @@ -0,0 +1,22 @@ +#ifndef CAN_COMMON_F1_H +#define CAN_COMMON_F1_H + +typedef struct +{ + unsigned char irq_priority; + unsigned char irq_subpriority; +}TCAN_IRQ_Priorities; + +enum CAN_SPEED { //only applies when APB1 = 36Mhz + CAN_10KBPS, + CAN_20KBPS, + CAN_50KBPS, + CAN_83K3BPS, + CAN_100KBPS, + CAN_125KBPS, + CAN_250KBPS, + CAN_500KBPS, + CAN_1000KBPS +}; + +#endif diff --git a/f1/can/src/can.c b/f1/can/src/can.c new file mode 100644 index 0000000000000000000000000000000000000000..0f2894d96e314d65e9a850e5b99685e38366b8fa --- /dev/null +++ b/f1/can/src/can.c @@ -0,0 +1,193 @@ +#include "can.h" + +#define CAN CAN1 +#define CAN_ENABLE_CLK __HAL_RCC_CAN1_CLK_ENABLE() +#define CAN_IRQnRX USB_LP_CAN1_RX0_IRQn +#define CAN_IRQnTX USB_HP_CAN1_TX_IRQn +#define CAN_IRQHandler USB_LP_CAN1_RX0CAN_IRQHandler + +#define CAN_TX_PIN GPIO_PIN_9 +#define CAN_TX_GPIO_PORT GPIOB +#define CAN_ENABLE_TX_GPIO_CLK __HAL_RCC_GPIOB_CLK_ENABLE() + +#define CAN_RX_PIN GPIO_PIN_8 +#define CAN_RX_GPIO_PORT GPIOB +#define CAN_ENABLE_RX_GPIO_CLK __HAL_RCC_GPIOB_CLK_ENABLE() + +// private variables +CAN_HandleTypeDef CANHandle; +CanTxMsgTypeDef CAN_txMessage; +CanRxMsgTypeDef CAN_rxMessage; +TComm *can_comm_dev; + + +void can_init(TComm *comm_dev,CAN_InitTypeDef *conf,TCAN_IRQ_Priorities *priorities) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable GPIO clock */ + CAN_ENABLE_TX_GPIO_CLK; + CAN_ENABLE_RX_GPIO_CLK; + + CAN_ENABLE_CLK; + + /**CAN GPIO Configuration + PB8 ------> CAN_RX + PB9 ------> CAN_TX + */ + /* Configure CAN Tx and Rx as alternate function push-pull */ + GPIO_InitStructure.Pin = CAN_RX_PIN; + GPIO_InitStructure.Pull = GPIO_PULLDOWN; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + HAL_GPIO_Init(CAN_RX_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = CAN_TX_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(CAN_TX_GPIO_PORT, &GPIO_InitStructure); + + _HAL_AFIO_REMAP_CAN1_2(); + + + CANHandle.Instance = CAN; + can_config(comm_dev,conf); + + can_set_priorities(comm_dev,priorities); + + /* Initialize the comm structure */ + comm_dev->send_irq=can_send_irq; + comm_dev->enable_tx_irq=can_enable_tx_irq; + comm_dev->receive_irq=can_receive_irq; + comm_dev->cancel_receive_irq=can_cancel_receive_irq; + comm_dev->irq_send_cb=0x00000000; + comm_dev->irq_receive_cb=0x00000000; + comm_dev->dma_send_cb=0x00000000; + comm_dev->dma_receive_cb=0x00000000; + + /* initialize internal variables */ + can_comm_dev=comm_dev; + HAL_CAN_Start(CANHandle); +} + +void can_config(TComm *comm_dev,CAN_InitTypeDef *conf) +{ + CANHandle.Init.Prescaler = conf->Prescaler; + CANHandle.Init.Mode = conf->Mode; + CANHandle.Init.SJW = conf->SJW; + CANHandle.Init.BS1 = conf->BS1; + CANHandle.Init.BS2 = conf->BS2; + CANHandle.Init.TTCM = conf->TTCM; + CANHandle.Init.ABOM = conf->ABOM; + CANHandle.Init.AWUM = conf->AWUM; + CANHandle.Init.NART = conf->NART; + CANHandle.Init.RFLM = conf->RFLM; + CANHandle.Init.TXFP = conf->TXFP; + HAL_CAN_Init(&CANHandle); +} + +void can_set_priorities(TComm *comm_dev,TCAN_IRQ_Priorities *priorities) +{ + HAL_NVIC_SetPriority(CAN_IRQnRX, priorities->irq_priority, priorities->irq_subpriority); + HAL_NVIC_EnableIRQ(CAN_IRQnRX); + HAL_NVIC_SetPriority(CAN_IRQnTX, priorities->irq_priority, priorities->irq_subpriority); + HAL_NVIC_EnableIRQ(CAN_IRQnTX); +} + +void can_set_bitrate(TComm *comm_dev,CAN_SPEED bitrate) +{ + switch (CAN_SPEED) { + case CAN_10KBPS: + CANHandle.Init.Prescaler = 225; + CANHandle.Init.TimeSeg1 = 13; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + case CAN_20KBPS: + CANHandle.Init.Prescaler = 100; + CANHandle.Init.TimeSeg1 = 15; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + case CAN_50KBPS: + CANHandle.Init.Prescaler = 45; + CANHandle.Init.TimeSeg1 = 13; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + case CAN_83K3BPS: + CANHandle.Init.Prescaler = 27; + CANHandle.Init.TimeSeg1 = 13; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + case CAN_100KBPS: + CANHandle.Init.Prescaler = 20; + CANHandle.Init.TimeSeg1 = 15; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + case CAN_125KBPS: + CANHandle.Init.Prescaler = 18; + CANHandle.Init.TimeSeg1 = 13; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + case CAN_250KBPS: + CANHandle.Init.Prescaler = 9; + CANHandle.Init.TimeSeg1 = 13; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + case CAN_500KBPS: + CANHandle.Init.Prescaler = 4; + CANHandle.Init.TimeSeg1 = 15; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + case CAN_1000KBPS: + CANHandle.Init.Prescaler = 2; + CANHandle.Init.TimeSeg1 = 15; + CANHandle.Init.TimeSeg2 = 2; + CANHandle.Init.SyncJumpWidth = 1; + break; + } +} + +void can_set_filter(TComm *comm_dev,CAN_FilterTypeDef *filter) +{ + HAL_CAN_ConfigFilter(&CANHandle, &filter); + HAL_CAN_Receive_IT(&CANHandle,CAN_FIFO0); +} + +// interrupt handlers +void USB_LP_CAN1_RX0_IRQHandler(void) +{ + /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */ + + /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */ + HAL_PCD_IRQHandler(&PCDHandle); + /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */ + + /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */ +} + +void USB_HP_CAN1_TX_IRQHandler(void) +{ + /* USER CODE BEGIN USB_HP_CAN1_TX_IRQn 0 */ + + /* USER CODE END USB_HP_CAN1_TX_IRQn 0 */ + HAL_CAN_IRQHandler(&hcan); + /* USER CODE BEGIN USB_HP_CAN1_TX_IRQn 1 */ + + /* USER CODE END USB_HP_CAN1_TX_IRQn 1 */ +} + +void usb_disconnect(void) +{ + HAL_PCD_DevDisconnect(&PCDHandle); +} + +void usb_connect(void) +{ + HAL_PCD_DevConnect(&PCDHandle); +}