source: rtems/c/src/lib/libbsp/arm/atsam/libraries/libboard/source/dbg_console.c @ e1eeb883

5
Last change on this file since e1eeb883 was e1eeb883, checked in by Sebastian Huber <sebastian.huber@…>, on Jan 12, 2016 at 2:34:31 PM

bsp/atsam: Import SAM Software Package

Import selected files of the "SAM V71 / V70 / E70 / S70 Software
Package" obtained from the "SAMV71-XULT GNU Software Package 1.5".

Converted files via dos2unix before import.

Update #2529.

  • Property mode set to 100644
File size: 12.4 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#include "board.h"
42
43#include <stdio.h>
44#include <stdint.h>
45
46/*----------------------------------------------------------------------------
47 *        Definitions
48 *----------------------------------------------------------------------------*/
49
50/** Console baud rate always using 115200. */
51
52
53#define CONSOLE_BAUDRATE    115200
54
55/** EDBG used USART1 as the console, but LON support on USART1 only */
56#ifndef USART_LON
57        #define CONSOLE_EDBG
58#endif
59
60#if defined CONSOLE_EDBG
61        #define CONSOLE_ON_USART
62#else
63        #define CONSOLE_ON_UART
64#endif
65
66#if defined CONSOLE_ON_UART
67        #if defined SSC_AUDIO || defined USART_LON
68                /** Usart Hw interface used by the console (UART4). */
69                #define CONSOLE_UART       UART4
70
71                /** Pins description corresponding to Rxd,Txd, (UART pins) */
72                #define CONSOLE_PINS        {PINS_UART4}
73
74                #define CONSOLE_ID          ID_UART4
75        #else
76                /** Usart Hw interface used by the console (UART0). */
77                #define CONSOLE_UART       UART0
78
79                /** Pins description corresponding to Rxd,Txd, (UART pins) */
80                #define CONSOLE_PINS        {PINS_UART0}
81
82                #define CONSOLE_ID          ID_UART0
83
84        #endif
85#endif
86
87#if defined CONSOLE_ON_USART
88
89/** USART1 pin RX */
90#define PIN_USART1_RXD_DBG \
91        {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
92/** USART1 pin TX */
93#define PIN_USART1_TXD_DBG \
94        {PIO_PB4D_TXD1, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT}
95#define PINS_USART1        PIN_USART1_TXD_DBG, PIN_USART1_RXD_DBG
96
97/** Usart Hw interface used by the console (Usart0). */
98#define CONSOLE_Usart      USART1
99
100/** Pins description corresponding to Rxd,Txd, (Usart pins) */
101#define CONSOLE_PINS      {PINS_USART1}
102
103#define CONSOLE_ID        ID_USART1
104#endif
105
106
107/*----------------------------------------------------------------------------
108 *        Variables
109 *----------------------------------------------------------------------------*/
110
111/** Is Console Initialized. */
112static uint8_t _ucIsConsoleInitialized = 0;
113
114/**
115 * \brief Configures an USART peripheral with the specified parameters.
116 *
117 * \param baudrate  Baudrate at which the USART should operate (in Hz).
118 * \param masterClock  Frequency of the system master clock (in Hz).
119 */
120extern void DBG_Configure(uint32_t baudrate, uint32_t masterClock)
121{
122
123        const Pin pPins[] = CONSOLE_PINS;
124#if defined CONSOLE_ON_UART
125        Uart *pUart = CONSOLE_UART;
126        /* Configure PIO */
127        PIO_Configure(pPins, PIO_LISTSIZE(pPins));
128
129        // Reset & disable receiver and transmitter, disable interrupts
130        pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RSTSTA;
131        pUart->UART_IDR = 0xFFFFFFFF;
132        PMC_EnablePeripheral(CONSOLE_ID);
133        pUart->UART_BRGR = (masterClock / baudrate) / 16;
134        // Configure mode register
135        pUart->UART_MR
136                = (UART_MR_CHMODE_NORMAL | UART_MR_PAR_NO
137                   | UART_MR_BRSRCCK_PERIPH_CLK);
138        // Enable receiver and transmitter
139        pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
140#endif
141
142#if defined CONSOLE_ON_USART
143        Usart *pUsart = CONSOLE_Usart;
144        // Disable the MATRIX registers write protection
145        MATRIX->MATRIX_WPMR  = MATRIX_WPMR_WPKEY_PASSWD;
146        MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4;
147
148        PIO_Configure(pPins, PIO_LISTSIZE(pPins));
149
150        // Reset & disable receiver and transmitter, disable interrupts
151        pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA;
152        pUsart->US_IDR = 0xFFFFFFFF;
153        PMC_EnablePeripheral(CONSOLE_ID);
154        pUsart->US_BRGR = (masterClock / baudrate) / 16;
155
156        // Configure mode register
157        pUsart->US_MR
158                = (US_MR_USART_MODE_NORMAL | US_MR_PAR_NO | US_MR_USCLKS_MCK
159                   | US_MR_CHRL_8_BIT);
160
161        // Enable receiver and transmitter
162        pUsart->US_CR = US_CR_RXEN | US_CR_TXEN;
163#endif
164        _ucIsConsoleInitialized = 1;
165
166        /* Disable buffering for printf(). */
167#if (defined (__GNUC__) && !defined (__SAMBA__))
168        setvbuf(stdout, (char *)NULL, _IONBF, 0);
169#endif
170}
171
172/**
173 * \brief Outputs a character on the UART line.
174 *
175 * \note This function is synchronous (i.e. uses polling).
176 * \param c  Character to send.
177 */
178extern void DBG_PutChar(uint8_t c)
179{
180#if defined CONSOLE_ON_UART
181        Uart *pUart = CONSOLE_UART;
182
183        if (!_ucIsConsoleInitialized)
184                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
185
186        // Wait for the transmitter to be ready
187        while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
188
189        // Send character
190        pUart->UART_THR = c;
191
192        // Wait for the transfer to complete
193        while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
194
195#endif
196
197#if defined CONSOLE_ON_USART
198        Usart *pUsart = CONSOLE_Usart;
199
200        if (!_ucIsConsoleInitialized)
201                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
202
203        // Wait for the transmitter to be ready
204        while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
205
206        // Send character
207        pUsart->US_THR = c;
208
209        // Wait for the transfer to complete
210        while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
211
212#endif
213}
214
215/**
216 * \brief Input a character from the UART line.
217 *
218 * \note This function is synchronous
219 * \return character received.
220 */
221extern uint32_t DBG_GetChar(void)
222{
223#if defined CONSOLE_ON_UART
224        Uart *pUart = CONSOLE_UART;
225
226        if (!_ucIsConsoleInitialized)
227                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
228
229        while ((pUart->UART_SR & UART_SR_RXRDY) == 0);
230
231        return pUart->UART_RHR;
232#endif
233
234#if defined CONSOLE_ON_USART
235        Usart *pUsart = CONSOLE_Usart;
236
237        if (!_ucIsConsoleInitialized)
238                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
239
240        while ((pUsart->US_CSR & US_CSR_RXRDY) == 0);
241
242        return pUsart->US_RHR;
243#endif
244}
245
246/**
247 * \brief Check if there is Input from UART line.
248 *
249 * \return true if there is Input.
250 */
251extern uint32_t DBG_IsRxReady(void)
252{
253#if defined CONSOLE_ON_UART
254        Uart *pUart = CONSOLE_UART;
255
256        if (!_ucIsConsoleInitialized)
257                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
258
259        return (pUart->UART_SR & UART_SR_RXRDY);
260#endif
261
262#if defined CONSOLE_ON_USART
263        Usart *pUsart = CONSOLE_Usart;
264
265        if (!_ucIsConsoleInitialized)
266                DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
267
268        return (pUsart->US_CSR & US_CSR_RXRDY);
269#endif
270}
271
272/**
273 *  Displays the content of the given frame on the UART0.
274 *
275 *  \param pucFrame Pointer to the frame to dump.
276 *  \param dwSize   Buffer size in bytes.
277 */
278extern void DBG_DumpFrame(uint8_t *pucFrame, uint32_t dwSize)
279{
280        uint32_t dw;
281
282        for (dw = 0; dw < dwSize; dw++)
283                printf("%02X ", pucFrame[dw]);
284
285        printf("\n\r");
286}
287
288/**
289 *  Displays the content of the given buffer on the UART0.
290 *
291 *  \param pucBuffer  Pointer to the buffer to dump.
292 *  \param dwSize     Buffer size in bytes.
293 *  \param dwAddress  Start address to display
294 */
295extern void DBG_DumpMemory(uint8_t *pucBuffer, uint32_t dwSize,
296                                                        uint32_t dwAddress)
297{
298        uint32_t i;
299        uint32_t j;
300        uint32_t dwLastLineStart;
301        uint8_t *pucTmp;
302
303        for (i = 0; i < (dwSize / 16); i++) {
304                printf("0x%08X: ", (unsigned int)(dwAddress + (i * 16)));
305                pucTmp = (uint8_t *)&pucBuffer[i * 16];
306
307                for (j = 0; j < 4; j++) {
308                        printf("%02X%02X%02X%02X ",
309                                        pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3]);
310                        pucTmp += 4;
311                }
312
313                pucTmp = (uint8_t *)&pucBuffer[i * 16];
314
315                for (j = 0; j < 16; j++)
316                        DBG_PutChar(*pucTmp++);
317
318                printf("\n\r");
319        }
320
321        if ((dwSize % 16) != 0) {
322                dwLastLineStart = dwSize - (dwSize % 16);
323
324                printf("0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart));
325
326                for (j = dwLastLineStart; j < dwLastLineStart + 16; j++) {
327                        if ((j != dwLastLineStart) && (j % 4 == 0))
328                                printf(" ");
329
330                        if (j < dwSize)
331                                printf("%02X", pucBuffer[j]);
332                        else
333                                printf("  ");
334                }
335
336                printf(" ");
337
338                for (j = dwLastLineStart; j < dwSize; j++)
339                        DBG_PutChar(pucBuffer[j]);
340
341                printf("\n\r");
342        }
343}
344
345/**
346 * Reads an integer
347 *
348 * \param pdwValue  Pointer to a integer variable to contain the input value.
349 *
350 * \return success(1) or failure(0)
351 */
352extern uint32_t DBG_GetInteger(int32_t *pdwValue)
353{
354        uint8_t ucKey;
355        uint8_t ucNum = 0;
356        int32_t dwValue = 0;
357        int32_t sign = 1;
358
359        while (1) {
360                ucKey = DBG_GetChar();
361                DBG_PutChar(ucKey);
362
363                if (((ucKey == '-') || (ucKey == '+')) && (ucNum == 0)) {
364                        if (ucKey == '-')
365                                sign = -1;
366                        else
367                                sign = 1;
368
369                        ucNum++;
370                } else {
371                        if (ucKey >= '0' && ucKey <= '9') {
372                                dwValue = (dwValue * 10) + (ucKey - '0');
373                                ucNum++;
374                        } else {
375                                if (ucKey == 0x0D || ucKey == ' ') {
376                                        if (ucNum == 0) {
377                                                printf("\n\rWrite a number and press ENTER or SPACE!\n\r");
378                                                return 0;
379                                        } else {
380                                                printf("\n\r");
381                                                *pdwValue = dwValue * sign;
382
383                                                return 1;
384                                        }
385                                } else {
386                                        printf("\n\r'%c' not a number or sign(+/-)!\n\r", ucKey);
387                                        return 0;
388                                }
389                        }
390                }
391        }
392}
393
394/**
395 * Reads an integer and check the value
396 *
397 * \param pdwValue  Pointer to a integer variable to contain the input value.
398 * \param dwMin     Minimum value
399 * \param dwMax     Maximum value
400 *
401 * \return success(1) or failure(0)
402 */
403extern uint32_t DBG_GetIntegerMinMax(int32_t *pdwValue, int32_t dwMin,
404                                                                         int32_t dwMax)
405{
406        int32_t dwValue = 0;
407
408        if (DBG_GetInteger(&dwValue) == 0)
409                return 0;
410
411        if (dwValue < dwMin || dwValue > dwMax) {
412                printf("\n\rThe number have to be between %d and %d\n\r",
413                                (int)dwMin, (int)dwMax);
414
415                return 0;
416        }
417
418        printf("\n\r");
419
420        *pdwValue = dwValue;
421
422        return 1;
423}
424
425/**
426 *  Reads an hexadecimal number
427 *
428 *  \param pdwValue  Pointer to the uint32_t variable to contain the input value.
429 */
430extern uint32_t DBG_GetHexa32(uint32_t *pdwValue)
431{
432        uint8_t ucKey;
433        uint32_t dw = 0;
434        uint32_t dwValue = 0;
435
436        for (dw = 0; dw < 8; dw++) {
437                ucKey = DBG_GetChar();
438                DBG_PutChar(ucKey);
439
440                if (ucKey >= '0' &&  ucKey <= '9')
441                        dwValue = (dwValue * 16) + (ucKey - '0');
442                else {
443                        if (ucKey >= 'A' &&  ucKey <= 'F')
444                                dwValue = (dwValue * 16) + (ucKey - 'A' + 10);
445                        else {
446                                if (ucKey >= 'a' &&  ucKey <= 'f')
447                                        dwValue = (dwValue * 16) + (ucKey - 'a' + 10);
448                                else {
449                                        printf("\n\rIt is not a hexadecimal character!\n\r");
450
451                                        return 0;
452                                }
453                        }
454                }
455        }
456
457        printf("\n\r");
458        *pdwValue = dwValue;
459
460        return 1;
461}
462
463#if defined __ICCARM__ /* IAR Ewarm 5.41+ */
464/**
465 * \brief Outputs a character on the UART.
466 *
467 * \param c  Character to output.
468 *
469 * \return The character that was output.
470 */
471extern WEAK signed int putchar(signed int c)
472{
473        DBG_PutChar(c);
474
475        return c;
476}
477
478#endif  // defined __ICCARM__
479extern WEAK int puts(const char *ptr)
480{
481
482        for (; *ptr != 0; ptr++)
483                DBG_PutChar(*ptr);
484
485        return 0;
486
487}
488
489extern WEAK char *gets(char *ptr)
490{
491        uint8_t ch = 0;
492
493        while (ch != '\r') {
494                ch = DBG_GetChar();
495                DBG_PutChar(ch);
496                *(ptr++) = ch;
497        }
498
499        *ptr = '\0';
500        return 0;
501
502}
503
504
Note: See TracBrowser for help on using the repository browser.