diff --git a/source/shoh/src/Fmutex.cpp b/source/shoh/src/Fmutex.cpp new file mode 100644 index 0000000..de725e8 --- /dev/null +++ b/source/shoh/src/Fmutex.cpp @@ -0,0 +1,28 @@ +/* + * Fmutex.cpp + * + * Created on: 15.8.2017 + * Author: krl + */ + +#include "Fmutex.h" + +Fmutex::Fmutex() { + // TODO Auto-generated constructor stub + mutex = xSemaphoreCreateMutex(); +} + +Fmutex::~Fmutex() { + // TODO Auto-generated destructor stub + vSemaphoreDelete(mutex); +} + +void Fmutex::lock() +{ + xSemaphoreTake(mutex, portMAX_DELAY); +} + +void Fmutex::unlock() +{ + xSemaphoreGive(mutex); +} diff --git a/source/shoh/src/Fmutex.h b/source/shoh/src/Fmutex.h new file mode 100644 index 0000000..94563c7 --- /dev/null +++ b/source/shoh/src/Fmutex.h @@ -0,0 +1,24 @@ +/* + * Fmutex.h + * + * Created on: 15.8.2017 + * Author: krl + */ + +#ifndef FMUTEX_H_ +#define FMUTEX_H_ + +#include "FreeRTOS.h" +#include "semphr.h" + +class Fmutex { +public: + Fmutex(); + virtual ~Fmutex(); + void lock(); + void unlock(); +private: + SemaphoreHandle_t mutex; +}; + +#endif /* FMUTEX_H_ */ diff --git a/source/shoh/src/main.cpp b/source/shoh/src/main.cpp index 91d24cd..0b1f6bc 100644 --- a/source/shoh/src/main.cpp +++ b/source/shoh/src/main.cpp @@ -6,12 +6,17 @@ #include "ThreadCommon.h" #include "Master.h" #include "Rotary.h" - +#include "retarget_uart.h" int main(void) { SystemCoreClockUpdate(); Board_Init(); + + retarget_init(); + + printf("Hello there!\r\n"); + ThreadCommon::ThreadManager* manager = new ThreadCommon::ThreadManager; ThreadCommon::QueueManager* qmanager = new ThreadCommon::QueueManager; //Creating queues diff --git a/source/shoh/src/peripherals/LpcDebugUart.cpp b/source/shoh/src/peripherals/LpcDebugUart.cpp new file mode 100644 index 0000000..f47c8a8 --- /dev/null +++ b/source/shoh/src/peripherals/LpcDebugUart.cpp @@ -0,0 +1,228 @@ +/* + * LpcDebugUart.cpp + * + * Created on: 6.5.2023 + */ + +#include +#include +#include "LpcDebugUart.h" + +/* shoh: Important differences + * We don't have movable pins -> not needed. + * + * USART0 (the only debug uart): + * Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 18, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + * Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 19, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + */ + +static LpcDebugUart *u0; + +extern "C" { +/** + * @brief UART interrupt handler using ring buffers + * @return Nothing + */ +void USART0_IRQHandler(void) +{ + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + if(u0) { + u0->isr(&xHigherPriorityTaskWoken); + } + + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); +} + +} + + +void LpcDebugUart::isr(portBASE_TYPE *hpw) { + // get interrupt status for notifications + uint32_t istat = Chip_UART0_ReadLineStatus(uart); + + // chip library is used to handle receive and transmit + Chip_UART0_IRQRBHandler(uart, &rxring, &txring); + + // notify (hopefully) of the events handled + if(notify_rx && (istat & UART0_LSR_RDR) ) vTaskNotifyGiveFromISR(notify_rx, hpw); + if(notify_tx && (istat & UART0_LSR_THRE) ) vTaskNotifyGiveFromISR(notify_tx, hpw); + if(on_receive && (istat & UART0_LSR_RDR) ) on_receive(); +} + +LpcDebugUart::LpcDebugUart(const LpcDebugUartConfig &cfg) { + uart = nullptr; // set default value before checking which UART to configure + + if(cfg.pUART == LPC_USART0) { + if(u0) return; // already exists + else u0 = this; + irqn = USART0_IRQn; + } + else { + return; + } + + uart = cfg.pUART; // set the actual value after validity checking + + + if(cfg.tx.port >= 0) { + Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.tx.port, cfg.tx.pin, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + } + + if(cfg.rx.port >= 0) { + Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.rx.port, cfg.rx.pin, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + } + + notify_rx = nullptr; + notify_tx = nullptr; + on_receive = nullptr; + /* Setup UART */ + Chip_UART0_Init(uart); + Chip_UART0_SetBaud(LPC_USART0, cfg.speed); + Chip_UART0_ConfigData(LPC_USART0, cfg.data); + Chip_UART0_SetupFIFOS(LPC_USART0, (UART0_FCR_FIFO_EN | UART0_FCR_TRG_LEV2)); + Chip_UART0_TXEnable(uart); + + /* Before using the ring buffers, initialize them using the ring + buffer init function */ + RingBuffer_Init(&rxring, rxbuff, 1, UART_RB_SIZE); + RingBuffer_Init(&txring, txbuff, 1, UART_RB_SIZE); + + + /* Enable receive data and line status interrupt */ + Chip_UART0_IntEnable(uart, UART0_IER_RBRINT | UART0_IER_RLSINT); + + NVIC_SetPriority(irqn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); + /* Enable UART interrupt */ + NVIC_EnableIRQ(irqn); +} + +LpcDebugUart::~LpcDebugUart() { + if(uart != nullptr) { + NVIC_DisableIRQ(irqn); + Chip_UART0_IntDisable(uart, UART0_IER_RBRINT | UART0_IER_RLSINT); + + if(uart == LPC_USART0) { + u0 = nullptr; + } + } +} + +void LpcDebugUart::set_on_receive(void(*cb)(void)) +{ + on_receive = cb; +} + + +int LpcDebugUart::free() +{ + std::lock_guard lock(write_mutex); + + return UART_RB_SIZE - RingBuffer_GetCount(&txring); +} + +int LpcDebugUart::peek() +{ + std::lock_guard lock(read_mutex); + + return RingBuffer_GetCount(&rxring); +} + +int LpcDebugUart::read(char &c) +{ + return read(&c, 1); +} + +int LpcDebugUart::read(char *buffer, int len) +{ + std::lock_guard lock(read_mutex); + + if(RingBuffer_GetCount(&rxring) <= 0) { + notify_rx = xTaskGetCurrentTaskHandle(); + while(RingBuffer_GetCount(&rxring) <= 0) { + ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); + } + notify_rx = nullptr; + } + + return Chip_UART0_ReadRB(uart, &rxring, buffer, len); +} + + +int LpcDebugUart::read(char *buffer, int len, TickType_t total_timeout, TickType_t ic_timeout) +{ + std::lock_guard lock(read_mutex); + + // we can't read more than ring buffer size at a time + if(len > UART_RB_SIZE) len = UART_RB_SIZE; + + TimeOut_t timeoutState; + vTaskSetTimeOutState(&timeoutState); + + notify_rx = xTaskGetCurrentTaskHandle(); + while(RingBuffer_GetCount(&rxring) < len && xTaskCheckForTimeOut(&timeoutState, &total_timeout) == pdFALSE) { + TickType_t timeout = total_timeout > ic_timeout ? ic_timeout : total_timeout; + if(ulTaskNotifyTake( pdTRUE, timeout ) == 0) break; + } + notify_rx = nullptr; + + return Chip_UART0_ReadRB(uart, &rxring, buffer, len);; +} + +int LpcDebugUart::write(char c) +{ + return write(&c, 1); +} + +int LpcDebugUart::write(const char *s) +{ + return write(s, strlen(s)); +} + +int LpcDebugUart::write(const char *buffer, int len) +{ + std::lock_guard lock(write_mutex); + + int pos = 0; + notify_tx = xTaskGetCurrentTaskHandle(); + + while(len > pos) { + // restrict single write to ring buffer size + int size = (len - pos) > UART_RB_SIZE ? UART_RB_SIZE : (len - pos); + + // wait until we have space in the ring buffer + while(UART_RB_SIZE - RingBuffer_GetCount(&txring) < size) { + ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); + } + pos += Chip_UART0_SendRB(uart, &txring, buffer+pos, size); + } + notify_tx = nullptr; + + return pos; +} + +void LpcDebugUart::txbreak(bool brk) +{ + // break handling not implemented yet +} + +bool LpcDebugUart::rxbreak() +{ + // break handling not implemented yet + return false; +} + +void LpcDebugUart::speed(int bps) +{ + std::lock_guard lockw(write_mutex); + std::lock_guard lockr(read_mutex); + + Chip_UART0_SetBaud(uart, bps); +} + +bool LpcDebugUart::txempty() +{ + std::lock_guard lock(write_mutex); + + return (RingBuffer_GetCount(&txring) == 0); +} diff --git a/source/shoh/src/peripherals/LpcDebugUart.h b/source/shoh/src/peripherals/LpcDebugUart.h new file mode 100644 index 0000000..16c05e8 --- /dev/null +++ b/source/shoh/src/peripherals/LpcDebugUart.h @@ -0,0 +1,63 @@ +/* + * LpcDebugUart.h + * + * Created on: 6.5.2023 + */ + +#ifndef LPCDEBUGUART_H_ +#define LPCDEBUGUART_H_ + +#include "chip.h" +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "Fmutex.h" +#include "LpcUart.h" + +struct LpcDebugUartConfig { + LPC_USART0_T *pUART; + uint32_t speed; + uint32_t data; + LpcPinMap tx; + LpcPinMap rx; +}; + + +class LpcDebugUart { +public: + LpcDebugUart(const LpcDebugUartConfig &cfg); + LpcDebugUart(const LpcDebugUart &) = delete; + virtual ~LpcDebugUart(); + int free(); /* get amount of free space in transmit buffer */ + int peek(); /* get number of received characters in receive buffer */ + int write(char c); + int write(const char *s); + int write(const char *buffer, int len); + int read(char &c); /* get a single character. Returns number of characters read --> returns 0 if no character is available */ + int read(char *buffer, int len); + int read(char *buffer, int len, TickType_t total_timeout, TickType_t ic_timeout = portMAX_DELAY); + void txbreak(bool brk); /* set break signal on */ + bool rxbreak(); /* check if break is received */ + void speed(int bps); /* change transmission speed */ + bool txempty(); + void set_on_receive(void(*cb)(void)); + + void isr(portBASE_TYPE *hpw); /* ISR handler. This will be called by the HW ISR handler. Do not call from application */ +private: + LPC_USART0_T *uart; + IRQn_Type irqn; + /* currently we support only fixed size ring buffers */ + static const int UART_RB_SIZE = 128; + /* Transmit and receive ring buffers */ + RINGBUFF_T txring; + RINGBUFF_T rxring; + uint8_t rxbuff[UART_RB_SIZE]; + uint8_t txbuff[UART_RB_SIZE]; + TaskHandle_t notify_rx; + TaskHandle_t notify_tx; + void (*on_receive)(void); // callback for received data notifications + Fmutex read_mutex; + Fmutex write_mutex; +}; + +#endif /* LPCUART_H_ */ diff --git a/source/shoh/src/peripherals/LpcUart.cpp b/source/shoh/src/peripherals/LpcUart.cpp index 7e4e08d..7cbc985 100644 --- a/source/shoh/src/peripherals/LpcUart.cpp +++ b/source/shoh/src/peripherals/LpcUart.cpp @@ -9,32 +9,31 @@ #include #include "LpcUart.h" -// Remove this when code will be reworked. -#ifndef LPCUART_NOT_FIXED -// Remove this when code will be reworked. +/* shoh: Important differences + * We don't have movable pins -> not needed. + * + * Muxing is like this: + * Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 14, (IOCON_FUNC4 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + * Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 13, (IOCON_FUNC4 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + * + * USART0 (the only debug uart): + * Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 18, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + * Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 19, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + */ - -static LpcUart *u0; static LpcUart *u1; static LpcUart *u2; +static LpcUart *u3; +static LpcUart *u4; extern "C" { /** * @brief UART interrupt handler using ring buffers + * @par shoh: Unlike in lpc15xx, lpc11u68 has shared interrupts for 1 and 4, 2 and 3. + * shoh: Not sure how exactly it should be handled. UART0 is completely different compared to 1-4. * @return Nothing */ -void UART0_IRQHandler(void) -{ - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - - if(u0) { - u0->isr(&xHigherPriorityTaskWoken); - } - - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); -} - -void UART1_IRQHandler(void) +void USART1_4_IRQHandler(void) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; @@ -42,10 +41,14 @@ void UART1_IRQHandler(void) u1->isr(&xHigherPriorityTaskWoken); } + if(u4) { + u4->isr(&xHigherPriorityTaskWoken); + } + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } -void UART2_IRQHandler(void) +void USART2_3_IRQHandler(void) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; @@ -53,6 +56,10 @@ void UART2_IRQHandler(void) u2->isr(&xHigherPriorityTaskWoken); } + if(u3) { + u3->isr(&xHigherPriorityTaskWoken); + } + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } @@ -61,26 +68,23 @@ void UART2_IRQHandler(void) void LpcUart::isr(portBASE_TYPE *hpw) { // get interrupt status for notifications - uint32_t istat = Chip_UART_GetIntStatus(uart); + uint32_t istat = Chip_UARTN_GetIntStatus(uart); // chip library is used to handle receive and transmit - Chip_UART_IRQRBHandler(uart, &rxring, &txring); + Chip_UARTN_IRQRBHandler(uart, &rxring, &txring); // notify of the events handled - if(notify_rx && (istat & UART_STAT_RXRDY) ) vTaskNotifyGiveFromISR(notify_rx, hpw); - if(notify_tx && (istat & UART_STAT_TXRDY) ) vTaskNotifyGiveFromISR(notify_tx, hpw); - if(on_receive && (istat & UART_STAT_RXRDY) ) on_receive(); + if(notify_rx && (istat & UARTN_STAT_RXRDY) ) vTaskNotifyGiveFromISR(notify_rx, hpw); + if(notify_tx && (istat & UARTN_STAT_TXRDY) ) vTaskNotifyGiveFromISR(notify_tx, hpw); + if(on_receive && (istat & UARTN_STAT_RXRDY) ) on_receive(); } bool LpcUart::init = false; LpcUart::LpcUart(const LpcUartConfig &cfg) { - CHIP_SWM_PIN_MOVABLE_T tx; - CHIP_SWM_PIN_MOVABLE_T rx; - CHIP_SWM_PIN_MOVABLE_T cts; - CHIP_SWM_PIN_MOVABLE_T rts; - bool use_rts = (cfg.rts.port >= 0); - bool use_cts = (cfg.cts.port >= 0); + //shoh: removed handshakes and movable pins. + bool use_rts = false; //(cfg.rts.port >= 0); + bool use_cts = false; //(cfg.cts.port >= 0); if(!init) { init = true; @@ -90,37 +94,30 @@ LpcUart::LpcUart(const LpcUartConfig &cfg) { * UARTs. * */ /* Use main clock rate as base for UART baud rate divider */ - Chip_Clock_SetUARTBaseClockRate(Chip_Clock_GetMainClockRate(), false); + Chip_Clock_SetUSARTNBaseClockRate(Chip_Clock_GetMainClockRate(), false); //(115200 * 256), false); } uart = nullptr; // set default value before checking which UART to configure - if(cfg.pUART == LPC_USART0) { - if(u0) return; // already exists - else u0 = this; - tx = SWM_UART0_TXD_O; - rx = SWM_UART0_RXD_I; - rts = SWM_UART0_RTS_O; - cts = SWM_UART0_CTS_I; - irqn = UART0_IRQn; - } - else if(cfg.pUART == LPC_USART1) { + if(cfg.pUART == LPC_USART1) { if(u1) return; // already exists else u1 = this; - tx = SWM_UART1_TXD_O; - rx = SWM_UART1_RXD_I; - rts = SWM_UART1_RTS_O; - cts = SWM_UART1_CTS_I; - irqn = UART1_IRQn; + irqn = USART1_4_IRQn; //Shares interrupt with 4 } else if(cfg.pUART == LPC_USART2) { if(u2) return; // already exists else u2 = this; - tx = SWM_UART2_TXD_O; - rx = SWM_UART2_RXD_I; - use_rts = false; // UART2 does not support handshakes - use_cts = false; - irqn = UART2_IRQn; + irqn = USART2_3_IRQn; //Shares interrupt with 3 + } + else if(cfg.pUART == LPC_USART3) { + if(u3) return; // already exists + else u3 = this; + irqn = USART2_3_IRQn; + } + else if(cfg.pUART == LPC_USART4) { + if(u4) return; // already exists + else u4 = this; + irqn = USART1_4_IRQn; } else { return; @@ -130,32 +127,28 @@ LpcUart::LpcUart(const LpcUartConfig &cfg) { if(cfg.tx.port >= 0) { - Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.tx.port, cfg.tx.pin, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_SWM_MovablePortPinAssign(tx, cfg.tx.port, cfg.tx.pin); + Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.tx.port, cfg.tx.pin, (IOCON_FUNC4 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); } if(cfg.rx.port >= 0) { - Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.rx.port, cfg.rx.pin, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_SWM_MovablePortPinAssign(rx, cfg.rx.port, cfg.rx.pin); + Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.rx.port, cfg.rx.pin, (IOCON_FUNC4 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); } if(use_cts) { - Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.cts.port, cfg.cts.pin, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_SWM_MovablePortPinAssign(cts, cfg.cts.port, cfg.cts.pin); + Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.cts.port, cfg.cts.pin, (IOCON_FUNC4 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); } if(use_rts) { - Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.rts.port, cfg.rts.pin, (IOCON_MODE_INACT | IOCON_DIGMODE_EN)); - Chip_SWM_MovablePortPinAssign(rts, cfg.rts.port, cfg.rts.pin); + Chip_IOCON_PinMuxSet(LPC_IOCON, cfg.rts.port, cfg.rts.pin, (IOCON_FUNC4 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); } notify_rx = nullptr; notify_tx = nullptr; on_receive = nullptr; /* Setup UART */ - Chip_UART_Init(uart); - Chip_UART_ConfigData(uart, cfg.data); - Chip_UART_SetBaud(uart, cfg.speed); + Chip_UARTN_Init(uart); + Chip_UARTN_ConfigData(uart, cfg.data); + Chip_UARTN_SetBaud(uart, cfg.speed); if(use_rts && cfg.rs485) { uart->CFG |= (1 << 20); // enable rs485 mode @@ -163,8 +156,8 @@ LpcUart::LpcUart(const LpcUartConfig &cfg) { uart->CFG |= (1 << 21);// driver enable polarity (active high) } - Chip_UART_Enable(uart); - Chip_UART_TXEnable(uart); + Chip_UARTN_Enable(uart); + Chip_UARTN_TXEnable(uart); /* Before using the ring buffers, initialize them using the ring buffer init function */ @@ -173,8 +166,8 @@ LpcUart::LpcUart(const LpcUartConfig &cfg) { /* Enable receive data and line status interrupt */ - Chip_UART_IntEnable(uart, UART_INTEN_RXRDY); - Chip_UART_IntDisable(uart, UART_INTEN_TXRDY); /* May not be needed */ + Chip_UARTN_IntEnable(uart, UARTN_INTEN_RXRDY); + Chip_UARTN_IntDisable(uart, UARTN_INTEN_TXRDY); /* May not be needed */ NVIC_SetPriority(irqn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); /* Enable UART interrupt */ @@ -184,18 +177,21 @@ LpcUart::LpcUart(const LpcUartConfig &cfg) { LpcUart::~LpcUart() { if(uart != nullptr) { NVIC_DisableIRQ(irqn); - Chip_UART_IntDisable(uart, UART_INTEN_RXRDY); - Chip_UART_IntDisable(uart, UART_INTEN_TXRDY); + Chip_UARTN_IntDisable(uart, UARTN_INTEN_RXRDY); + Chip_UARTN_IntDisable(uart, UARTN_INTEN_TXRDY); - if(uart == LPC_USART0) { - u0 = nullptr; - } - else if(uart == LPC_USART1) { + if(uart == LPC_USART1) { u1 = nullptr; } else if(uart == LPC_USART2) { u2 = nullptr; } + else if(uart == LPC_USART3) { + u3 = nullptr; + } + else if(uart == LPC_USART4) { + u4 = nullptr; + } } } @@ -236,7 +232,7 @@ int LpcUart::read(char *buffer, int len) notify_rx = nullptr; } - return Chip_UART_ReadRB(uart, &rxring, buffer, len); + return Chip_UARTN_ReadRB(uart, &rxring, buffer, len); } @@ -257,7 +253,7 @@ int LpcUart::read(char *buffer, int len, TickType_t total_timeout, TickType_t i } notify_rx = nullptr; - return Chip_UART_ReadRB(uart, &rxring, buffer, len);; + return Chip_UARTN_ReadRB(uart, &rxring, buffer, len);; } int LpcUart::write(char c) @@ -285,7 +281,7 @@ int LpcUart::write(const char *buffer, int len) while(UART_RB_SIZE - RingBuffer_GetCount(&txring) < size) { ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); } - pos += Chip_UART_SendRB(uart, &txring, buffer+pos, size); + pos += Chip_UARTN_SendRB(uart, &txring, buffer+pos, size); } notify_tx = nullptr; @@ -308,7 +304,7 @@ void LpcUart::speed(int bps) std::lock_guard lockw(write_mutex); std::lock_guard lockr(read_mutex); - Chip_UART_SetBaud(uart, bps); + Chip_UARTN_SetBaud(uart, bps); } bool LpcUart::txempty() @@ -317,7 +313,3 @@ bool LpcUart::txempty() return (RingBuffer_GetCount(&txring) == 0); } - -// Remove this when code will be reworked. -#endif /* LPCUART_NOT_FIXED */ -// Remove this when code will be reworked. diff --git a/source/shoh/src/peripherals/LpcUart.h b/source/shoh/src/peripherals/LpcUart.h index 38a88ac..81df701 100644 --- a/source/shoh/src/peripherals/LpcUart.h +++ b/source/shoh/src/peripherals/LpcUart.h @@ -8,12 +8,6 @@ #ifndef LPCUART_H_ #define LPCUART_H_ -// Remove this when code will be reworked. -#define LPCUART_NOT_FIXED -#ifndef LPCUART_NOT_FIXED -// Remove this when code will be reworked. - - #include "chip.h" #include "FreeRTOS.h" #include "task.h" @@ -26,13 +20,13 @@ struct LpcPinMap { }; struct LpcUartConfig { - LPC_USART_T *pUART; + LPC_USARTN_T *pUART; uint32_t speed; uint32_t data; bool rs485; LpcPinMap tx; LpcPinMap rx; - LpcPinMap rts; /* used as output enable if RS-485 mode is enabled */ + LpcPinMap rts; /* used as output enable if RS-485 mode is enabled */ //shoh: Psst. Actually, not used anywhere. LpcPinMap cts; }; @@ -58,7 +52,7 @@ public: void isr(portBASE_TYPE *hpw); /* ISR handler. This will be called by the HW ISR handler. Do not call from application */ private: - LPC_USART_T *uart; + LPC_USARTN_T *uart; IRQn_Type irqn; /* currently we support only fixed size ring buffers */ static const int UART_RB_SIZE = 128; @@ -75,8 +69,4 @@ private: Fmutex write_mutex; }; -// Remove this when code will be reworked. -#endif /* LPCUART_NOT_FIXED */ -// Remove this when code will be reworked. - #endif /* LPCUART_H_ */ diff --git a/source/shoh/src/peripherals/retarget_uart.cpp b/source/shoh/src/peripherals/retarget_uart.cpp new file mode 100644 index 0000000..f30510d --- /dev/null +++ b/source/shoh/src/peripherals/retarget_uart.cpp @@ -0,0 +1,91 @@ +/* + * retarget_uart.cpp + * + * Created on: 28.9.2021 + * Author: keijo + */ + +#include "LpcDebugUart.h" + +static LpcDebugUart *dbgu; + +void retarget_init() +{ + LpcPinMap none = {-1, -1}; // unused pin has negative values in it + //Sadly, it seems that only USART0 is redirected to USB. + //It means that those are pins PIO0_18 and PIO0_19 + LpcPinMap txpin = { 0, 19 }; // transmit pin that goes to debugger's UART->USB converter + LpcPinMap rxpin = { 0, 18 }; // receive pin that goes to debugger's UART->USB converter + LpcDebugUartConfig cfg = { LPC_USART0, 115200, (UART0_LCR_WLEN8 | UART0_LCR_SBS_1BIT), txpin, rxpin }; + dbgu = new LpcDebugUart(cfg); +} + +extern "C" { + +// ****************************************************************** +// Redlib C Library function : __sys_write +// Newlib C library function : _write +// +// Function called by bottom level of printf routine within C library. +// With the default semihosting stub, this would write the +// character(s) to the debugger console window (which acts as +// stdout). But this version writes the character(s) to UART +// ****************************************************************** +#if defined (__REDLIB__) +int __sys_write(int iFileHandle, char *pcBuffer, int iLength) { +#elif defined (__NEWLIB__) +int _write(int iFileHandle, char *pcBuffer, int iLength) { +#endif + if(dbgu) { + int len = iLength; + while(len > 0) { + if(*pcBuffer == '\n') { // send a CR before every LF + while(dbgu->write('\r')==0); + } + while(dbgu->write(*pcBuffer)==0); + ++pcBuffer; + --len; + } + } + // Function returns number of bytes written + return iLength; +} + +#if defined (__REDLIB__) +// ****************************************************************** +// Redlib C Library function : __sys_readc +// +// Called by bottom level of scanf routine within RedLib C library +// to read a character. With the default semihosting stub, this +// would read the character from the debugger console window (which +// acts as stdin). But this version reads the character from UART +// ****************************************************************** + +int __sys_readc(void) { + char c; + if(dbgu && dbgu->read(c)) return c; + else return -1; + +} +// #endif REDLIB __sys_readc() + +#elif defined (__NEWLIB__) +// ****************************************************************** +// Function _read +// +// Called by bottom level of scanf routine within Newlib C library +// to read multiple characters. With the default semihosting stub, this +// would read characters from the debugger console window (which +// acts as stdin). But this version reads the characters from UART +// ****************************************************************** +int _read(int iFileHandle, char *pcBuffer, int iLength) { + + // TODO : Should potentially check that iFileHandle == 0 to confirm + // that read is from stdin + if(!dbgu) return 0; + return dbgu->read(pcBuffer, iLength); +} + +#endif // NEWLIB _read() + +} diff --git a/source/shoh/src/peripherals/retarget_uart.h b/source/shoh/src/peripherals/retarget_uart.h new file mode 100644 index 0000000..886a807 --- /dev/null +++ b/source/shoh/src/peripherals/retarget_uart.h @@ -0,0 +1,14 @@ +/* + * retarget_uart.h + * + * Created on: 28.9.2021 + * Author: keijo + */ + +#ifndef RETARGET_UART_H_ +#define RETARGET_UART_H_ + +void retarget_init(); + + +#endif /* RETARGET_UART_H_ */ diff --git a/source/shoh/src/threads/master/Master.cpp b/source/shoh/src/threads/master/Master.cpp index 2a7e094..c7cea1c 100644 --- a/source/shoh/src/threads/master/Master.cpp +++ b/source/shoh/src/threads/master/Master.cpp @@ -21,15 +21,19 @@ void Master::taskFunction() { { case ThreadCommon::RotaryAction::Right: Board_LED_Set(ThreadCommon::RotaryAction::Right, LedState); + printf("Right\r\n"); break; case ThreadCommon::RotaryAction::Left: Board_LED_Set(ThreadCommon::RotaryAction::Left, LedState); + printf("Left\r\n"); break; case ThreadCommon::RotaryAction::Press: Board_LED_Set(ThreadCommon::RotaryAction::Press, LedState); + printf("Press\r\n"); break; case ThreadCommon::RotaryAction::Idle: Board_LED_Set(ThreadCommon::RotaryAction::Right, LedState); + printf("Idle\r\n"); break; } LedState = !LedState;