SAMV71 Xplained Ultra Software Package 1.5

dbg_console.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /**
00031  * \file
00032  *
00033  * Implements UART console.
00034  *
00035  */
00036 
00037 /*----------------------------------------------------------------------------
00038  *        Headers
00039  *----------------------------------------------------------------------------*/
00040 
00041 #include "board.h"
00042 
00043 #include <stdio.h>
00044 #include <stdint.h>
00045 
00046 /*----------------------------------------------------------------------------
00047  *        Definitions
00048  *----------------------------------------------------------------------------*/
00049 
00050 /** Console baud rate always using 115200. */
00051 
00052 
00053 #define CONSOLE_BAUDRATE    115200
00054 
00055 /** EDBG used USART1 as the console, but LON support on USART1 only */
00056 #ifndef USART_LON
00057     #define CONSOLE_EDBG
00058 #endif
00059 
00060 #if defined CONSOLE_EDBG
00061     #define CONSOLE_ON_USART
00062 #else
00063     #define CONSOLE_ON_UART
00064 #endif
00065 
00066 #if defined CONSOLE_ON_UART
00067     #if defined SSC_AUDIO || defined USART_LON
00068         /** Usart Hw interface used by the console (UART4). */
00069         #define CONSOLE_UART       UART4
00070 
00071         /** Pins description corresponding to Rxd,Txd, (UART pins) */
00072         #define CONSOLE_PINS        {PINS_UART4}
00073 
00074         #define CONSOLE_ID          ID_UART4
00075     #else
00076         /** Usart Hw interface used by the console (UART0). */
00077         #define CONSOLE_UART       UART0
00078 
00079         /** Pins description corresponding to Rxd,Txd, (UART pins) */
00080         #define CONSOLE_PINS        {PINS_UART0}
00081 
00082         #define CONSOLE_ID          ID_UART0
00083 
00084     #endif
00085 #endif
00086 
00087 #if defined CONSOLE_ON_USART
00088 
00089 /** USART1 pin RX */
00090 #define PIN_USART1_RXD_DBG \
00091     {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
00092 /** USART1 pin TX */
00093 #define PIN_USART1_TXD_DBG \
00094     {PIO_PB4D_TXD1, PIOB, ID_PIOB, PIO_PERIPH_D, PIO_DEFAULT}
00095 #define PINS_USART1        PIN_USART1_TXD_DBG, PIN_USART1_RXD_DBG
00096 
00097 /** Usart Hw interface used by the console (Usart0). */
00098 #define CONSOLE_Usart      USART1
00099 
00100 /** Pins description corresponding to Rxd,Txd, (Usart pins) */
00101 #define CONSOLE_PINS      {PINS_USART1}
00102 
00103 #define CONSOLE_ID        ID_USART1
00104 #endif
00105 
00106 
00107 /*----------------------------------------------------------------------------
00108  *        Variables
00109  *----------------------------------------------------------------------------*/
00110 
00111 /** Is Console Initialized. */
00112 static uint8_t _ucIsConsoleInitialized = 0;
00113 
00114 /**
00115  * \brief Configures an USART peripheral with the specified parameters.
00116  *
00117  * \param baudrate  Baudrate at which the USART should operate (in Hz).
00118  * \param masterClock  Frequency of the system master clock (in Hz).
00119  */
00120 extern void DBG_Configure(uint32_t baudrate, uint32_t masterClock)
00121 {
00122 
00123     const Pin pPins[] = CONSOLE_PINS;
00124 #if defined CONSOLE_ON_UART
00125     Uart *pUart = CONSOLE_UART;
00126     /* Configure PIO */
00127     PIO_Configure(pPins, PIO_LISTSIZE(pPins));
00128 
00129     // Reset & disable receiver and transmitter, disable interrupts
00130     pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RSTSTA;
00131     pUart->UART_IDR = 0xFFFFFFFF;
00132     PMC_EnablePeripheral(CONSOLE_ID);
00133     pUart->UART_BRGR = (masterClock / baudrate) / 16;
00134     // Configure mode register
00135     pUart->UART_MR
00136         = (UART_MR_CHMODE_NORMAL | UART_MR_PAR_NO
00137            | UART_MR_BRSRCCK_PERIPH_CLK);
00138     // Enable receiver and transmitter
00139     pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
00140 #endif
00141 
00142 #if defined CONSOLE_ON_USART
00143     Usart *pUsart = CONSOLE_Usart;
00144     // Disable the MATRIX registers write protection
00145     MATRIX->MATRIX_WPMR  = MATRIX_WPMR_WPKEY_PASSWD;
00146     MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4;
00147 
00148     PIO_Configure(pPins, PIO_LISTSIZE(pPins));
00149 
00150     // Reset & disable receiver and transmitter, disable interrupts
00151     pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RSTSTA;
00152     pUsart->US_IDR = 0xFFFFFFFF;
00153     PMC_EnablePeripheral(CONSOLE_ID);
00154     pUsart->US_BRGR = (masterClock / baudrate) / 16;
00155 
00156     // Configure mode register
00157     pUsart->US_MR
00158         = (US_MR_USART_MODE_NORMAL | US_MR_PAR_NO | US_MR_USCLKS_MCK
00159            | US_MR_CHRL_8_BIT);
00160 
00161     // Enable receiver and transmitter
00162     pUsart->US_CR = US_CR_RXEN | US_CR_TXEN;
00163 #endif
00164     _ucIsConsoleInitialized = 1;
00165 
00166     /* Disable buffering for printf(). */
00167 #if (defined (__GNUC__) && !defined (__SAMBA__))
00168     setvbuf(stdout, (char *)NULL, _IONBF, 0);
00169 #endif
00170 }
00171 
00172 /**
00173  * \brief Outputs a character on the UART line.
00174  *
00175  * \note This function is synchronous (i.e. uses polling).
00176  * \param c  Character to send.
00177  */
00178 extern void DBG_PutChar(uint8_t c)
00179 {
00180 #if defined CONSOLE_ON_UART
00181     Uart *pUart = CONSOLE_UART;
00182 
00183     if (!_ucIsConsoleInitialized)
00184         DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
00185 
00186     // Wait for the transmitter to be ready
00187     while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
00188 
00189     // Send character
00190     pUart->UART_THR = c;
00191 
00192     // Wait for the transfer to complete
00193     while ((pUart->UART_SR & UART_SR_TXEMPTY) == 0);
00194 
00195 #endif
00196 
00197 #if defined CONSOLE_ON_USART
00198     Usart *pUsart = CONSOLE_Usart;
00199 
00200     if (!_ucIsConsoleInitialized)
00201         DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
00202 
00203     // Wait for the transmitter to be ready
00204     while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
00205 
00206     // Send character
00207     pUsart->US_THR = c;
00208 
00209     // Wait for the transfer to complete
00210     while ((pUsart->US_CSR & US_CSR_TXEMPTY) == 0);
00211 
00212 #endif
00213 }
00214 
00215 /**
00216  * \brief Input a character from the UART line.
00217  *
00218  * \note This function is synchronous
00219  * \return character received.
00220  */
00221 extern uint32_t DBG_GetChar(void)
00222 {
00223 #if defined CONSOLE_ON_UART
00224     Uart *pUart = CONSOLE_UART;
00225 
00226     if (!_ucIsConsoleInitialized)
00227         DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
00228 
00229     while ((pUart->UART_SR & UART_SR_RXRDY) == 0);
00230 
00231     return pUart->UART_RHR;
00232 #endif
00233 
00234 #if defined CONSOLE_ON_USART
00235     Usart *pUsart = CONSOLE_Usart;
00236 
00237     if (!_ucIsConsoleInitialized)
00238         DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
00239 
00240     while ((pUsart->US_CSR & US_CSR_RXRDY) == 0);
00241 
00242     return pUsart->US_RHR;
00243 #endif
00244 }
00245 
00246 /**
00247  * \brief Check if there is Input from UART line.
00248  *
00249  * \return true if there is Input.
00250  */
00251 extern uint32_t DBG_IsRxReady(void)
00252 {
00253 #if defined CONSOLE_ON_UART
00254     Uart *pUart = CONSOLE_UART;
00255 
00256     if (!_ucIsConsoleInitialized)
00257         DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
00258 
00259     return (pUart->UART_SR & UART_SR_RXRDY);
00260 #endif
00261 
00262 #if defined CONSOLE_ON_USART
00263     Usart *pUsart = CONSOLE_Usart;
00264 
00265     if (!_ucIsConsoleInitialized)
00266         DBG_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
00267 
00268     return (pUsart->US_CSR & US_CSR_RXRDY);
00269 #endif
00270 }
00271 
00272 /**
00273  *  Displays the content of the given frame on the UART0.
00274  *
00275  *  \param pucFrame Pointer to the frame to dump.
00276  *  \param dwSize   Buffer size in bytes.
00277  */
00278 extern void DBG_DumpFrame(uint8_t *pucFrame, uint32_t dwSize)
00279 {
00280     uint32_t dw;
00281 
00282     for (dw = 0; dw < dwSize; dw++)
00283         printf("%02X ", pucFrame[dw]);
00284 
00285     printf("\n\r");
00286 }
00287 
00288 /**
00289  *  Displays the content of the given buffer on the UART0.
00290  *
00291  *  \param pucBuffer  Pointer to the buffer to dump.
00292  *  \param dwSize     Buffer size in bytes.
00293  *  \param dwAddress  Start address to display
00294  */
00295 extern void DBG_DumpMemory(uint8_t *pucBuffer, uint32_t dwSize,
00296                             uint32_t dwAddress)
00297 {
00298     uint32_t i;
00299     uint32_t j;
00300     uint32_t dwLastLineStart;
00301     uint8_t *pucTmp;
00302 
00303     for (i = 0; i < (dwSize / 16); i++) {
00304         printf("0x%08X: ", (unsigned int)(dwAddress + (i * 16)));
00305         pucTmp = (uint8_t *)&pucBuffer[i * 16];
00306 
00307         for (j = 0; j < 4; j++) {
00308             printf("%02X%02X%02X%02X ",
00309                     pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3]);
00310             pucTmp += 4;
00311         }
00312 
00313         pucTmp = (uint8_t *)&pucBuffer[i * 16];
00314 
00315         for (j = 0; j < 16; j++)
00316             DBG_PutChar(*pucTmp++);
00317 
00318         printf("\n\r");
00319     }
00320 
00321     if ((dwSize % 16) != 0) {
00322         dwLastLineStart = dwSize - (dwSize % 16);
00323 
00324         printf("0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart));
00325 
00326         for (j = dwLastLineStart; j < dwLastLineStart + 16; j++) {
00327             if ((j != dwLastLineStart) && (j % 4 == 0))
00328                 printf(" ");
00329 
00330             if (j < dwSize)
00331                 printf("%02X", pucBuffer[j]);
00332             else
00333                 printf("  ");
00334         }
00335 
00336         printf(" ");
00337 
00338         for (j = dwLastLineStart; j < dwSize; j++)
00339             DBG_PutChar(pucBuffer[j]);
00340 
00341         printf("\n\r");
00342     }
00343 }
00344 
00345 /**
00346  * Reads an integer
00347  *
00348  * \param pdwValue  Pointer to a integer variable to contain the input value.
00349  *
00350  * \return success(1) or failure(0)
00351  */
00352 extern uint32_t DBG_GetInteger(int32_t *pdwValue)
00353 {
00354     uint8_t ucKey;
00355     uint8_t ucNum = 0;
00356     int32_t dwValue = 0;
00357     int32_t sign = 1;
00358 
00359     while (1) {
00360         ucKey = DBG_GetChar();
00361         DBG_PutChar(ucKey);
00362 
00363         if (((ucKey == '-') || (ucKey == '+')) && (ucNum == 0)) {
00364             if (ucKey == '-')
00365                 sign = -1;
00366             else
00367                 sign = 1;
00368 
00369             ucNum++;
00370         } else {
00371             if (ucKey >= '0' && ucKey <= '9') {
00372                 dwValue = (dwValue * 10) + (ucKey - '0');
00373                 ucNum++;
00374             } else {
00375                 if (ucKey == 0x0D || ucKey == ' ') {
00376                     if (ucNum == 0) {
00377                         printf("\n\rWrite a number and press ENTER or SPACE!\n\r");
00378                         return 0;
00379                     } else {
00380                         printf("\n\r");
00381                         *pdwValue = dwValue * sign;
00382 
00383                         return 1;
00384                     }
00385                 } else {
00386                     printf("\n\r'%c' not a number or sign(+/-)!\n\r", ucKey);
00387                     return 0;
00388                 }
00389             }
00390         }
00391     }
00392 }
00393 
00394 /**
00395  * Reads an integer and check the value
00396  *
00397  * \param pdwValue  Pointer to a integer variable to contain the input value.
00398  * \param dwMin     Minimum value
00399  * \param dwMax     Maximum value
00400  *
00401  * \return success(1) or failure(0)
00402  */
00403 extern uint32_t DBG_GetIntegerMinMax(int32_t *pdwValue, int32_t dwMin,
00404                                      int32_t dwMax)
00405 {
00406     int32_t dwValue = 0;
00407 
00408     if (DBG_GetInteger(&dwValue) == 0)
00409         return 0;
00410 
00411     if (dwValue < dwMin || dwValue > dwMax) {
00412         printf("\n\rThe number have to be between %d and %d\n\r",
00413                 (int)dwMin, (int)dwMax);
00414 
00415         return 0;
00416     }
00417 
00418     printf("\n\r");
00419 
00420     *pdwValue = dwValue;
00421 
00422     return 1;
00423 }
00424 
00425 /**
00426  *  Reads an hexadecimal number
00427  *
00428  *  \param pdwValue  Pointer to the uint32_t variable to contain the input value.
00429  */
00430 extern uint32_t DBG_GetHexa32(uint32_t *pdwValue)
00431 {
00432     uint8_t ucKey;
00433     uint32_t dw = 0;
00434     uint32_t dwValue = 0;
00435 
00436     for (dw = 0; dw < 8; dw++) {
00437         ucKey = DBG_GetChar();
00438         DBG_PutChar(ucKey);
00439 
00440         if (ucKey >= '0' &&  ucKey <= '9')
00441             dwValue = (dwValue * 16) + (ucKey - '0');
00442         else {
00443             if (ucKey >= 'A' &&  ucKey <= 'F')
00444                 dwValue = (dwValue * 16) + (ucKey - 'A' + 10);
00445             else {
00446                 if (ucKey >= 'a' &&  ucKey <= 'f')
00447                     dwValue = (dwValue * 16) + (ucKey - 'a' + 10);
00448                 else {
00449                     printf("\n\rIt is not a hexadecimal character!\n\r");
00450 
00451                     return 0;
00452                 }
00453             }
00454         }
00455     }
00456 
00457     printf("\n\r");
00458     *pdwValue = dwValue;
00459 
00460     return 1;
00461 }
00462 
00463 #if defined __ICCARM__ /* IAR Ewarm 5.41+ */
00464 /**
00465  * \brief Outputs a character on the UART.
00466  *
00467  * \param c  Character to output.
00468  *
00469  * \return The character that was output.
00470  */
00471 extern WEAK signed int putchar(signed int c)
00472 {
00473     DBG_PutChar(c);
00474 
00475     return c;
00476 }
00477 
00478 #endif  // defined __ICCARM__
00479 extern WEAK int puts(const char *ptr)
00480 {
00481 
00482     for (; *ptr != 0; ptr++)
00483         DBG_PutChar(*ptr);
00484 
00485     return 0;
00486 
00487 }
00488 
00489 extern WEAK char *gets(char *ptr)
00490 {
00491     uint8_t ch = 0;
00492 
00493     while (ch != '\r') {
00494         ch = DBG_GetChar();
00495         DBG_PutChar(ch);
00496         *(ptr++) = ch;
00497     }
00498 
00499     *ptr = '\0';
00500     return 0;
00501 
00502 }
00503 
00504 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines