-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcancom.c
155 lines (119 loc) · 4.74 KB
/
cancom.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_can.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/can.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "cancom.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
//***************************MyCANProtocol**********************************
// CAN protocol - Master transmits a SYNC msg all slave nodes receive the msg
// each node replies back with their data to the master
//
// Each node's ID consists of 11 bits the first Most significant three bits
// Indicate the type of sensor. The remaining 8 bits indicate the node number
// |----| |-------------|
// CAN ID 11-bits numbers: 10 9 8 7 6 5 4 3 2 1 0
// |type| |----number---|
//**************************************************************************
// NOTE: the node with the lowest identifier transmits more zeros at the start of the frame,
// and that is the node that wins the arbitration or has the highest priority.
//
// the default SYNC time is set to 1ms
// each node replies back with (Node number)x(100us) from the time of reception of the SYNC
// Msg from the Master node.
//
// Master Msg to be sent
//
static tCANMsgObject txCANMessage;
/*****************************************************************************/
//
// Data structure to be received
//
static tCANMsgObject rxCANMessage;
void CANIntHandler(void);
// Intializes the CAN module for Master node operation which requires:
// Master receives any msg on network
// Master sends a sync msg every 2s
//
void CANCom_Master_Init(void)
{
/*****************************************************************/
// CAN Hardware configuration
/*****************************************************************/
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinConfigure(GPIO_PB4_CAN0RX);
GPIOPinConfigure(GPIO_PB5_CAN0TX);
GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
//
// The GPIO port and pins have been set up for CAN. The CAN peripheral
// must be enabled.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);
//
// Initialize the CAN controller
//
CANInit(CAN0_BASE);
CANBitRateSet( CAN0_BASE, SysCtlClockGet(), 125000 );
//UARTprintf(" Baudrate set = %d\n", CANBitRateSet( CAN0_BASE, SysCtlClockGet(), 125000 ) );
// Register interrupt in the vector table using dynamic addressing
CANIntRegister(CAN0_BASE, CANIntHandler);
CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
IntEnable(INT_CAN0);
CANEnable(CAN0_BASE);
//****************************************************************************
//
// Initialize the sync msg transmitted by this master
// All sensors will receive this msg on the network and reply
// accordingly
//
// sync msg: CAN ID + DATA
// CAN ID = (NODE_TYPE<<8) | (NODE_NR)
// DATA = ( HEARTBEAT )
//
static uint16_t sync_period = HEARTBEAT;
txCANMessage.ui32MsgID = ((NODE_TYPE<<8) | (NODE_NR));
txCANMessage.ui32MsgIDMask = 0;
txCANMessage.pui8MsgData = (uint8_t *)&sync_period;
txCANMessage.ui32MsgLen = 2;
txCANMessage.ui32Flags = 0; //MSG_OBJ_TX_INT_ENABLE;
// Initialize Msg received to zero
static uint16_t dataRx = 0;
// Receive any valid msg on the network by setting the ID and MASK to zeros
rxCANMessage.pui8MsgData = (uint8_t *)&dataRx;
rxCANMessage.ui32MsgID = 0;
rxCANMessage.ui32MsgIDMask = 0;
rxCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
// Receive response in rxCANMessage struct
CANMessageSet(CAN0_BASE, 1, &rxCANMessage, MSG_OBJ_TYPE_RX);
}
//*******************************************************************************
// broadcast a sync msg to be received by all nodes on the network
void TransmitSync(void)
{
CANMessageSet(CAN0_BASE, 2, &txCANMessage, MSG_OBJ_TYPE_TX);
}
//*******************************************************************************
// will receive the data then extract the node_nr, node_type and data info from the
// msg and store it in the passed parameters to be used by the application
void ReceiveData( Node_t * node )
{
taskENTER_CRITICAL();
CANMessageGet(CAN0_BASE, 1, &rxCANMessage, 0);
node->node_nr = (rxCANMessage.ui32MsgID & 0xff); // extact the first 8 bits which correspond to the node id
node->node_type = ((rxCANMessage.ui32MsgID) & (0x700))>>8; // extract the node type from the msg id
node->node_data_size = rxCANMessage.ui32MsgLen;
node->node_data_ptr = rxCANMessage.pui8MsgData;
taskEXIT_CRITICAL();
}
//********************************************************************************