1 | // Structs
|
2 | CanTxMsg CanTxMessage;
|
3 | CanRxMsg CanRxMessage;
|
4 |
|
5 | char std_id_buffer[5] = {'\0'};
|
6 |
|
7 | /**
|
8 | * @brief This function inits CAN 1 for operation in normal mode.
|
9 | * @param none
|
10 | * @return none
|
11 | */
|
12 | void init_can()
|
13 | {
|
14 | // --------------------------
|
15 | // GPIO for CAN configuration
|
16 | // --------------------------
|
17 | GPIO_InitTypeDef GPIO_InitStructure;
|
18 | // Set clock signal for GPIOs
|
19 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
|
20 |
|
21 | // Map alternate function of CAN1 to specific pins:
|
22 | // PD0 for CAN1_RX, PD1 for CAN1_TX
|
23 | GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
|
24 | GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
|
25 |
|
26 | // Init the GPIOs
|
27 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
28 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
29 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
|
30 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
31 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
32 | GPIO_Init(GPIOD, &GPIO_InitStructure);
|
33 |
|
34 | // -------------------
|
35 | // CAN 1 configuration
|
36 | // -------------------
|
37 | CAN_InitTypeDef CAN_InitStructure;
|
38 | // Set clock signal for CAN1
|
39 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
40 |
|
41 | // Init the CAN module
|
42 | CAN_DeInit(CAN1);
|
43 | CAN_InitStructure.CAN_ABOM = DISABLE;
|
44 | CAN_InitStructure.CAN_AWUM = DISABLE;
|
45 | CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
|
46 | CAN_InitStructure.CAN_NART = DISABLE;
|
47 | CAN_InitStructure.CAN_RFLM = DISABLE;
|
48 | CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;
|
49 | CAN_InitStructure.CAN_TTCM = DISABLE;
|
50 | CAN_InitStructure.CAN_TXFP = DISABLE;
|
51 |
|
52 | // // CAN Baudrate = 125 kBps (CAN clocked at 42 MHz)
|
53 | // // CAN Baudrate = APB1 / (BRP * (1 + BS1 + BS2))
|
54 | // // = 42 MHz / (16 * (1 + 14 + 6))
|
55 | // // = 125 kBit/s
|
56 | // // Sample point: 15/21 =(approx)= 71 %
|
57 | // CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;
|
58 | // CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq;
|
59 | // CAN_InitStructure.CAN_Prescaler = 16;
|
60 | // CAN_Init(CAN1, &CAN_InitStructure);
|
61 |
|
62 |
|
63 | // CAN Baudrate = 100 kBps (CAN clocked at 42 MHz)
|
64 | // CAN Baudrate = APB1 / (BRP * (1 + BS1 + BS2))
|
65 | // = 42 MHz / (20 * (1 + 14 + 6))
|
66 | // = 100 kBit/s
|
67 | // Sample point: 15/21 =(approx)= 71 %
|
68 | CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;
|
69 | CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq;
|
70 | CAN_InitStructure.CAN_Prescaler = 20;
|
71 | CAN_Init(CAN1, &CAN_InitStructure);
|
72 |
|
73 | // Init the CAN filter
|
74 | CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
75 | CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
76 | CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
|
77 | CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
|
78 | CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
|
79 | CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
|
80 | CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
|
81 | CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
82 | CAN_FilterInitStructure.CAN_FilterNumber = 0;
|
83 | CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
84 | CAN_FilterInit(&CAN_FilterInitStructure);
|
85 |
|
86 | // Init interrupts
|
87 | NVIC_InitTypeDef NVIC_InitStructure;
|
88 | NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
|
89 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
90 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
|
91 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
|
92 | NVIC_Init(&NVIC_InitStructure);
|
93 |
|
94 | // Enable "FIFO 0 message pending" interrupt
|
95 | CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
|
96 | }
|
97 |
|
98 | /**
|
99 | * @brief This function sends a dummy message on CAN 1.
|
100 | * @param none
|
101 | * @return none
|
102 | */
|
103 | void send_can_dummy()
|
104 | {
|
105 | // Init CanTxMessage
|
106 | clear_CanTxMessage();
|
107 | clear_CanRxMessage();
|
108 |
|
109 | CanTxMessage.StdId = 0x00F; // 0...0x7FF
|
110 | CanTxMessage.RTR = CAN_RTR_DATA;
|
111 | CanTxMessage.IDE = CAN_ID_STD;
|
112 | CanTxMessage.DLC = 8;
|
113 |
|
114 | CanTxMessage.Data[0] = 'H';
|
115 | CanTxMessage.Data[1] = 'i';
|
116 | CanTxMessage.Data[2] = ' ';
|
117 | CanTxMessage.Data[3] = 'C';
|
118 | CanTxMessage.Data[4] = 'A';
|
119 | CanTxMessage.Data[5] = 'N';
|
120 | CanTxMessage.Data[6] = '1';
|
121 | CanTxMessage.Data[7] = '\0';
|
122 |
|
123 | CAN_Transmit(CAN1, &CanTxMessage);
|
124 | }
|
125 |
|
126 | /**
|
127 | * @brief This is the IRQ-handler for message reception on CAN1
|
128 | * @param none
|
129 | * @return none
|
130 | */
|
131 | void CAN1_RX0_IRQHandler()
|
132 | {
|
133 | // Check CAN1_Rx status
|
134 | if( CAN_GetITStatus(CAN1, CAN_IT_FMP0))
|
135 | {
|
136 | // Send data to PC
|
137 | trigger_uart_PC_send((char*)CanRxMessage.Data);
|
138 |
|
139 | // Clear CAN buffer
|
140 | clear_CanRxMessage();
|
141 | }
|
142 | }
|
143 |
|
144 | /**
|
145 | * @brief This function clears the CanTxMessage struct.
|
146 | * @param none
|
147 | * @return none
|
148 | */
|
149 | void clear_CanRxMessage()
|
150 | {
|
151 | unsigned char i;
|
152 | CanRxMessage.StdId = 0x000;
|
153 | CanRxMessage.ExtId = 0;
|
154 | CanRxMessage.RTR = CAN_RTR_DATA;
|
155 | CanRxMessage.IDE = CAN_ID_STD;
|
156 | CanRxMessage.DLC = 0;
|
157 | CanRxMessage.FMI = 0;
|
158 |
|
159 | for(i=0; i < 8; i++)
|
160 | {
|
161 | CanRxMessage.Data[i] = 0;
|
162 | }
|
163 | }
|