1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2011, Atmel Corporation
\r
6 * All rights reserved.
\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
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\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
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
32 * Implement simple DBGU usage as stream receiver.
\r
35 /*-------------------------------
\r
37 *-------------------------------*/
\r
41 /*-------------------------------
\r
43 *-------------------------------*/
\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
50 /* ASCII Character Codes */
\r
54 #define CTRL_D 0x04 /**< Transfer Done */
\r
57 #define CAN 0x18 /**< Cancel transfer */
\r
60 /* 1K XMODEM Parameters */
\r
61 #define SOH_LENGTH 128
\r
62 #define STX_LENGTH 1024
\r
63 #define SOH_TIMEOUT 1000
\r
65 /*-------------------------------
\r
67 *-------------------------------*/
\r
70 * \brief Compute the CRC
\r
72 static uint16_t _GetCRC(uint8_t bByte, uint16_t wCrc)
\r
76 for (cnt = 7; cnt >= 0; cnt --)
\r
78 newBit = ((wCrc >> 15) & 0x1) ^ ((bByte >> cnt) & 0x1);
\r
80 if (newBit) wCrc ^= (0x1021);
\r
86 /*-------------------------------
\r
87 * Exported functions
\r
88 *-------------------------------*/
\r
91 * \brief Receives byte with timeout.
\r
92 * \param pByte pointer to locate received byte, can be NULL
\r
94 * \param timeOut timeout setting, in number of ticks.
\r
96 uint8_t DbgReceiveByte(uint8_t* pByte, uint32_t timeOut)
\r
100 tick = GetTickCount();
\r
103 if (DBGU_IsRxReady())
\r
105 uint8_t tmp = DBGU_GetChar();
\r
106 if (pByte) *pByte = tmp;
\r
111 { /* Never timeout */
\r
115 delay = GetDelayInTicks(tick, GetTickCount());
\r
116 if (delay > timeOut)
\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
131 uint32_t DbgReceiveBinary(uint8_t bStart, uint32_t address, uint32_t maxSize)
\r
133 volatile uint32_t tick0;
\r
135 uint8_t *pBuffer = (uint8_t*)address;
\r
137 uint32_t rxCnt = 0;
\r
139 if (maxSize == 0) return 0;
\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
148 if (DBGU_IsRxReady())
\r
150 pBuffer[rxCnt ++] = DBGU_GetChar();
\r
156 delay = GetDelayInTicks(tick0, GetTickCount());
\r
157 if ((delay % 1000) == 0)
\r
170 if (delay > TIMEOUT_RX_START)
\r
172 printf("\n\rRX timeout!\n\r");
\r
181 tick0 = GetTickCount();
\r
184 if (DBGU_IsRxReady())
\r
186 pBuffer[rxCnt ++] = DBGU_GetChar();
\r
187 if ((rxCnt % (10*1024)) == 0)
\r
191 if (rxCnt >= maxSize)
\r
193 /* Wait until file transfer finished */
\r
198 delay = GetDelayInTicks(tick0, GetTickCount());
\r
199 if (delay > TIMEOUT_RX)
\r
208 * \brief Receives raw binary file through DBGU.
\r
210 * \note When "CCC..", uses Ctrl + D to exit.
\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
217 uint32_t DbgReceive1KXModem(uint8_t* pktBuffer,
\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
233 if (!DbgReceiveByte(&inChar, SOH_TIMEOUT))
\r
245 else if (CAN == inChar)
\r
249 else if (CTRL_X == inChar)
\r
253 else if (SOH == inChar)
\r
255 pktLen = SOH_LENGTH;
\r
257 else if (STX == inChar)
\r
259 pktLen = STX_LENGTH;
\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
270 if (!DbgReceiveByte(&inChar, SOH_TIMEOUT)) error = 6;
\r
271 checkSum += inChar;
\r
272 myCrc = _GetCRC(inChar, myCrc);
\r
273 if (pktNum != prevPktNum)
\r
275 pktBuffer[index ++] = inChar;
\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
289 /* Save packet, ACK and next */
\r
292 prevPktNum = pktNum;
\r
295 if (totalLen + pktLen > maxSize)
\r
297 /* Copy until buffer full? */
\r
298 /* Stop transfer */
\r
303 /* Copy the packet */
\r
304 for (i = 0; i < pktLen; i ++)
\r
306 pBuffer[totalLen + i] = pktBuffer[i];
\r
308 totalLen += pktLen;
\r