| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ccan_18xx_43xx.c
Go to the documentation of this file.
1 /*
2 * @brief LPC18xx/43xx CCAN driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include "chip.h"
33
34 /*****************************************************************************
35 * Private types/enumerations/variables
36 ****************************************************************************/
37
38 #define MAX_OBJECT 32
39 #define CHIP_CCAN_DETERMINECLK(n) (((n) == LPC_C_CAN0) ? CLK_APB3_CAN0 : CLK_APB1_CAN1)
40
41 /*****************************************************************************
42 * Public types/enumerations/variables
43 ****************************************************************************/
44
45 /*****************************************************************************
46 * Private functions
47 ****************************************************************************/
48
49 /* Return 1->32; 0 if not find free msg */
50 static uint8_t getFreeMsgObject(LPC_CCAN_T *pCCAN)
51 {
52 uint32_t msg_valid;
53 uint8_t i;
54 msg_valid = IP_CCAN_GetValidMsg(pCCAN);
55 for (i = 0; i < MAX_OBJECT; i++) {
56 if (!((msg_valid >> i) & 1UL)) {
57 return i + 1;
58 }
59 }
60 return 0; // No free object
61 }
62
63 static void Free_msg_object(LPC_CCAN_T *pCCAN, uint8_t msg_num)
64 {
65 IP_CCAN_SetValidMsg(pCCAN, IF1, msg_num, DISABLE);
66 }
67
68 /*****************************************************************************
69 * Public functions
70 ****************************************************************************/
71
72 /* Select bit rate for CCAN bus */
73 void Chip_CCAN_SetBitRate(LPC_CCAN_T *pCCAN, uint32_t bitRate)
74 {
75 uint32_t pClk, clk_div = 1, div, quanta, segs, seg1, seg2, clk_per_bit, can_sjw;
76 pClk = Chip_Clock_GetRate(CHIP_CCAN_DETERMINECLK(pCCAN));
77 clk_per_bit = pClk / bitRate;
78
79 for (div = 0; div <= 15; div++) {
80 if (div) {
81 clk_div = (1 << (div - 1)) + 1;
82 }
83 for (quanta = 1; quanta <= 32; quanta++) {
84 for (segs = 3; segs <= 17; segs++) {
85 if (clk_per_bit == (segs * quanta * clk_div)) {
86 segs -= 3;
87 seg1 = segs / 2;
88 seg2 = segs - seg1;
89 can_sjw = seg1 > 3 ? 3 : seg1;
90 IP_CCAN_TimingCfg(pCCAN, div, quanta - 1, can_sjw, seg1, seg2);
91 return;
92 }
93 }
94 }
95 }
96 while (1) { // Can not find a correct value with input bitrate
97 }
98 }
99
100 /* Send a message */
101 void Chip_CCAN_Send(LPC_CCAN_T *pCCAN, uint32_t RemoteEnable, message_object *msg_ptr)
102 {
103 uint8_t msg_num_send = getFreeMsgObject(pCCAN);
104 if (!msg_num_send) {
105 return;
106 }
107 IP_CCAN_SetMsgObject(pCCAN, IF1, CCAN_TX_DIR, RemoteEnable, msg_num_send, msg_ptr);
108 while (IP_CCAN_GetTxRQST(pCCAN) >> (msg_num_send - 1)) { // blocking , wait for sending completed
109 }
110 if (!RemoteEnable) {
111 Free_msg_object(pCCAN, msg_num_send);
112 }
113 }
114
115 /* Initialize the CCAN peripheral, free all message object in RAM */
116 void Chip_CCAN_Init(LPC_CCAN_T *pCCAN)
117 {
118 uint8_t i;
119 uint32_t can_stat;
120
121 Chip_Clock_EnableOpts(CHIP_CCAN_DETERMINECLK(pCCAN), true, false, 1);
122 can_stat = IP_CCAN_GetStatus(pCCAN);
123 for (i = 1; i <= MAX_OBJECT; i++) {
124 Free_msg_object(pCCAN, i);
125 }
126 IP_CCAN_SetStatus(pCCAN, can_stat & (~(CCAN_STAT_RXOK | CCAN_STAT_TXOK)));
127 }
128
129 /* De-initialize the CCAN peripheral */
130 void Chip_CCAN_DeInit(LPC_CCAN_T *pCCAN)
131 {
132 // FIXME is any specific CAN shutdown code needed here?
133 Chip_Clock_Disable(CHIP_CCAN_DETERMINECLK(pCCAN));
134 }
135
136 /* Register a message ID for receiving */
137 void Chip_CCAN_AddReceiveID(LPC_CCAN_T *pCCAN, uint32_t rev_id)
138 {
139 message_object temp;
140 uint8_t msg_num_rev = getFreeMsgObject(pCCAN);
141 if (!msg_num_rev) {
142 return;
143 }
144 temp.id = rev_id;
145 IP_CCAN_SetMsgObject(pCCAN, IF2, CCAN_RX_DIR, 0, msg_num_rev, &temp);
146 }
147
148 /* Remove a registered message ID from receiving */
149 void Chip_CCAN_DeleteReceiveID(LPC_CCAN_T *pCCAN, uint32_t rev_id)
150 {
151 uint8_t i;
152 message_object temp;
153 for (i = 1; i <= MAX_OBJECT; i++) {
154 IP_CCAN_GetMsgObject(pCCAN, IF1, i, &temp);
155 if (temp.id == rev_id) {
156 Free_msg_object(pCCAN, i);
157 }
158 }
159 }
160
161 /* Clear the pending interrupt */
162 void Chip_CCAN_ClearIntPend(LPC_CCAN_T *pCCAN, uint8_t msg_num, uint8_t TRxMode)
163 {
164 uint32_t can_stat = IP_CCAN_GetStatus(pCCAN);
165 if (TRxMode == CCAN_TX_DIR) {
166 IP_CCAN_SetStatus(pCCAN, can_stat & (~CCAN_STAT_TXOK));
167 }
168 else {
169 IP_CCAN_SetStatus(pCCAN, can_stat & (~CCAN_STAT_RXOK));
170 }
171 IP_CCAN_ClearIntPend(pCCAN, IF1, msg_num);
172
173 }
174
175 /* Clear the status of CCAN bus */
176 void Chip_CCAN_ClearStatus(LPC_CCAN_T *pCCAN, IP_CCAN_STATUS_T status)
177 {
178 uint32_t tmp = IP_CCAN_GetStatus(pCCAN);
179 IP_CCAN_SetStatus(pCCAN, tmp & (~status));
180 }