]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libboard_sama5d3x-ek/source/dbg_util.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D3x_Xplained_IAR / AtmelFiles / libboard_sama5d3x-ek / source / dbg_util.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License\r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2011, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 /**\r
31  *  \file\r
32  *  Implement simple DBGU usage as stream receiver.\r
33  */\r
34 \r
35 /*-------------------------------\r
36  *          Headers\r
37  *-------------------------------*/\r
38 \r
39 #include <board.h>\r
40 \r
41 /*-------------------------------\r
42  *          Defines\r
43  *-------------------------------*/\r
44 \r
45 /** Data RX timeout in binary start up */\r
46 #define TIMEOUT_RX_START        (1000*20)\r
47 /** Data RX timeout default value */\r
48 #define TIMEOUT_RX              (200)\r
49 \r
50 /* ASCII Character Codes */\r
51 #define SOH             0x01\r
52 #define STX             0x02\r
53 #define EOT             0x04\r
54 #define CTRL_D          0x04 /**< Transfer Done */\r
55 #define ACK             0x06\r
56 #define NAK             0x15\r
57 #define CAN             0x18 /**< Cancel transfer */\r
58 #define CTRL_X          0x24\r
59 \r
60 /* 1K XMODEM Parameters */\r
61 #define SOH_LENGTH      128\r
62 #define STX_LENGTH      1024\r
63 #define SOH_TIMEOUT     1000\r
64 \r
65 /*-------------------------------\r
66  *          Local functions\r
67  *-------------------------------*/\r
68 \r
69 /**\r
70  * \brief Compute the CRC\r
71  */\r
72 static uint16_t _GetCRC(uint8_t bByte, uint16_t wCrc)\r
73 {\r
74     int32_t cnt;\r
75     uint8_t  newBit;\r
76     for (cnt = 7; cnt >= 0; cnt --)\r
77     {\r
78         newBit = ((wCrc >> 15) & 0x1) ^ ((bByte >> cnt) & 0x1);\r
79         wCrc <<= 1;\r
80         if (newBit) wCrc ^= (0x1021);\r
81     }\r
82     return wCrc;\r
83     \r
84 }\r
85 \r
86 /*-------------------------------\r
87  *          Exported functions\r
88  *-------------------------------*/\r
89 \r
90 /**\r
91  * \brief Receives byte with timeout.\r
92  * \param pByte pointer to locate received byte, can be NULL\r
93  *              to discard data.\r
94  * \param timeOut timeout setting, in number of ticks.\r
95  */\r
96 uint8_t DbgReceiveByte(uint8_t* pByte, uint32_t timeOut)\r
97 {\r
98     uint32_t tick;\r
99     uint32_t delay;\r
100     tick = GetTickCount();\r
101     while(1)\r
102     {\r
103         if (DBGU_IsRxReady())\r
104         {\r
105             uint8_t tmp = DBGU_GetChar();\r
106             if (pByte) *pByte = tmp;\r
107             return 1;\r
108         }\r
109 \r
110         if (timeOut == 0)\r
111         {   /* Never timeout */\r
112         }\r
113         else\r
114         {\r
115             delay = GetDelayInTicks(tick, GetTickCount());\r
116             if (delay > timeOut)\r
117             {\r
118                 return 0;\r
119             }\r
120         }\r
121     }\r
122 }\r
123 \r
124 /**\r
125  * \brief Receives raw binary file through DBGU.\r
126  * \param bStart 1 to start a new data stream.\r
127  * \param address receiving data address\r
128  * \param maxSize max receive data size in bytes\r
129  * \return number of received bytes\r
130  */\r
131 uint32_t DbgReceiveBinary(uint8_t bStart, uint32_t address, uint32_t maxSize)\r
132 {\r
133     volatile uint32_t tick0;\r
134     uint32_t delay;\r
135     uint8_t  *pBuffer = (uint8_t*)address;\r
136     uint8_t  xSign = 0;\r
137     uint32_t rxCnt = 0;\r
138 \r
139     if (maxSize == 0) return 0;\r
140 \r
141     if (bStart)\r
142     {\r
143         printf("\n\r-- Please start binary data in %d seconds:\n\r",\r
144             TIMEOUT_RX_START / 1000);\r
145         tick0 = GetTickCount();\r
146         while(1)\r
147         {\r
148             if (DBGU_IsRxReady())\r
149             {\r
150                 pBuffer[rxCnt ++] = DBGU_GetChar();\r
151                 DBGU_PutChar(' ');\r
152                 break;\r
153             }\r
154             else\r
155             {\r
156                 delay = GetDelayInTicks(tick0, GetTickCount());\r
157                 if ((delay % 1000) == 0)\r
158                 {\r
159                     if (xSign == 0)\r
160                     {\r
161                         DBGU_PutChar('*');\r
162                         xSign = 1;\r
163                     }\r
164                 }\r
165                 else if (xSign)\r
166                 {\r
167                     xSign = 0;\r
168                 }\r
169 \r
170                 if (delay > TIMEOUT_RX_START)\r
171                 {\r
172                     printf("\n\rRX timeout!\n\r");\r
173                     return rxCnt;\r
174                 }\r
175             }\r
176         }\r
177     }\r
178     /* Get data */\r
179     while(1)\r
180     {\r
181         tick0 = GetTickCount();\r
182         while(1)\r
183         {\r
184             if (DBGU_IsRxReady())\r
185             {\r
186                 pBuffer[rxCnt ++] = DBGU_GetChar();\r
187                 if ((rxCnt % (10*1024)) == 0)\r
188                 {\r
189                     DBGU_PutChar('.');\r
190                 }\r
191                 if (rxCnt >= maxSize)\r
192                 {\r
193                     /* Wait until file transfer finished */\r
194                     return rxCnt;\r
195                 }\r
196                 break;\r
197             }\r
198             delay = GetDelayInTicks(tick0, GetTickCount());\r
199             if (delay > TIMEOUT_RX)\r
200             {\r
201                 return rxCnt;\r
202             }\r
203         }\r
204     }\r
205 }\r
206 \r
207 /**\r
208  * \brief Receives raw binary file through DBGU.\r
209  *\r
210  * \note When "CCC..", uses Ctrl + D to exit.\r
211  *\r
212  * \param pktBuffer 1K size packet buffer\r
213  * \param address   receiving data address\r
214  * \param maxSize   max receive data size in bytes\r
215  * \return number of received bytes\r
216  */\r
217 uint32_t DbgReceive1KXModem(uint8_t* pktBuffer,\r
218                             uint32_t address,\r
219                             uint32_t maxSize)\r
220 {\r
221     uint8_t inChar;\r
222     uint32_t i, index = 0, pktLen = 0;\r
223     uint8_t pktNum = 0, prevPktNum = 0;\r
224     uint32_t error = 0;\r
225     uint16_t inCrc, myCrc;\r
226     uint8_t inCheckSum = 0xFF, checkSum = 0;\r
227     uint8_t *pBuffer = (uint8_t*)address;\r
228     uint32_t totalLen = 0;\r
229 \r
230     DBGU_PutChar('C');\r
231     while (1)\r
232     {\r
233         if (!DbgReceiveByte(&inChar, SOH_TIMEOUT))\r
234         {\r
235             DBGU_PutChar('C');\r
236             continue;\r
237         }\r
238         /* Done */\r
239         if (EOT == inChar)\r
240         {\r
241             error = 0;\r
242             DBGU_PutChar(ACK);\r
243             break;\r
244         }\r
245         else if (CAN == inChar)\r
246         {\r
247             error = 2;\r
248         }\r
249         else if (CTRL_X == inChar)\r
250         {\r
251             error = 3;\r
252         }\r
253         else if (SOH == inChar)\r
254         {\r
255             pktLen = SOH_LENGTH;\r
256         }\r
257         else if (STX == inChar)\r
258         {\r
259             pktLen = STX_LENGTH;\r
260         }\r
261         else    continue;\r
262         /* Get Packet Number */\r
263         if (!DbgReceiveByte(&pktNum, SOH_TIMEOUT)) error = 4;\r
264         /* Get 1's complement of packet number */\r
265         if (!DbgReceiveByte(&inChar, SOH_TIMEOUT)) error = 5;\r
266         /* Get 1 packet of information. */\r
267         checkSum = 0; myCrc = 0; index = 0;\r
268         for (i = 0; i < pktLen; i ++)\r
269         {\r
270             if (!DbgReceiveByte(&inChar, SOH_TIMEOUT)) error = 6;\r
271             checkSum += inChar;\r
272             myCrc = _GetCRC(inChar, myCrc);\r
273             if (pktNum != prevPktNum)\r
274             {\r
275                 pktBuffer[index ++] = inChar;\r
276             }\r
277         }\r
278         /* Get CRC bytes */\r
279         if (!DbgReceiveByte(&inCheckSum, SOH_TIMEOUT)) error = 7;\r
280         inCrc  = inCheckSum << 8;\r
281         if (!DbgReceiveByte(&inCheckSum, SOH_TIMEOUT)) error = 7;\r
282         inCrc += inCheckSum;\r
283         /* If CRC error, NAK */\r
284         if (error || (inCrc != myCrc))\r
285         {\r
286             DBGU_PutChar(NAK);\r
287             error = 0;\r
288         }\r
289         /* Save packet, ACK and next */\r
290         else\r
291         {\r
292             prevPktNum = pktNum;\r
293 \r
294             /* Buffer full? */\r
295             if (totalLen + pktLen > maxSize)\r
296             {\r
297                 /* Copy until buffer full? */\r
298                 /* Stop transfer */\r
299                 DBGU_PutChar(CAN);\r
300                 return totalLen;\r
301             }\r
302 \r
303             /* Copy the packet */\r
304             for (i = 0; i < pktLen; i ++)\r
305             {\r
306                 pBuffer[totalLen + i] = pktBuffer[i];\r
307             }\r
308             totalLen += pktLen;\r
309             DBGU_PutChar(ACK);\r
310         }\r
311     }\r
312 \r
313     return totalLen;\r
314 }\r
315 \r