Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
humanoides
tools
stm32_libraries
Commits
190d65ed
Commit
190d65ed
authored
Dec 24, 2020
by
smartinezs
Browse files
can library
parent
9fa74025
Changes
2
Hide whitespace changes
Inline
Side-by-side
f1/can/include/can.h
View file @
190d65ed
...
...
@@ -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_Filter
Conf
TypeDef
*
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
f1/can/src/can.c
View file @
190d65ed
...
...
@@ -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
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_13TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
case
CAN_20KBPS
:
CANHandle
.
Init
.
Prescaler
=
100
;
CANHandle
.
Init
.
TimeSeg1
=
15
;
CANHandle
.
Init
.
TimeSeg2
=
2
;
CANHandle
.
Init
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_15TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
case
CAN_50KBPS
:
CANHandle
.
Init
.
Prescaler
=
45
;
CANHandle
.
Init
.
TimeSeg1
=
13
;
CANHandle
.
Init
.
TimeSeg2
=
2
;
CANHandle
.
Init
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_13TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
case
CAN_83K3BPS
:
CANHandle
.
Init
.
Prescaler
=
27
;
CANHandle
.
Init
.
TimeSeg1
=
13
;
CANHandle
.
Init
.
TimeSeg2
=
2
;
CANHandle
.
Init
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_13TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
case
CAN_100KBPS
:
CANHandle
.
Init
.
Prescaler
=
20
;
CANHandle
.
Init
.
TimeSeg1
=
15
;
CANHandle
.
Init
.
TimeSeg2
=
2
;
CANHandle
.
Init
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_15TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
case
CAN_125KBPS
:
CANHandle
.
Init
.
Prescaler
=
18
;
CANHandle
.
Init
.
TimeSeg1
=
13
;
CANHandle
.
Init
.
TimeSeg2
=
2
;
CANHandle
.
Init
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_13TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
case
CAN_250KBPS
:
CANHandle
.
Init
.
Prescaler
=
9
;
CANHandle
.
Init
.
TimeSeg1
=
13
;
CANHandle
.
Init
.
TimeSeg2
=
2
;
CANHandle
.
Init
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_13TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
case
CAN_500KBPS
:
CANHandle
.
Init
.
Prescaler
=
4
;
CANHandle
.
Init
.
TimeSeg1
=
15
;
CANHandle
.
Init
.
TimeSeg2
=
2
;
CANHandle
.
Init
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_15TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
case
CAN_1000KBPS
:
CANHandle
.
Init
.
Prescaler
=
2
;
CANHandle
.
Init
.
TimeSeg1
=
15
;
CANHandle
.
Init
.
TimeSeg2
=
2
;
CANHandle
.
Init
.
S
yncJumpWidth
=
1
;
CANHandle
.
Init
.
BS1
=
CAN_BS1_15TQ
;
CANHandle
.
Init
.
BS2
=
CAN_BS2_2TQ
;
CANHandle
.
Init
.
S
JW
=
CAN_SJW_1TQ
;
break
;
}
}
void
can_set_filter
(
TComm
*
comm_dev
,
CAN_FilterTypeDef
*
filter
)
void
can_set_filter
(
TComm
*
comm_dev
,
CAN_Filter
Conf
TypeDef
*
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
(
&
PCD
Handle
);
HAL_
CAN
_IRQHandler
(
&
CAN
Handle
);
/* 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
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment