source: rtems/bsps/arm/atsam/contrib/libraries/libboard/source/dbg_console.c @ 54aabb7

5
Last change on this file since 54aabb7 was 54aabb7, checked in by Sebastian Huber <sebastian.huber@…>, on 04/22/18 at 13:11:43

bsp/atsam: Move libraries to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 14.0 KB
Line 
1/* ---------------------------------------------------------------------------- */
2/*                  Atmel Microcontroller Software Support                      */
3/*                       SAM Software Package License                           */
4/* ---------------------------------------------------------------------------- */
5/* Copyright (c) 2015, Atmel Corporation                                        */
6/*                                                                              */
7/* All rights reserved.                                                         */
8/*                                                                              */
9/* Redistribution and use in source and binary forms, with or without           */
10/* modification, are permitted provided that the following condition is met:    */
11/*                                                                              */
12/* - Redistributions of source code must retain the above copyright notice,     */
13/* this list of conditions and the disclaimer below.                            */
14/*                                                                              */
15/* Atmel's name may not be used to endorse or promote products derived from     */
16/* this software without specific prior written permission.                     */
17/*                                                                              */
18/* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
19/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
20/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
21/* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
22/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
23/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
24/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
25/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
26/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
27/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
28/* ---------------------------------------------------------------------------- */
29
30/**
31 * \file
32 *
33 * Implements UART console.
34 *
35 */
36
37/*----------------------------------------------------------------------------
38 *        Headers
39 *----------------------------------------------------------------------------*/
40
41#ifndef __rtems__
42#include "board.h"
43#else /* __rtems__ */
44#include <chip.h>
45#include <include/dbg_console.h>
46#endif /* __rtems__ */
47
48#include <stdio.h>
49#include <stdint.h>
50
51/*----------------------------------------------------------------------------
52 *        Definitions
53 *----------------------------------------------------------------------------*/
54
55/** Console baud rate always using 115200. */
56
57
58#ifndef __rtems__
59#define CONSOLE_BAUDRATE    115200
60
61/** EDBG used USART1 as the console, but LON support on USART1 only */
62#ifndef USART_LON
63        #define CONSOLE_EDBG
64#endif
65
66#if defined CONSOLE_EDBG
67        #define CONSOLE_ON_USART
68#else
69        #define CONSOLE_ON_UART
70#endif
71
72#if defined CONSOLE_ON_UART
73        #if defined SSC_AUDIO || defined USART_LON
74                /** Usart Hw interface used by the console (UART4). */
75                #define CONSOLE_UART       UART4
76
77                /** Pins description corresponding to Rxd,Txd, (UART pins) */
78                #define CONSOLE_PINS        {PINS_UART4}
79
80                #define CONSOLE_ID          ID_UART4
81        #else
82                /** Usart Hw interface used by the console (UART0). */
83                #define CONSOLE_UART       UART0
84
85                /** Pins description corresponding to Rxd,Txd, (UART pins) */
86                #define CONSOLE_PINS        {PINS_UART0}
87
88                #define CONSOLE_ID          ID_UART0
89
90        #endif
91#endif
92
93#if defined CONSOLE_ON_USART
94
95/** USART1 pin RX */
96#define PIN_USART1_RXD_DBG \
97        {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
98/** USART1 pin TX */
99#define PIN_USART1_TXD_DBG \
100        {PIO_PB4D_TXD1, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT}
101#define PINS_USART1        PIN_USART1_TXD_DBG, PIN_USART1_RXD_DBG
102
103/** Usart Hw interface used by the console (Usart0). */
104#define CONSOLE_Usart      USART1
105
106/** Pins description corresponding to Rxd,Txd, (Usart pins) */
107#define CONSOLE_PINS      {PINS_USART1}
108
109#define CONSOLE_ID        ID_USART1
110#endif
111#else /* __rtems__ */
112#define CONSOLE_BAUDRATE ATSAM_CONSOLE_BAUD
113#if ATSAM_CONSOLE_DEVICE_TYPE == 1
114  #define CONSOLE_ON_UART
115  #if ATSAM_CONSOLE_DEVICE_INDEX == 4
116    #define CONSOLE_UART UART4
117    #define CONSOLE_ID ID_UART4
118  #elif ATSAM_CONSOLE_DEVICE_INDEX == 3
119    #define CONSOLE_UART UART3
120    #define CONSOLE_ID ID_UART3
121  #elif ATSAM_CONSOLE_DEVICE_INDEX == 2
122    #define CONSOLE_UART UART2
123    #define CONSOLE_ID ID_UART2
124  #elif ATSAM_CONSOLE_DEVICE_INDEX == 1
125    #define CONSOLE_UART UART1
126    #define CONSOLE_ID ID_UART1
127  #else
128    #define CONSOLE_UART UART0
129    #define CONSOLE_ID ID_UART0
130  #endif
131#else
132  #define CONSOLE_ON_USART
133  #if ATSAM_CONSOLE_DEVICE_INDEX == 4
134    #define CONSOLE_Usart USART4
135    #define CONSOLE_ID ID_USART4
136  #elif ATSAM_CONSOLE_DEVICE_INDEX == 3
137    #define CONSOLE_Usart USART3
138    #define CONSOLE_ID ID_USART3
139  #elif ATSAM_CONSOLE_DEVICE_INDEX == 2
140    #define CONSOLE_Usart USART2
141    #define CONSOLE_ID ID_USART2
142  #elif ATSAM_CONSOLE_DEVICE_INDEX == 1
143    #define CONSOLE_Usart USART1
144    #define CONSOLE_ID ID_USART1
145  #else
146    #define CONSOLE_Usart USART0
147    #define CONSOLE_ID ID_USART0
148  #endif
149#endif
150#endif /* __rtems__ */
151
152
153/*----------------------------------------------------------------------------
154 *        Variables
155 *----------------------------------------------------------------------------*/
156
157#ifndef __rtems__
158/** Is Console Initialized. */
159static uint8_t _ucIsConsoleInitialized = 0;
160#else /* __rtems__ */
161#define _ucIsConsoleInitialized 1
162#endif /* __rtems__ */
163
164/**
165 * \brief Configures an USART peripheral with the specified parameters.
166 *
167 * \param baudrate  Baudrate at which the USART should operate (in Hz).
168 * \param masterClock  Frequency of the system master clock (in Hz).
169 */
170extern void DBG_Configure(uint32_t baudrate, uint32_t masterClock)
171{
172
173#ifndef __rtems__
174        const Pin pPins[] = CONSOLE_PINS;
175#endif /* __rtems__ */
176#if defined CONSOLE_ON_UART
177        Uart *pUart = CONSOLE_UART;
178        /* Configure PIO */
179#ifndef __rtems__
180        PIO_Configure(pPins, PIO_LISTSIZE(pPins));
181#endif /* __rtems__ */
182
183        // Reset & disable receiver and transmitter, disable interrupts
184        pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RSTSTA;
185        pUart->UART_IDR = 0xFFFFFFFF;
186        PMC_EnablePeripheral(CONSOLE_ID);
187        pUart->UART_BRGR = (masterClock / baudrate) / 16;
188        // Configure mode register
189        pUart->UART_MR
190                = (UART_MR_CHMODE_NORMAL | UART_MR_PAR_NO
191                   | UART_MR_BRSRCCK_PERIPH_CLK);
192        // Enable receiver and transmitter
193        pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
194#endif
195
196#if defined CONSOLE_ON_USART
197        Usart *pUsart = CONSOLE_Usart;
198        // Disable the MATRIX registers write protection
199#ifndef __rtems__
200        MATRIX->MATRIX_WPMR  = MATRIX_WPMR_WPKEY_PASSWD;
201        MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4;
202
203        PIO_Configure(pPins, PIO_LISTSIZE(pPins));
204#endif /* __rtems__ */
205
206        // Reset & disable receiver and transmitter, disable interrupts
207        pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA;
208        pUsart->US_IDR = 0xFFFFFFFF;
209        PMC_EnablePeripheral(CONSOLE_ID);
210        pUsart->US_BRGR = (masterClock / baudrate) / 16;
211
212        // Configure mode register
213        pUsart->US_MR
214                = (US_MR_USART_MODE_NORMAL | US_MR_PAR_NO | US_MR_USCLKS_MCK
215                   | US_MR_CHRL_8_BIT);
216
217        // Enable receiver and transmitter
218        pUsart->US_CR = US_CR_RXEN | US_CR_TXEN;
219#endif
220#ifndef __rtems__
221        _ucIsConsoleInitialized = 1;
222
223        /* Disable buffering for printf(). */
224#if (defined (__GNUC__) && !defined (__SAMBA__))
225        setvbuf(stdout, (char *)NULL, _IONBF, 0);
226#endif
227#endif /* __rtems__ */
228}
229
230/**
231 * \brief Outputs a character on the UART line.
232 *
233 * \note This function is synchronous (i.e. uses polling).
234 * \param c  Character to send.
235 */
236extern void DBG_PutChar(uint8_t c)
237{
238#if defined CONSOLE_ON_UART
239        Uart *pUart = CONSOLE_UART;
240
241        if (!_ucIsConsoleInitialized)
242                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
243
244        // Wait for the transmitter to be ready
245        while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
246
247        // Send character
248        pUart->UART_THR = c;
249
250        // Wait for the transfer to complete
251        while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
252
253#endif
254
255#if defined CONSOLE_ON_USART
256        Usart *pUsart = CONSOLE_Usart;
257
258        if (!_ucIsConsoleInitialized)
259                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
260
261        // Wait for the transmitter to be ready
262        while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
263
264        // Send character
265        pUsart->US_THR = c;
266
267        // Wait for the transfer to complete
268        while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
269
270#endif
271}
272
273/**
274 * \brief Input a character from the UART line.
275 *
276 * \note This function is synchronous
277 * \return character received.
278 */
279extern uint32_t DBG_GetChar(void)
280{
281#if defined CONSOLE_ON_UART
282        Uart *pUart = CONSOLE_UART;
283
284        if (!_ucIsConsoleInitialized)
285                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
286
287        while ((pUart->UART_SR & UART_SR_RXRDY) == 0);
288
289        return pUart->UART_RHR;
290#endif
291
292#if defined CONSOLE_ON_USART
293        Usart *pUsart = CONSOLE_Usart;
294
295        if (!_ucIsConsoleInitialized)
296                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
297
298        while ((pUsart->US_CSR & US_CSR_RXRDY) == 0);
299
300        return pUsart->US_RHR;
301#endif
302}
303
304/**
305 * \brief Check if there is Input from UART line.
306 *
307 * \return true if there is Input.
308 */
309extern uint32_t DBG_IsRxReady(void)
310{
311#if defined CONSOLE_ON_UART
312        Uart *pUart = CONSOLE_UART;
313
314        if (!_ucIsConsoleInitialized)
315                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
316
317        return (pUart->UART_SR & UART_SR_RXRDY);
318#endif
319
320#if defined CONSOLE_ON_USART
321        Usart *pUsart = CONSOLE_Usart;
322
323        if (!_ucIsConsoleInitialized)
324                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
325
326        return (pUsart->US_CSR & US_CSR_RXRDY);
327#endif
328}
329
330#ifndef __rtems__
331/**
332 *  Displays the content of the given frame on the UART0.
333 *
334 *  \param pucFrame Pointer to the frame to dump.
335 *  \param dwSize   Buffer size in bytes.
336 */
337extern void DBG_DumpFrame(uint8_t *pucFrame, uint32_t dwSize)
338{
339        uint32_t dw;
340
341        for (dw = 0; dw < dwSize; dw++)
342                printf("%02X ", pucFrame[dw]);
343
344        printf("\n\r");
345}
346
347/**
348 *  Displays the content of the given buffer on the UART0.
349 *
350 *  \param pucBuffer  Pointer to the buffer to dump.
351 *  \param dwSize     Buffer size in bytes.
352 *  \param dwAddress  Start address to display
353 */
354extern void DBG_DumpMemory(uint8_t *pucBuffer, uint32_t dwSize,
355                                                        uint32_t dwAddress)
356{
357        uint32_t i;
358        uint32_t j;
359        uint32_t dwLastLineStart;
360        uint8_t *pucTmp;
361
362        for (i = 0; i < (dwSize / 16); i++) {
363                printf("0x%08X: ", (unsigned int)(dwAddress + (i * 16)));
364                pucTmp = (uint8_t *)&pucBuffer[i * 16];
365
366                for (j = 0; j < 4; j++) {
367                        printf("%02X%02X%02X%02X ",
368                                        pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3]);
369                        pucTmp += 4;
370                }
371
372                pucTmp = (uint8_t *)&pucBuffer[i * 16];
373
374                for (j = 0; j < 16; j++)
375                        DBG_PutChar(*pucTmp++);
376
377                printf("\n\r");
378        }
379
380        if ((dwSize % 16) != 0) {
381                dwLastLineStart = dwSize - (dwSize % 16);
382
383                printf("0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart));
384
385                for (j = dwLastLineStart; j < dwLastLineStart + 16; j++) {
386                        if ((j != dwLastLineStart) && (j % 4 == 0))
387                                printf(" ");
388
389                        if (j < dwSize)
390                                printf("%02X", pucBuffer[j]);
391                        else
392                                printf("  ");
393                }
394
395                printf(" ");
396
397                for (j = dwLastLineStart; j < dwSize; j++)
398                        DBG_PutChar(pucBuffer[j]);
399
400                printf("\n\r");
401        }
402}
403
404/**
405 * Reads an integer
406 *
407 * \param pdwValue  Pointer to a integer variable to contain the input value.
408 *
409 * \return success(1) or failure(0)
410 */
411extern uint32_t DBG_GetInteger(int32_t *pdwValue)
412{
413        uint8_t ucKey;
414        uint8_t ucNum = 0;
415        int32_t dwValue = 0;
416        int32_t sign = 1;
417
418        while (1) {
419                ucKey = DBG_GetChar();
420                DBG_PutChar(ucKey);
421
422                if (((ucKey == '-') || (ucKey == '+')) && (ucNum == 0)) {
423                        if (ucKey == '-')
424                                sign = -1;
425                        else
426                                sign = 1;
427
428                        ucNum++;
429                } else {
430                        if (ucKey >= '0' && ucKey <= '9') {
431                                dwValue = (dwValue * 10) + (ucKey - '0');
432                                ucNum++;
433                        } else {
434                                if (ucKey == 0x0D || ucKey == ' ') {
435                                        if (ucNum == 0) {
436                                                printf("\n\rWrite a number and press ENTER or SPACE!\n\r");
437                                                return 0;
438                                        } else {
439                                                printf("\n\r");
440                                                *pdwValue = dwValue * sign;
441
442                                                return 1;
443                                        }
444                                } else {
445                                        printf("\n\r'%c' not a number or sign(+/-)!\n\r", ucKey);
446                                        return 0;
447                                }
448                        }
449                }
450        }
451}
452
453/**
454 * Reads an integer and check the value
455 *
456 * \param pdwValue  Pointer to a integer variable to contain the input value.
457 * \param dwMin     Minimum value
458 * \param dwMax     Maximum value
459 *
460 * \return success(1) or failure(0)
461 */
462extern uint32_t DBG_GetIntegerMinMax(int32_t *pdwValue, int32_t dwMin,
463                                                                         int32_t dwMax)
464{
465        int32_t dwValue = 0;
466
467        if (DBG_GetInteger(&dwValue) == 0)
468                return 0;
469
470        if (dwValue < dwMin || dwValue > dwMax) {
471                printf("\n\rThe number have to be between %d and %d\n\r",
472                                (int)dwMin, (int)dwMax);
473
474                return 0;
475        }
476
477        printf("\n\r");
478
479        *pdwValue = dwValue;
480
481        return 1;
482}
483
484/**
485 *  Reads an hexadecimal number
486 *
487 *  \param pdwValue  Pointer to the uint32_t variable to contain the input value.
488 */
489extern uint32_t DBG_GetHexa32(uint32_t *pdwValue)
490{
491        uint8_t ucKey;
492        uint32_t dw = 0;
493        uint32_t dwValue = 0;
494
495        for (dw = 0; dw < 8; dw++) {
496                ucKey = DBG_GetChar();
497                DBG_PutChar(ucKey);
498
499                if (ucKey >= '0' &&  ucKey <= '9')
500                        dwValue = (dwValue * 16) + (ucKey - '0');
501                else {
502                        if (ucKey >= 'A' &&  ucKey <= 'F')
503                                dwValue = (dwValue * 16) + (ucKey - 'A' + 10);
504                        else {
505                                if (ucKey >= 'a' &&  ucKey <= 'f')
506                                        dwValue = (dwValue * 16) + (ucKey - 'a' + 10);
507                                else {
508                                        printf("\n\rIt is not a hexadecimal character!\n\r");
509
510                                        return 0;
511                                }
512                        }
513                }
514        }
515
516        printf("\n\r");
517        *pdwValue = dwValue;
518
519        return 1;
520}
521
522#if defined __ICCARM__ /* IAR Ewarm 5.41+ */
523/**
524 * \brief Outputs a character on the UART.
525 *
526 * \param c  Character to output.
527 *
528 * \return The character that was output.
529 */
530extern WEAK signed int putchar(signed int c)
531{
532        DBG_PutChar(c);
533
534        return c;
535}
536
537#endif  // defined __ICCARM__
538extern WEAK int puts(const char *ptr)
539{
540
541        for (; *ptr != 0; ptr++)
542                DBG_PutChar(*ptr);
543
544        return 0;
545
546}
547
548extern WEAK char *gets(char *ptr)
549{
550        uint8_t ch = 0;
551
552        while (ch != '\r') {
553                ch = DBG_GetChar();
554                DBG_PutChar(ch);
555                *(ptr++) = ch;
556        }
557
558        *ptr = '\0';
559        return 0;
560
561}
562
563
564#endif /* __rtems__ */
Note: See TracBrowser for help on using the repository browser.