| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580 |
- #include "nim_config.h"
- #include "uart.h"
- /*
- * uart_util.c
- *
- * Created on: 2025年7月30日
- * Author: wulianwei
- */
- //static char txArray[] = "Nim DSP Application\r\n";
- /* A mapping from an integer between 0 and 15 to its ASCII character
- * equivalent. */
- static const char *const g_pcHex = "0123456789abcdef";
- static uart_recv_t console_recv = { 0 }; //串口接收缓存
- static void uart_recv_clear(uart_recv_t* uart_recv);
- static void uart_recv_wait(uart_recv_t* uart_recv,int timeout);
- /****************************************************************************/
- /* */
- /* 串口控制台初始化 */
- /* */
- /****************************************************************************/
- void ConsoleDeviceInit(void)
- {
- if(UART_CONSOLE_BASE == SOC_UART_1_REGS)
- {
- UART1Init();
- }
- else if(UART_CONSOLE_BASE == SOC_UART_2_REGS)
- {
- UART2Init();
- }
- }
- /****************************************************************************/
- /* */
- /* 输出一个字符 */
- /* */
- /****************************************************************************/
- void UARTConsolePutc(unsigned char data)
- {
- UARTCharPut(UART_CONSOLE_BASE, data);
- }
- /****************************************************************************/
- /* */
- /* 取得一个字符 */
- /* */
- /****************************************************************************/
- unsigned char UARTConsoleGetc(void)
- {
- return ((unsigned char) UARTCharGet(UART_CONSOLE_BASE));
- }
- void ConsolePutsHexStr(unsigned char *source, unsigned int numBytesToWrite)
- {
- unsigned char highByte, lowByte;
- short i = 0;
- for (i = 0; i < numBytesToWrite; i++)
- {
- highByte = ((source[i] >> 4)&0x0f) + 0x30;
- lowByte = (source[i] & 0x0f) + 0x30;
- highByte = highByte>0x39? highByte+0x07 : highByte;
- lowByte = lowByte>0x39? lowByte+0x07 : lowByte;
- UARTConsolePutc(highByte);
- UARTConsolePutc(lowByte);
- }
- }
- /**
- * \brief This function writes data from a specified buffer onto the
- * transmitter FIFO of UART.
- *
- * \param pTxBuffer Pointer to a buffer in the transmitter.
- * \param numBytesToWrite Number of bytes to be transmitted to the
- * transmitter FIFO. The user has the freedom to not
- * specify any valid value for this if he wants to
- * print until the occurence of a NULL character.
- * In this case, he has to pass a negative value as
- * this parameter.
- *
- * \return Number of bytes written to the transmitter FIFO.
- *
- * \note 1> Whenever a null character(\0) is encountered in the
- * data to be transmitted, the transmission is stopped. \n
- * 2> Whenever the transmitter data has a new line character(\n),
- * it is interpreted as a new line(\n) + carraige return(\r)
- * characters. This is because the serial console interprets a
- * new line character as it is and does not introduce a carraige
- * return. \n
- *
- * Some example function calls of this function are: \n
- *
- * UARTPuts(txArray, -2): This shall print the contents of txArray[]
- * until the occurence of a NULL character. \n
- *
- * UARTPuts("Hello World", 8): This shall print the first 8 characters
- * of the string shown. \n
- *
- * UARTPuts("Hello World", 20): This shall print the string shown until
- * the occurence of the NULL character. Here, the NULL character is
- * encountered earlier than the length of 20 bytes.\n
- *
- */
- unsigned int ConsolePuts(char *pTxBuffer, int numBytesToWrite)
- {
- unsigned int count = 0;
- unsigned int flag = 0;
- if (numBytesToWrite < 0)
- {
- flag = 1;
- }
- while ('\0' != *pTxBuffer)
- {
- /* Checks if data is a newline character. */
- if ('\n' == *pTxBuffer)
- {
- /* Ensuring applicability to serial console.*/
- UARTConsolePutc('\r');
- UARTConsolePutc('\n');
- }
- else
- {
- UARTConsolePutc((unsigned char) *pTxBuffer);
- }
- pTxBuffer++;
- count++;
- if ((0 == flag) && (count == numBytesToWrite))
- {
- break;
- }
- }
- /* Returns the number of bytes written onto the transmitter FIFO. */
- return count;
- }
- void ConsolePrintf(char *fmt, ...)
- {
- //return ;
- unsigned char UsartPrintfBuf[512];
- va_list ap;
- unsigned char *pStr = UsartPrintfBuf;
- va_start(ap, fmt);
- vsnprintf((char*) UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);
- va_end(ap);
- while (*pStr != 0)
- {
- UARTConsolePutc(*pStr++);
- }
- }
- unsigned int UARTwrite(const char *pcBuf, unsigned int len)
- {
- unsigned int uIdx;
- /* Send the characters */
- for(uIdx = 0; uIdx < len; uIdx++)
- {
- /* If the character to the UART is \n, then add a \r before it so that
- * \n is translated to \n\r in the output. */
- if(pcBuf[uIdx] == '\n')
- {
- UARTConsolePutc('\r');
- }
- /* Send the character to the UART output. */
- UARTConsolePutc(pcBuf[uIdx]);
- }
- /* Return the number of characters written. */
- return(uIdx);
- }
- /**
- * A simple UART based printf function supporting \%c, \%d, \%p, \%s, \%u,
- * \%x, and \%X.
- *
- * \param pcString is the format string.
- * \param ... are the optional arguments, which depend on the contents of the
- * format string.
- *
- * This function is very similar to the C library <tt>fprintf()</tt> function.
- * All of its output will be sent to the UART. Only the following formatting
- * characters are supported:
- *
- * - \%c to print a character
- * - \%d to print a decimal value
- * - \%s to print a string
- * - \%u to print an unsigned decimal value
- * - \%x to print a hexadecimal value using lower case letters
- * - \%X to print a hexadecimal value using lower case letters (not upper case
- * letters as would typically be used)
- * - \%p to print a pointer as a hexadecimal value
- * - \%\% to print out a \% character
- *
- * For \%s, \%d, \%u, \%p, \%x, and \%X, an optional number may reside
- * between the \% and the format character, which specifies the minimum number
- * of characters to use for that value; if preceded by a 0 then the extra
- * characters will be filled with zeros instead of spaces. For example,
- * ``\%8d'' will use eight characters to print the decimal value with spaces
- * added to reach eight; ``\%08d'' will use eight characters as well but will
- * add zeroes instead of spaces.
- *
- * The type of the arguments after \e pcString must match the requirements of
- * the format string. For example, if an integer was passed where a string
- * was expected, an error of some kind will most likely occur.
- *
- * \return None.
- */
- void LogPrintf(const char *pcString, ...)
- {
- unsigned int idx, pos, count, base, neg;
- char *pcStr, pcBuf[16], cFill;
- va_list vaArgP;
- int value;
- /* Start the varargs processing. */
- va_start(vaArgP, pcString);
- /* Loop while there are more characters in the string. */
- while (*pcString)
- {
- /* Find the first non-% character, or the end of the string. */
- for (idx = 0; (pcString[idx] != '%') && (pcString[idx] != '\0'); idx++)
- {
- }
- /* Write this portion of the string. */
- UARTwrite(pcString, idx);
- /* Skip the portion of the string that was written. */
- pcString += idx;
- /* See if the next character is a %. */
- if (*pcString == '%')
- {
- /* Skip the %. */
- pcString++;
- /* Set the digit count to zero, and the fill character to space
- * (i.e. to the defaults). */
- count = 0;
- cFill = ' ';
- /* It may be necessary to get back here to process more characters.
- * Goto's aren't pretty, but effective. I feel extremely dirty for
- * using not one but two of the beasts. */
- again:
- /* Determine how to handle the next character. */
- switch (*pcString++)
- {
- /* Handle the digit characters. */
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- /* If this is a zero, and it is the first digit, then the
- * fill character is a zero instead of a space. */
- if ((pcString[-1] == '0') && (count == 0))
- {
- cFill = '0';
- }
- /* Update the digit count. */
- count *= 10;
- count += pcString[-1] - '0';
- /* Get the next character. */
- goto again;
- }
- /* Handle the %c command. */
- case 'c':
- {
- /* Get the value from the varargs. */
- value = va_arg(vaArgP, unsigned int);
- /* Print out the character. */
- UARTwrite((char*) &value, 1);
- /* This command has been handled. */
- break;
- }
- /* Handle the %d command. */
- case 'd':
- {
- /* Get the value from the varargs. */
- value = va_arg(vaArgP, unsigned int);
- /* Reset the buffer position. */
- pos = 0;
- /* If the value is negative, make it positive and indicate
- * that a minus sign is needed. */
- if ((int) value < 0)
- {
- /* Make the value positive. */
- value = -(int) value;
- /* Indicate that the value is negative. */
- neg = 1;
- }
- else
- {
- /* Indicate that the value is positive so that a minus
- * sign isn't inserted. */
- neg = 0;
- }
- /* Set the base to 10. */
- base = 10;
- /* Convert the value to ASCII. */
- goto convert;
- }
- /* Handle the %s command. */
- case 's':
- {
- /* Get the string pointer from the varargs. */
- pcStr = va_arg(vaArgP, char *);
- /* Determine the length of the string. */
- for (idx = 0; pcStr[idx] != '\0'; idx++)
- {
- }
- /* Write the string. */
- UARTwrite(pcStr, idx);
- /* Write any required padding spaces */
- if (count > idx)
- {
- count -= idx;
- while (count--)
- {
- UARTwrite((const char*) " ", 1);
- }
- }
- /* This command has been handled. */
- break;
- }
- /* Handle the %u command. */
- case 'u':
- {
- /* Get the value from the varargs. */
- value = va_arg(vaArgP, unsigned int);
- /* Reset the buffer position. */
- pos = 0;
- /* Set the base to 10. */
- base = 10;
- /* Indicate that the value is positive so that a minus sign
- * isn't inserted. */
- neg = 0;
- /* Convert the value to ASCII. */
- goto convert;
- }
- /* Handle the %x and %X commands. Note that they are treated
- * identically; i.e. %X will use lower case letters for a-f
- * instead of the upper case letters is should use. We also
- * alias %p to %x. */
- case 'x':
- case 'X':
- case 'p':
- {
- /* Get the value from the varargs. */
- value = va_arg(vaArgP, unsigned int);
- /* Reset the buffer position. */
- pos = 0;
- /* Set the base to 16. */
- base = 16;
- /* Indicate that the value is positive so that a minus sign
- * isn't inserted. */
- neg = 0;
- /* Determine the number of digits in the string version of
- * the value. */
- convert: for (idx = 1;
- (((idx * base) <= value)
- && (((idx * base) / base) == idx));
- idx *= base, count--)
- {
- }
- /* If the value is negative, reduce the count of padding
- * characters needed. */
- if (neg)
- {
- count--;
- }
- /* If the value is negative and the value is padded with
- * zeros, then place the minus sign before the padding. */
- if (neg && (cFill == '0'))
- {
- /* Place the minus sign in the output buffer. */
- pcBuf[pos++] = '-';
- /* The minus sign has been placed, so turn off the
- * negative flag. */
- neg = 0;
- }
- /* Provide additional padding at the beginning of the
- * string conversion if needed. */
- if ((count > 1) && (count < 16))
- {
- for (count--; count; count--)
- {
- pcBuf[pos++] = cFill;
- }
- }
- /* If the value is negative, then place the minus sign
- * before the number. */
- if (neg)
- {
- /* Place the minus sign in the output buffer. */
- pcBuf[pos++] = '-';
- }
- /* Convert the value into a string. */
- for (; idx; idx /= base)
- {
- pcBuf[pos++] = g_pcHex[(value / idx) % base];
- }
- /* Write the string. */
- UARTwrite(pcBuf, pos);
- /* This command has been handled. */
- break;
- }
- /* Handle the %% command. */
- case '%':
- {
- /* Simply write a single %. */
- UARTwrite(pcString - 1, 1);
- /* This command has been handled. */
- break;
- }
- /* Handle all other commands. */
- default:
- {
- /* Indicate an error. */
- UARTwrite((const char*) "ERROR", 5);
- /* This command has been handled. */
- break;
- }
- }
- }
- }
- /* End the varargs processing. */
- va_end(vaArgP);
- }
- /**
- *接收控制台数据
- */
- void ConsoleRecvFill(unsigned char data)
- {
- if (console_recv.len >= sizeof(console_recv.buf) - 1) console_recv.len = 0;
- console_recv.buf[console_recv.len++] = data;
- }
- /**
- * 清空接收的控制台数据
- */
- void ConsoleRecvClear()
- {
- uart_recv_clear(&console_recv);
- }
- /**
- * @Title 等待接收控制台数据
- * @Param timeout, 最长等待时间,单位毫秒
- */
- void ConsoleRecvWait(int timeout)
- {
- uart_recv_wait(&console_recv,timeout);
- }
- /**
- * 串口接收状态
- */
- unsigned char* ConsoleRecvData()
- {
- return console_recv.buf;
- }
- /**
- * 串口接收长度
- */
- int ConsoleRecvLen()
- {
- return console_recv.len;
- }
- /**
- * 串口接收状态
- */
- recv_status_e ConsoleRecvFlag()
- {
- return console_recv.recv_flag;
- }
- /**
- *@Title 清空串口接收缓存
- */
- static void uart_recv_clear(uart_recv_t* uart_recv)
- {
- memset(uart_recv->buf,0,sizeof(uart_recv->buf));
- uart_recv->len = 0;
- uart_recv->recv_flag = REV_WAIT;
- }
- /**
- *@Title 等待串口接收数据
- *@Param 最长等待时间
- */
- static void uart_recv_wait(uart_recv_t* uart_recv,int timeout)
- {
- int per = 5; //
- int prelen = 0;
- if(timeout<=0) return;
- timeout=timeout/per+(timeout%per==0? 0 : 1);
- while(timeout--)
- {
- if(uart_recv->len)
- {
- if(uart_recv->len == prelen)
- {
- uart_recv->recv_flag = REV_OK; //
- break;
- }
- else
- {
- prelen = uart_recv->len;
- }
- }
- delay_ms(per);
- }
- }
|