Commit 190d65ed authored by smartinezs's avatar smartinezs
Browse files

can library

parent 9fa74025
......@@ -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
......@@ -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;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment