diff --git a/f1/can/include/can.h b/f1/can/include/can.h index 0d65b11d627dc2c0a2e72762879d16a62ed3123e..b1cbd78e66c295111989fa13753c6d5fbfe3ec07 100644 --- a/f1/can/include/can.h +++ b/f1/can/include/can.h @@ -4,16 +4,100 @@ #include "stm32f1xx_hal.h" #include "comm.h" +typedef struct +{ + unsigned char irq_priority; + unsigned char irq_subpriority; +}TCAN_IRQ_Priorities; + +typedef enum +{ + CAN_10KBPS, + CAN_20KBPS, + CAN_50KBPS, + CAN_83K3BPS, + CAN_100KBPS, + CAN_125KBPS, + CAN_250KBPS, + CAN_500KBPS, + CAN_1000KBPS +} CAN_SPEED; + +typedef enum +{ + VERSION_1, + VERSION_2, + VERSION_NULL +} DynamixelVersion; + +typedef struct TDynamixelMessage +{ + unsigned char received_bytes; +/** + * \brief + * + */ + unsigned char rx_buffer[MAX_DYN_SLAVE_RX_BUFFER_LEN]; +/** + * \brief + * + */ + unsigned char Len_L; +/** + * \brief + * + */ + unsigned char Len_H; +/** + * \brief + * + */ + unsigned int length; +/** + * \brief + * + */ + DynamixelVersion version; +/** + * \brief + * + */ + unsigned char packet_init; +/** + * \brief + * + */ + unsigned char packet_incomplete; +/** + * \brief + * + */ + unsigned char send_packet; +/** + * \brief + * + */ + unsigned char iterations; +/** + * \brief + * + */ +}TDynamixelMessage; + /* 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) +void can_set_bitrate(TComm *comm_dev,CAN_SPEED bitrate); +void can_set_filter(TComm *comm_dev,CAN_FilterConfTypeDef *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); +/* DMA functions */ +unsigned char can_send_dma(unsigned char *data,unsigned short int length); +unsigned char can_receive_dma(unsigned char *data,unsigned short int length); +unsigned char can_cancel_receive_dma(void); #endif diff --git a/f1/can/src/can.c b/f1/can/src/can.c index 0f2894d96e314d65e9a850e5b99685e38366b8fa..c78107c986cde75bdc8a2c966a20bc2fe46d48e8 100644 --- a/f1/can/src/can.c +++ b/f1/can/src/can.c @@ -16,13 +16,24 @@ // private variables CAN_HandleTypeDef CANHandle; +CAN_FilterConfTypeDef CANFilterConfig; CanTxMsgTypeDef CAN_txMessage; CanRxMsgTypeDef CAN_rxMessage; + TComm *can_comm_dev; +unsigned char can_dma_phase; +unsigned char *can_dma_phase_data; +unsigned short int can_dma_phase_length; +unsigned short int can_dma_phase_write_ptr; +TDynamixelMessage message; +// 1 void can_init(TComm *comm_dev,CAN_InitTypeDef *conf,TCAN_IRQ_Priorities *priorities) { + CANHandle.Instance = CAN1; + can_config(comm_dev,conf); + GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIO clock */ @@ -37,7 +48,7 @@ void can_init(TComm *comm_dev,CAN_InitTypeDef *conf,TCAN_IRQ_Priorities *priorit */ /* Configure CAN Tx and Rx as alternate function push-pull */ GPIO_InitStructure.Pin = CAN_RX_PIN; - GPIO_InitStructure.Pull = GPIO_PULLDOWN; + GPIO_InitStructure.Pull = GPIO_MODE_INPUT; GPIO_InitStructure.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(CAN_RX_GPIO_PORT, &GPIO_InitStructure); @@ -46,27 +57,65 @@ void can_init(TComm *comm_dev,CAN_InitTypeDef *conf,TCAN_IRQ_Priorities *priorit 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); + __HAL_AFIO_REMAP_CAN1_2(); can_set_priorities(comm_dev,priorities); + HAL_CAN_Init(&CANHandle); + /* 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; + if(comm_dev->use_dma) + { + comm_dev->send_dma=can_send_dma; + comm_dev->receive_dma=can_receive_dma; + comm_dev->cancel_receive_dma=can_cancel_receive_dma; + } 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 */ + // /* initialize internal variables */ can_comm_dev=comm_dev; - HAL_CAN_Start(CANHandle); + + can_dma_phase=0x00; + can_dma_phase_data=0x00; + can_dma_phase_length=0; + can_dma_phase_write_ptr=0; + + message.packet_init = 0x00; + message.packet_incomplete = 0x00; + message.send_packet = 0x00; + message.iterations = 0; + /////////////////////////////////////////////////////////////////////////// + CANFilterConfig.FilterNumber = 0; + CANFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; + CANFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; + CANFilterConfig.FilterIdHigh = 0x0000; + CANFilterConfig.FilterIdLow = 0x0000; + CANFilterConfig.FilterMaskIdHigh = 0x0000; + CANFilterConfig.FilterMaskIdLow = 0x0000; + CANFilterConfig.FilterFIFOAssignment = 0; + CANFilterConfig.FilterActivation = ENABLE; + CANFilterConfig.BankNumber = 0; + + HAL_CAN_ConfigFilter(&CANHandle, &CANFilterConfig); + + + CANHandle.pRxMsg = &CAN_rxMessage; + CANHandle.pTxMsg = &CAN_txMessage; + + CANHandle.pTxMsg->StdId = 0x321; + CANHandle.pTxMsg->ExtId = 0x01; + CANHandle.pTxMsg->RTR = CAN_RTR_DATA; + CANHandle.pTxMsg->IDE = CAN_ID_STD; + + HAL_CAN_Receive_IT(&CANHandle,CAN_FIFO0); + } void can_config(TComm *comm_dev,CAN_InitTypeDef *conf) @@ -82,7 +131,6 @@ void can_config(TComm *comm_dev,CAN_InitTypeDef *conf) 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) @@ -95,77 +143,268 @@ void can_set_priorities(TComm *comm_dev,TCAN_IRQ_Priorities *priorities) void can_set_bitrate(TComm *comm_dev,CAN_SPEED bitrate) { - switch (CAN_SPEED) { + switch (bitrate) { case CAN_10KBPS: CANHandle.Init.Prescaler = 225; - CANHandle.Init.TimeSeg1 = 13; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_13TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; case CAN_20KBPS: CANHandle.Init.Prescaler = 100; - CANHandle.Init.TimeSeg1 = 15; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_15TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; case CAN_50KBPS: CANHandle.Init.Prescaler = 45; - CANHandle.Init.TimeSeg1 = 13; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_13TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; case CAN_83K3BPS: CANHandle.Init.Prescaler = 27; - CANHandle.Init.TimeSeg1 = 13; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_13TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; case CAN_100KBPS: CANHandle.Init.Prescaler = 20; - CANHandle.Init.TimeSeg1 = 15; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_15TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; case CAN_125KBPS: CANHandle.Init.Prescaler = 18; - CANHandle.Init.TimeSeg1 = 13; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_13TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; case CAN_250KBPS: CANHandle.Init.Prescaler = 9; - CANHandle.Init.TimeSeg1 = 13; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_13TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; case CAN_500KBPS: CANHandle.Init.Prescaler = 4; - CANHandle.Init.TimeSeg1 = 15; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_15TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; case CAN_1000KBPS: CANHandle.Init.Prescaler = 2; - CANHandle.Init.TimeSeg1 = 15; - CANHandle.Init.TimeSeg2 = 2; - CANHandle.Init.SyncJumpWidth = 1; + CANHandle.Init.BS1 = CAN_BS1_15TQ; + CANHandle.Init.BS2 = CAN_BS2_2TQ; + CANHandle.Init.SJW = CAN_SJW_1TQ; break; } } -void can_set_filter(TComm *comm_dev,CAN_FilterTypeDef *filter) +void can_set_filter(TComm *comm_dev,CAN_FilterConfTypeDef *filter) { - HAL_CAN_ConfigFilter(&CANHandle, &filter); + HAL_CAN_ConfigFilter(&CANHandle, filter); HAL_CAN_Receive_IT(&CANHandle,CAN_FIFO0); } +void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *CANHandle) +{ + HAL_CAN_Receive_IT(CANHandle,CAN_FIFO0); + // HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4); +} + +void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* CANHandle) +{ + // HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4); +} + +void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CANHandle) +{ + // for (int i = 0; i<10; i++){ + // HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4); + // for (int i = 0; i<100000; i++){;} + // } + + for(uint8_t i=0;i<CAN_rxMessage.DLC;i++) + { + if(!can_dma_phase) + comm_do_irq_receive(can_comm_dev,CAN_rxMessage.Data[i]); + else + { + can_dma_phase_data[can_dma_phase_write_ptr]=CAN_rxMessage.Data[i]; + can_dma_phase_length--; + can_dma_phase_write_ptr++; + if(can_dma_phase_length==0) + comm_do_dma_receive(can_comm_dev); + } + } + HAL_CAN_Receive_IT(CANHandle,CAN_FIFO0); + // message.received_bytes = 0; + // if(!message.packet_init) + // { + // if (CAN_rxMessage.DLC<6) + // { + // message.Len_L = 0x00; + // message.Len_H = 0x00; + // message.length = 0x00; + // message.packet_init = 0x00; + // message.packet_incomplete = 0x00; + // message.send_packet = 0x00; + // message.version = VERSION_NULL; + // } + // else + // { + // for(uint8_t i=0;i<CAN_rxMessage.DLC;i++) + // { + // uint8_t byte = CAN_rxMessage.Data[i]; + // + // switch(message.received_bytes) + // { + // case 0: if(byte==0xFF) + // { + // message.rx_buffer[message.received_bytes]=byte; + // message.received_bytes++; + // } + // break; + // case 1: if(byte==0xFF) + // { + // message.rx_buffer[message.received_bytes]=byte; + // message.received_bytes++; + // } + // else + // message.received_bytes--; + // break; + // case 2: message.rx_buffer[message.received_bytes]=byte; //ID vs 0xFD + // message.received_bytes++; + // break; + // case 3: if(byte!=0x00) //Length vs 0x00 + // { + // message.version = VERSION_1; + // message.Len_L = byte; + // message.length = byte+4; + // message.packet_init = 0x01; + // message.rx_buffer[message.received_bytes] = byte; + // } + // else + // { + // message.version = VERSION_2; + // } + // message.received_bytes++; + // break; + // case 4: if (message.version == VERSION_2) //Instruction vs ID + // { + // message.rx_buffer[message.received_bytes] = byte; + // } + // message.received_bytes++; + // break; + // case 5: if (message.version == VERSION_2) //Pn vs Len_L + // { + // message.rx_buffer[message.received_bytes] = byte; + // message.Len_L = byte; + // } + // message.received_bytes++; + // break; + // case 6: if (message.version == VERSION_2) //Pn vs Len_L + // { + // message.rx_buffer[message.received_bytes] = byte; + // message.Len_H = byte; + // message.length = (message.Len_H << 8) + message.Len_L; + // message.packet_init = 0x01; + // } + // message.received_bytes++; + // break; + // default: break; + // } + // } + // } + // } + // + // if(message.packet_init) + // { + // if (message.version == VERSION_1) + // { + // if (!message.packet_incomplete) + // { + // if (message.Len_L<=4) + // { + // for(uint8_t i=4;i<(message.Len_L+4);i++) + // { + // message.rx_buffer[i]=CAN_rxMessage.Data[i]; + // } + // message.send_packet = 0x01; + // message.packet_incomplete = 0x00; + // } + // else + // { + // for(uint8_t i=4;i<8;i++) + // { + // message.rx_buffer[i]=CAN_rxMessage.Data[i]; + // } + // message.Len_L = message.Len_L-4; + // message.packet_incomplete = 0x01; + // } + // } + // else + // { + // if (message.Len_L<8) + // { + // for(uint8_t i=0;i<message.Len_L;i++) + // { + // message.rx_buffer[i+(message.iterations*8)]=CAN_rxMessage.Data[i]; + // } + // message.send_packet = 0x01; + // } + // else + // { + // for(uint8_t i=0;i<8;i++) + // { + // message.rx_buffer[i+(message.iterations*8)]=CAN_rxMessage.Data[i]; + // } + // message.Len_L = message.Len_L-8; + // } + // message.iterations++; + // } + // } + // else if (message.version == VERSION_2) + // { + // + // } + // } + // + // if (message.send_packet) + // { + // for(unsigned int i=0;i<message.length;i++) + // { + // if(!can_dma_phase) + // comm_do_irq_receive(can_comm_dev,message.rx_buffer[i]); + // else /* do DMA phase */ + // { + // can_dma_phase_data[can_dma_phase_write_ptr]=message.rx_buffer[i]; + // can_dma_phase_length--; + // can_dma_phase_write_ptr++; + // if(can_dma_phase_length==0) + // { + // comm_do_dma_receive(can_comm_dev); + // } + // } + // } + // + // message.Len_L = 0x00; + // message.Len_H = 0x00; + // message.length = 0x00; + // message.packet_init = 0x00; + // message.packet_incomplete = 0x00; + // message.send_packet = 0x00; + // } +} + // 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); + HAL_CAN_IRQHandler(&CANHandle); /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */ /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */ @@ -176,18 +415,97 @@ 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); + HAL_CAN_IRQHandler(&CANHandle); /* USER CODE BEGIN USB_HP_CAN1_TX_IRQn 1 */ /* USER CODE END USB_HP_CAN1_TX_IRQn 1 */ } -void usb_disconnect(void) +unsigned char can_send_irq(unsigned char first_byte) { - HAL_PCD_DevDisconnect(&PCDHandle); + return 0x00; } -void usb_connect(void) +unsigned char can_enable_tx_irq(void) { - HAL_PCD_DevConnect(&PCDHandle); + return 0x00; +} + +unsigned char can_receive_irq(void) +{ + can_dma_phase=0x00; + return 0x00; +} + +unsigned char can_cancel_receive_irq(void) +{ + return 0x00; +} + +/* DMA functions */ +unsigned char can_send_dma(unsigned char *data,unsigned short int length) +{ + if (length <= 8) + { + CANHandle.pTxMsg->DLC = length; + for (uint8_t i=0;i<length;i++) + { + CANHandle.pTxMsg->Data[i] = data[i]; + } + //HAL_CAN_Transmit(&CANHandle, 10); + HAL_CAN_Transmit_IT(&CANHandle); + } + else + { + // unsigned char completed = 0x00; + // unsigned char iterations = 0x00; + // while (!completed) { + // if (length>8) + // { + // CANHandle.pTxMsg->DLC = 8; + // for (uint8_t i=0;i<8;i++) + // { + // CANHandle.pTxMsg->Data[i] = data[i+iterations]; + // } + // iterations = iterations+8; + // HAL_CAN_Transmit(&CANHandle, 10); + // length = length-8; + // } + // else + // { + // CANHandle.pTxMsg->DLC = length; + // for (uint8_t i=0;i<length;i++) + // { + // CANHandle.pTxMsg->Data[i] = data[i+iterations]; + // } + // HAL_CAN_Transmit(&CANHandle, 10); + // completed = 0x01; + // } + // } + } + uint8_t byte; + comm_do_dma_send(can_comm_dev); + comm_do_irq_send(can_comm_dev,&byte); + + return 0x00; +} + +unsigned char can_receive_dma(unsigned char *data,unsigned short int length) +{ + can_dma_phase=0x01; + can_dma_phase_data=data; + can_dma_phase_length=length; + can_dma_phase_write_ptr=0; + + return 0x00; +} + +unsigned char can_cancel_receive_dma(void) +{ + can_dma_phase=0x00; + can_dma_phase_data=0x00; + can_dma_phase_length=0; + can_dma_phase_write_ptr=0; + + return 0x00; }