123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- /*
- * This Source Code Form is subject to the terms of the MIT License.
- * If a copy of the MIT License was not distributed with this file,
- * you can obtain one at https://opensource.org/licenses/MIT
- */
- #include <string.h>
- #include "main.h"
- #include "uart.h"
- #include "system.h"
- #define UART_BUFFER_LEN (12u)
- #define UART1 (0x40004000)
- #define UART2 (0x40004400)
- #define UART3 (0x40004800)
- #define UART2_SR (*(volatile uint32_t *)(UART2))
- #define UART2_DR (*(volatile uint32_t *)(UART2 + 0x04))
- #define UART2_BRR (*(volatile uint32_t *)(UART2 + 0x08))
- #define UART2_CR1 (*(volatile uint32_t *)(UART2 + 0x0c))
- #define UART2_CR2 (*(volatile uint32_t *)(UART2 + 0x10))
- #define UART_CR1_UART_ENABLE (1 << 13)
- #define UART_CR1_SYMBOL_LEN (1 << 12)
- #define UART_CR1_PARITY_ENABLED (1 << 10)
- #define UART_CR1_PARITY_ODD (1 << 9)
- #define UART_CR1_TX_ENABLE (1 << 3)
- #define UART_CR1_RX_ENABLE (1 << 2)
- #define UART_CR2_STOPBITS (3 << 12)
- #define UART_SR_TX_EMPTY (1 << 7)
- #define UART_SR_RX_NOTEMPTY (1 << 5)
- //#define UART_WAIT_TRANSMIT do { } while(0)
- #define UART_WAIT_TRANSMIT do { ; } while (!(UART2_SR & UART_SR_TX_EMPTY))
- #define CLOCK_SPEED (168000000)
- #define NVIC_UART1_IRQN (37)
- #define NVIC_UART2_IRQN (38)
- #define NVIC_UART3_IRQN (39)
- #define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
- #define UART1_APB1_CLOCK_ER_VAL (1 << 14)
- #define UART2_APB1_CLOCK_ER_VAL (1 << 17)
- #define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
- #define GPIOD_AHB1_CLOCK_ER (1 << 3)
- #define GPIOD_BASE 0x40020c00
- #define GPIOD_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00))
- #define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20))
- #define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24))
- #define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20))
- #define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24))
- #define GPIO_MODE_AF (2)
- #define UART2_PIN_AF 7
- #ifndef CUSTOM_HW
- #define UART_PIO_MODE GPIOA_MODE
- #define UART_PIO_AFL GPIOA_AFL
- #define UART_PIO_AFH GPIOA_AFH
- #define UART2_RX_PIN 3
- #define UART2_TX_PIN 2
- #else
- #define UART_PIO_MODE GPIOA_MODE
- #define UART_PIO_AFL GPIOA_AFL
- #define UART_PIO_AFH GPIOA_AFH
- #define UART2_RX_PIN 3
- #define UART2_TX_PIN 2
- #endif
- static const char chrTbl[] = "0123456789ABCDEF";
- uint8_t uartStr[UART_BUFFER_LEN] = {0u};
- uint8_t uartStrInd = 0u;
- static void uartExecCmd( uint8_t const * const cmd, uartControl_t * const ctrl );
- /* UART: PA2 (TX), PA3 (RX) */
- static void uart2_pins_setup(void)
- {
- uint32_t reg;
- /* Set mode = AF */
- reg = UART_PIO_MODE & ~ (0x03 << (UART2_RX_PIN * 2));
- UART_PIO_MODE = reg | (2 << (UART2_RX_PIN * 2));
- reg = UART_PIO_MODE & ~ (0x03 << (UART2_TX_PIN * 2));
- UART_PIO_MODE = reg | (2 << (UART2_TX_PIN * 2));
- /* Alternate function: use low pins (5 and 6) */
- #if (UART2_RX_PIN > 7)
- reg = UART_PIO_AFH & ~(0xf << ((UART2_RX_PIN - 8) * 4));
- UART_PIO_AFH = reg | (UART2_PIN_AF << ((UART2_RX_PIN - 8) * 4));
- #else
- reg = UART_PIO_AFL & ~(0xf << ((UART2_RX_PIN) * 4));
- UART_PIO_AFL = reg | (UART2_PIN_AF << ((UART2_RX_PIN) * 4));
- #endif
- #if (UART2_TX_PIN > 7)
- reg = UART_PIO_AFH & ~(0xf << ((UART2_TX_PIN - 8) * 4));
- UART_PIO_AFH = reg | (UART2_PIN_AF << ((UART2_TX_PIN - 8) * 4));
- #else
- reg = UART_PIO_AFL & ~(0xf << ((UART2_TX_PIN) * 4));
- UART_PIO_AFL = reg | (UART2_PIN_AF << ((UART2_TX_PIN) * 4));
- #endif
- }
- void uartInit( void )
- {
- uint32_t reg;
- const int data = 8;
- const char parity = 'N';
- const char stop = 1;
- const unsigned bitrate = 115200;
- uint8_t uartData;
- /* Enable pins and configure for AF7 */
- uart2_pins_setup();
- /* Turn on the device */
- APB1_CLOCK_ER |= UART2_APB1_CLOCK_ER_VAL;
- /* Configure for TX + RX */
- UART2_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE);
- /* Configure clock */
- UART2_BRR = CLOCK_SPEED / bitrate;
- /* Configure data bits */
- if (data == 8)
- UART2_CR1 &= ~UART_CR1_SYMBOL_LEN;
- else
- UART2_CR1 |= UART_CR1_SYMBOL_LEN;
- /* Configure parity */
- switch (parity) {
- case 'O':
- UART2_CR1 |= UART_CR1_PARITY_ODD;
- /* fall through to enable parity */
- /* fall through */
- case 'E':
- UART2_CR1 |= UART_CR1_PARITY_ENABLED;
- break;
- default:
- UART2_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
- }
- /* Set stop bits */
- reg = UART2_CR2 & ~UART_CR2_STOPBITS;
- if (stop > 1)
- UART2_CR2 = reg & (2 << 12);
- else
- UART2_CR2 = reg;
- /* Turn on uart */
- UART2_CR1 |= UART_CR1_UART_ENABLE;
- /* Flush UART buffers */
- uartData = UART2_DR;
- uartData = UART2_DR;
- uartData = UART2_DR;
- (void)uartData;
- return ;
- }
- static void uartExecCmd( uint8_t const * const cmd, uartControl_t * const ctrl )
- {
- uint8_t i = 1u;
- uint8_t c = 0u;
- uint32_t hConv = 0u;
- switch (cmd[0])
- {
- case 'a':
- case 'A':
- case 'l':
- case 'L':
- hConv = 0u;
- for (i = 1; i < (UART_BUFFER_LEN - 1u); ++i)
- {
- c = cmd[i];
- if ((c <= '9') && (c >= '0'))
- {
- c -= '0';
- }
- else if ((c >= 'a') && (c <= 'f'))
- {
- c -= 'a';
- c += 0x0A;
- }
- else if ((c >= 'A') && (c <= 'F'))
- {
- c -= 'A';
- c += 0x0A;
- }
- else
- {
- break;
- }
- hConv <<= 4u;
- hConv |= c;
- }
- if ((cmd[0] == 'a') || (cmd[0] == 'A'))
- {
- /* Enforce 32-bit alignment */
- while ((hConv & 0x00000003u) != 0x00u)
- {
- --hConv;
- }
- ctrl->readoutAddress = hConv;
- uartSendStr("Start address set to 0x");
- uartSendWordHexBE(hConv);
- uartSendStr("\r\n");
- }
- else /* l or L */
- {
- /* Enforce 32-bit alignment */
- while ((hConv & 0x00000003u) != 0x00u)
- {
- ++hConv;
- }
- ctrl->readoutLen = hConv;
- uartSendStr("Readout length set to 0x");
- uartSendWordHexBE(hConv);
- uartSendStr("\r\n");
- }
- break;
- case 'b':
- case 'B':
- ctrl->transmitHex = 0u;
- uartSendStr("Binary output mode selected\r\n");
- break;
- case 'e':
- ctrl->transmitLittleEndian = 1u;
- uartSendStr("Little Endian mode enabled\r\n");
- break;
- case 'E':
- ctrl->transmitLittleEndian = 0u;
- uartSendStr("Big Endian mode enabled\r\n");
- break;
- case 'h':
- case 'H':
- ctrl->transmitHex = 1u;
- uartSendStr("Hex output mode selected\r\n");
- break;
- case 'p':
- case 'P':
- printExtractionStatistics();
- break;
- case 's':
- case 'S':
- ctrl->active = 1u;
- uartSendStr("Flash readout started!\r\n");
- break;
- case '\n':
- case '\r':
- case '\0':
- /* ignore */
- break;
- default:
- uartSendStr("ERROR: unknown command\r\n");
- break;
- }
- }
- void uartReceiveCommands( uartControl_t * const ctrl )
- {
- uint8_t uartData = 0u;
- if (UART2_SR & UART_SR_RX_NOTEMPTY)
- {
- uartData = UART2_DR;
- switch (uartData)
- {
- /* ignore \t */
- case '\t':
- break;
- /* Accept \r and \n as command delimiter */
- case '\r':
- case '\n':
- /* Execute Command */
- uartExecCmd(uartStr, ctrl);
- uartStrInd = 0u;
- memset(uartStr, 0x00u, sizeof(uartStr));
- break;
- default:
- if (uartStrInd < (UART_BUFFER_LEN - 1u))
- {
- uartStr[uartStrInd] = uartData;
- ++uartStrInd;
- }
- break;
- }
- }
- return ;
- }
- void uartSendWordBin( uint32_t const val, uartControl_t const * const ctrl )
- {
- if (ctrl->transmitLittleEndian)
- {
- uartSendWordBinLE( val );
- }
- else
- {
- uartSendWordBinBE( val );
- }
- }
- void uartSendWordHex( uint32_t const val, uartControl_t const * const ctrl )
- {
- if (ctrl->transmitLittleEndian)
- {
- uartSendWordHexLE( val );
- }
- else
- {
- uartSendWordHexBE( val );
- }
- }
- void uartSendWordBinLE( uint32_t const val )
- {
- uint8_t i = 0u;
- uint32_t tval = val;
- for (i = 0u; i < 4u; ++i)
- {
- UART2_DR = tval & 0xFFu;
- tval >>= 8u;
- UART_WAIT_TRANSMIT;
- }
- return ;
- }
- void uartSendWordBinBE( uint32_t const val )
- {
- uint8_t i = 0u;
- uint32_t tval = val;
- for (i = 0u; i < 4u; ++i)
- {
- UART2_DR = ((tval >> ((3u - i) << 3u)) & 0xFFu);
- UART_WAIT_TRANSMIT;
- }
- return ;
- }
- void uartSendWordHexLE( uint32_t const val )
- {
- uint8_t i = 0u;
- uint32_t tval = val;
- for (i = 0u; i < 4u; ++i)
- {
- uartSendByteHex( tval & 0xFFu );
- tval >>= 8u;
- }
- return;
- }
- void uartSendWordHexBE( uint32_t const val )
- {
- uint8_t i = 0u;
- uint32_t tval = val;
- for (i = 0u; i < 4u; ++i)
- {
- uartSendByteHex((tval >> ((3u - i) << 3u)) & 0xFFu);
- UART_WAIT_TRANSMIT;
- }
- return ;
- }
- void uartSendByteHex( uint8_t const val )
- {
- char sendstr[3] = {0};
- sendstr[0] = chrTbl[(val >> 4u) & 0x0Fu];
- sendstr[1] = chrTbl[val & 0x0Fu];
- sendstr[2] = '\0';
- uartSendStr( sendstr );
- return ;
- }
- void uartSendStr( const char * const str )
- {
- const char * strptr = str;
- while (*strptr)
- {
- UART2_DR = *strptr;
- ++strptr;
- UART_WAIT_TRANSMIT;
- }
- return ;
- }
|