blob: 2fda8ba61a50426626a039be0d91b89d3784260e [file] [log] [blame]
Christina Quast8be71e42014-12-02 13:06:01 +01001/* ----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support
3 * ----------------------------------------------------------------------------
4 * Copyright (c) 2009, Atmel Corporation
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the disclaimer below.
13 *
14 * Atmel's name may not be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * ----------------------------------------------------------------------------
28 */
29
30/**
31 * \file
32 *
33 * Implements UART console.
34 *
35 */
36
37/*----------------------------------------------------------------------------
38 * Headers
39 *----------------------------------------------------------------------------*/
40
41#include "board.h"
42
43#include <stdio.h>
44#include <stdint.h>
45
46/*----------------------------------------------------------------------------
47 * Definitions
48 *----------------------------------------------------------------------------*/
49
Christina Quast8be71e42014-12-02 13:06:01 +010050/*----------------------------------------------------------------------------
51 * Variables
52 *----------------------------------------------------------------------------*/
53
54/** Is Console Initialized. */
55static uint8_t _ucIsConsoleInitialized=0 ;
56
Christina Quast8be71e42014-12-02 13:06:01 +010057/**
58 * \brief Configures an USART peripheral with the specified parameters.
59 *
60 * \param baudrate Baudrate at which the USART should operate (in Hz).
61 * \param masterClock Frequency of the system master clock (in Hz).
62 */
63extern void UART_Configure( uint32_t baudrate, uint32_t masterClock)
64{
65 const Pin pPins[] = CONSOLE_PINS;
66 Uart *pUart = CONSOLE_USART;
67
68 /* Configure PIO */
69 PIO_Configure(pPins, PIO_LISTSIZE(pPins));
70
71 /* Configure PMC */
72 PMC->PMC_PCER0 = 1 << CONSOLE_ID;
73
74 /* Reset and disable receiver & transmitter */
75 pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
76 | UART_CR_RXDIS | UART_CR_TXDIS;
77
78 /* Configure mode */
79 pUart->UART_MR = UART_MR_PAR_NO;
80
81 /* Configure baudrate */
82 /* Asynchronous, no oversampling */
83 pUart->UART_BRGR = (masterClock / baudrate) / 16;
84
85 /* Disable PDC channel */
86 pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
87
88 /* Enable receiver and transmitter */
89 pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
90
91 _ucIsConsoleInitialized=1 ;
92}
93
94/**
95 * \brief Outputs a character on the UART line.
96 *
97 * \note This function is synchronous (i.e. uses polling).
98 * \param c Character to send.
99 */
100extern void UART_PutChar( uint8_t c )
101{
102 Uart *pUart=CONSOLE_USART ;
103
104 if ( !_ucIsConsoleInitialized )
105 {
106 UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
107 }
108
109 /* Wait for the transmitter to be ready */
110 while ( (pUart->UART_SR & UART_SR_TXEMPTY) == 0 ) ;
111
112 /* Send character */
113 pUart->UART_THR=c ;
114
115}
116
117/**
118 * \brief Input a character from the UART line.
119 *
120 * \note This function is synchronous
121 * \return character received.
122 */
123extern uint32_t UART_GetChar( void )
124{
125 Uart *pUart=CONSOLE_USART ;
126
127 if ( !_ucIsConsoleInitialized )
128 {
129 UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
130 }
131
Harald Welte02d0ec62017-05-20 14:46:29 +0100132 while ( (pUart->UART_SR & UART_SR_RXRDY) == 0 )
133 WDT_Restart(WDT);
Christina Quast8be71e42014-12-02 13:06:01 +0100134
135 return pUart->UART_RHR ;
136}
137
138/**
139 * \brief Check if there is Input from UART line.
140 *
141 * \return true if there is Input.
142 */
143extern uint32_t UART_IsRxReady( void )
144{
145 Uart *pUart=CONSOLE_USART ;
146
147 if ( !_ucIsConsoleInitialized )
148 {
149 UART_Configure( CONSOLE_BAUDRATE, BOARD_MCK ) ;
150 }
151
152 return (pUart->UART_SR & UART_SR_RXRDY) > 0 ;
153}
154
155/**
156 * Displays the content of the given frame on the UART0.
157 *
158 * \param pucFrame Pointer to the frame to dump.
159 * \param dwSize Buffer size in bytes.
160 */
161extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize )
162{
163 uint32_t dw ;
164
165 for ( dw=0 ; dw < dwSize ; dw++ )
166 {
167 printf( "%02X ", pucFrame[dw] ) ;
168 }
169
170 printf( "\n\r" ) ;
171}
172
173/**
174 * Displays the content of the given buffer on the UART0.
175 *
176 * \param pucBuffer Pointer to the buffer to dump.
177 * \param dwSize Buffer size in bytes.
178 * \param dwAddress Start address to display
179 */
180extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress )
181{
182 uint32_t i ;
183 uint32_t j ;
184 uint32_t dwLastLineStart ;
185 uint8_t* pucTmp ;
186
187 for ( i=0 ; i < (dwSize / 16) ; i++ )
188 {
189 printf( "0x%08X: ", (unsigned int)(dwAddress + (i*16)) ) ;
190 pucTmp = (uint8_t*)&pucBuffer[i*16] ;
191
192 for ( j=0 ; j < 4 ; j++ )
193 {
194 printf( "%02X%02X%02X%02X ", pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3] ) ;
195 pucTmp += 4 ;
196 }
197
198 pucTmp=(uint8_t*)&pucBuffer[i*16] ;
199
200 for ( j=0 ; j < 16 ; j++ )
201 {
202 UART_PutChar( *pucTmp++ ) ;
203 }
204
205 printf( "\n\r" ) ;
206 }
207
208 if ( (dwSize%16) != 0 )
209 {
210 dwLastLineStart=dwSize - (dwSize%16) ;
211
212 printf( "0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart) ) ;
213 for ( j=dwLastLineStart ; j < dwLastLineStart+16 ; j++ )
214 {
215 if ( (j!=dwLastLineStart) && (j%4 == 0) )
216 {
217 printf( " " ) ;
218 }
219
220 if ( j < dwSize )
221 {
222 printf( "%02X", pucBuffer[j] ) ;
223 }
224 else
225 {
226 printf(" ") ;
227 }
228 }
229
230 printf( " " ) ;
231 for ( j=dwLastLineStart ; j < dwSize ; j++ )
232 {
233 UART_PutChar( pucBuffer[j] ) ;
234 }
235
236 printf( "\n\r" ) ;
237 }
238}
239
240/**
241 * Reads an integer
242 *
243 * \param pdwValue Pointer to the uint32_t variable to contain the input value.
244 */
245extern uint32_t UART_GetInteger( uint32_t* pdwValue )
246{
247 uint8_t ucKey ;
248 uint8_t ucNbNb=0 ;
249 uint32_t dwValue=0 ;
250
251 while ( 1 )
252 {
253 ucKey=UART_GetChar() ;
254 UART_PutChar( ucKey ) ;
255
256 if ( ucKey >= '0' && ucKey <= '9' )
257 {
258 dwValue = (dwValue * 10) + (ucKey - '0');
259 ucNbNb++ ;
260 }
261 else
262 {
263 if ( ucKey == 0x0D || ucKey == ' ' )
264 {
265 if ( ucNbNb == 0 )
266 {
267 printf( "\n\rWrite a number and press ENTER or SPACE!\n\r" ) ;
268 return 0 ;
269 }
270 else
271 {
272 printf( "\n\r" ) ;
273 *pdwValue=dwValue ;
274
275 return 1 ;
276 }
277 }
278 else
279 {
280 printf( "\n\r'%c' not a number!\n\r", ucKey ) ;
281
282 return 0 ;
283 }
284 }
Harald Welte02d0ec62017-05-20 14:46:29 +0100285 WDT_Restart(WDT);
Christina Quast8be71e42014-12-02 13:06:01 +0100286 }
287}
288
289/**
290 * Reads an integer and check the value
291 *
292 * \param pdwValue Pointer to the uint32_t variable to contain the input value.
293 * \param dwMin Minimum value
294 * \param dwMax Maximum value
295 */
296extern uint32_t UART_GetIntegerMinMax( uint32_t* pdwValue, uint32_t dwMin, uint32_t dwMax )
297{
298 uint32_t dwValue=0 ;
299
300 if ( UART_GetInteger( &dwValue ) == 0 )
301 {
302 return 0 ;
303 }
304
305 if ( dwValue < dwMin || dwValue > dwMax )
306 {
307 printf( "\n\rThe number have to be between %d and %d\n\r", (int)dwMin, (int)dwMax ) ;
308
309 return 0 ;
310 }
311
312 printf( "\n\r" ) ;
313
314 *pdwValue = dwValue ;
315
316 return 1 ;
317}
318
319/**
320 * Reads an hexadecimal number
321 *
322 * \param pdwValue Pointer to the uint32_t variable to contain the input value.
323 */
324extern uint32_t UART_GetHexa32( uint32_t* pdwValue )
325{
326 uint8_t ucKey ;
327 uint32_t dw = 0 ;
328 uint32_t dwValue = 0 ;
329
330 for ( dw=0 ; dw < 8 ; dw++ )
331 {
332 ucKey = UART_GetChar() ;
333 UART_PutChar( ucKey ) ;
334
335 if ( ucKey >= '0' && ucKey <= '9' )
336 {
337 dwValue = (dwValue * 16) + (ucKey - '0') ;
338 }
339 else
340 {
341 if ( ucKey >= 'A' && ucKey <= 'F' )
342 {
343 dwValue = (dwValue * 16) + (ucKey - 'A' + 10) ;
344 }
345 else
346 {
347 if ( ucKey >= 'a' && ucKey <= 'f' )
348 {
349 dwValue = (dwValue * 16) + (ucKey - 'a' + 10) ;
350 }
351 else
352 {
353 printf( "\n\rIt is not a hexa character!\n\r" ) ;
354
355 return 0 ;
356 }
357 }
358 }
359 }
360
361 printf("\n\r" ) ;
362 *pdwValue = dwValue ;
363
364 return 1 ;
365}
366
367#if defined __ICCARM__ /* IAR Ewarm 5.41+ */
368/**
369 * \brief Outputs a character on the UART.
370 *
371 * \param c Character to output.
372 *
373 * \return The character that was output.
374 */
375extern WEAK signed int putchar( signed int c )
376{
377 UART_PutChar( c ) ;
378
379 return c ;
380}
381#endif // defined __ICCARM__
382