From 4532191da60454b12a060ee551990ad2a6046c69 Mon Sep 17 00:00:00 2001 From: RedHawk Date: Thu, 27 Apr 2023 13:45:45 +0300 Subject: [PATCH 1/3] LCD:[#22] rewritten delayMicroseconds(). * Now it uses timer peripheral with interrupt. * It sets interrupt to trigger after certain time and waits for it to clear the "interrupt pending" flag. --- source/shoh/src/peripherals/LiquidCrystal.cpp | 61 +++++++++++++++---- source/shoh/src/peripherals/LiquidCrystal.h | 9 --- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/source/shoh/src/peripherals/LiquidCrystal.cpp b/source/shoh/src/peripherals/LiquidCrystal.cpp index 6fe05ef..18d30c9 100644 --- a/source/shoh/src/peripherals/LiquidCrystal.cpp +++ b/source/shoh/src/peripherals/LiquidCrystal.cpp @@ -1,21 +1,62 @@ #include "LiquidCrystal.h" - -// Remove this when code will be reworked. -#ifndef LiquidCrystal_NOT_FIXED -// Remove this when code will be reworked. - - #include #include "chip.h" +#include "board.h" #define LOW 0 #define HIGH 1 +#define MHz1 1000000 +/** + * @brief Handle interrupt from 32-bit timer 0 + * @return Nothing + */ +void TIMER32_0_IRQHandler(void) +{ + if (Chip_TIMER_MatchPending(LPC_TIMER32_0, 1)) { + Chip_TIMER_ClearMatch(LPC_TIMER32_0, 1); + } +} -#if 0 +#if 1 void delayMicroseconds(unsigned int us) { - // implement with RIT + /* Initialize 32-bit timer 0 clock */ + Chip_TIMER_Init(LPC_TIMER32_0); + + /* Timer setup for match and interrupt at TICKRATE_HZ */ + Chip_TIMER_Reset(LPC_TIMER32_0); + + /* Enable timer to generate interrupt when time matches */ + Chip_TIMER_MatchEnableInt(LPC_TIMER32_0, 1); + + /* Setup 32-bit timer's duration (32-bit match time) */ + /* Once_per_microsecond * number_of_microseconds. */ + Chip_TIMER_SetMatch(LPC_TIMER32_0, 1, (Chip_Clock_GetSystemClockRate() / MHz1 * us)); + + /* Setup timer to stop when match occurs */ + Chip_TIMER_StopOnMatchEnable(LPC_TIMER32_0, 1); + + /* Start timer */ + Chip_TIMER_Enable(LPC_TIMER32_0); + + /* Clear timer of any pending interrupts */ + NVIC_ClearPendingIRQ(TIMER_32_0_IRQn); + + /* Enable timer interrupt */ + NVIC_EnableIRQ(TIMER_32_0_IRQn); + + /* Wait for the interrupt to trigger */ + while(Chip_TIMER_MatchPending(LPC_TIMER32_0, 1)); + + /*Disable the interrupt*/ + Chip_TIMER_MatchDisableInt(LPC_TIMER32_0, 1); + + /* Disable timer */ + Chip_TIMER_Disable(LPC_TIMER32_0); + + /* Deinitialise timer. */ + Chip_TIMER_DeInit(LPC_TIMER32_0); } #else void delayMicroseconds(uint32_t delay) @@ -291,7 +332,3 @@ void LiquidCrystal::write4bits(uint8_t value) { pulseEnable(); } - -// Remove this when code will be reworked. -#endif /* LiquidCrystal_NOT_FIXED */ -// Remove this when code will be reworked. diff --git a/source/shoh/src/peripherals/LiquidCrystal.h b/source/shoh/src/peripherals/LiquidCrystal.h index 546565e..6954c3a 100644 --- a/source/shoh/src/peripherals/LiquidCrystal.h +++ b/source/shoh/src/peripherals/LiquidCrystal.h @@ -1,11 +1,6 @@ #ifndef LiquidCrystal_h #define LiquidCrystal_h -// Remove this when code will be reworked. -#define LiquidCrystal_NOT_FIXED -#ifndef LiquidCrystal_NOT_FIXED -// Remove this when code will be reworked. - #include #include #include "chip.h" @@ -98,8 +93,4 @@ private: uint8_t _numlines,_currline; }; -// Remove this when code will be reworked. -#endif /* LiquidCrystal_NOT_FIXED */ -// Remove this when code will be reworked. - #endif /* LiquidCrystal_h */ From 6787f03f0a1c6e7c3dad056bc297b602f35b1cf9 Mon Sep 17 00:00:00 2001 From: RedHawk Date: Thu, 4 May 2023 15:46:32 +0300 Subject: [PATCH 2/3] LiquidCrystal.cpp: [#22] Fixed the interrupt. --- source/shoh/src/peripherals/LiquidCrystal.cpp | 63 ++++++++----------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/source/shoh/src/peripherals/LiquidCrystal.cpp b/source/shoh/src/peripherals/LiquidCrystal.cpp index 18d30c9..2b9b636 100644 --- a/source/shoh/src/peripherals/LiquidCrystal.cpp +++ b/source/shoh/src/peripherals/LiquidCrystal.cpp @@ -7,50 +7,58 @@ #define HIGH 1 #define MHz1 1000000 -/** - * @brief Handle interrupt from 32-bit timer 0 - * @return Nothing - */ -void TIMER32_0_IRQHandler(void) -{ - if (Chip_TIMER_MatchPending(LPC_TIMER32_0, 1)) { - Chip_TIMER_ClearMatch(LPC_TIMER32_0, 1); - } +static bool match_flag = false; + +extern "C" { + /** + * @brief Handle interrupt from 32-bit timer 0 + * Sets match_flag to true when the match occurs. + * @return Nothing + */ + void TIMER32_0_IRQHandler(void) + { + if(Chip_TIMER_MatchPending(LPC_TIMER32_0, 0)) { + Chip_TIMER_ClearMatch(LPC_TIMER32_0, 0); + match_flag = true; + } + } } -#if 1 void delayMicroseconds(unsigned int us) { + /* Reset match flag */ + match_flag = false; + /* Initialize 32-bit timer 0 clock */ - Chip_TIMER_Init(LPC_TIMER32_0); + Chip_TIMER_Init(LPC_TIMER32_0); /* Timer setup for match and interrupt at TICKRATE_HZ */ Chip_TIMER_Reset(LPC_TIMER32_0); /* Enable timer to generate interrupt when time matches */ - Chip_TIMER_MatchEnableInt(LPC_TIMER32_0, 1); + Chip_TIMER_MatchEnableInt(LPC_TIMER32_0, 0); /* Setup 32-bit timer's duration (32-bit match time) */ /* Once_per_microsecond * number_of_microseconds. */ - Chip_TIMER_SetMatch(LPC_TIMER32_0, 1, (Chip_Clock_GetSystemClockRate() / MHz1 * us)); + Chip_TIMER_SetMatch(LPC_TIMER32_0, 0, (Chip_Clock_GetSystemClockRate() / MHz1 * us)); /* Setup timer to stop when match occurs */ - Chip_TIMER_StopOnMatchEnable(LPC_TIMER32_0, 1); + Chip_TIMER_StopOnMatchEnable(LPC_TIMER32_0, 0); /* Start timer */ Chip_TIMER_Enable(LPC_TIMER32_0); /* Clear timer of any pending interrupts */ - NVIC_ClearPendingIRQ(TIMER_32_0_IRQn); + NVIC_ClearPendingIRQ(TIMER_32_0_IRQn); /* Enable timer interrupt */ - NVIC_EnableIRQ(TIMER_32_0_IRQn); + NVIC_EnableIRQ(TIMER_32_0_IRQn); /* Wait for the interrupt to trigger */ - while(Chip_TIMER_MatchPending(LPC_TIMER32_0, 1)); + while(!match_flag); /*Disable the interrupt*/ - Chip_TIMER_MatchDisableInt(LPC_TIMER32_0, 1); + Chip_TIMER_MatchDisableInt(LPC_TIMER32_0, 0); /* Disable timer */ Chip_TIMER_Disable(LPC_TIMER32_0); @@ -58,23 +66,6 @@ void delayMicroseconds(unsigned int us) /* Deinitialise timer. */ Chip_TIMER_DeInit(LPC_TIMER32_0); } -#else -void delayMicroseconds(uint32_t delay) -{ - static int init; - if(!init) { - // start core clock counter - CoreDebug->DEMCR |= 1 << 24; - DWT->CTRL |= 1; - init = 1; - } - - uint32_t start = DWT->CYCCNT; - delay = delay * 72; // assuming 72MHz clock - while(DWT->CYCCNT - start < delay); -} - -#endif // When the display powers up, it is configured as follows: // @@ -98,7 +89,7 @@ void delayMicroseconds(uint32_t delay) LiquidCrystal::LiquidCrystal(DigitalIoPin *rs, DigitalIoPin *enable, - DigitalIoPin *d0, DigitalIoPin *d1, DigitalIoPin *d2, DigitalIoPin *d3) + DigitalIoPin *d0, DigitalIoPin *d1, DigitalIoPin *d2, DigitalIoPin *d3) { rs_pin = rs; enable_pin = enable; From c421af2f8c17a174dc62672a959bbbe4d9d04398 Mon Sep 17 00:00:00 2001 From: RedHawk Date: Sat, 6 May 2023 13:38:46 +0300 Subject: [PATCH 3/3] main.cpp: [#22] Example LCD code. *Checked it - works like a charm. --- source/shoh/src/main.cpp | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/source/shoh/src/main.cpp b/source/shoh/src/main.cpp index 0b1f6bc..d374f52 100644 --- a/source/shoh/src/main.cpp +++ b/source/shoh/src/main.cpp @@ -7,6 +7,9 @@ #include "Master.h" #include "Rotary.h" #include "retarget_uart.h" +#include "LiquidCrystal.h" + +void lcd_starting(); int main(void) { @@ -16,6 +19,8 @@ int main(void) retarget_init(); printf("Hello there!\r\n"); + + lcd_starting(); ThreadCommon::ThreadManager* manager = new ThreadCommon::ThreadManager; ThreadCommon::QueueManager* qmanager = new ThreadCommon::QueueManager; @@ -36,3 +41,44 @@ int main(void) return 1; } + +/** + * @brief While we don't have UI, this should do for LCD. + * + */ +void lcd_starting() { + // LCD pins init. + //Well, this lpc is a bit different with those. Table 83 from UM10732-11u68.pdf + DigitalIoPin *rs = new DigitalIoPin(1, 9, false); + Chip_IOCON_PinMuxSet (LPC_IOCON, 1, 9, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + DigitalIoPin *en = new DigitalIoPin(0, 14, false); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 14, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + DigitalIoPin *d4 = new DigitalIoPin(0, 13, false); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 13, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + DigitalIoPin *d5 = new DigitalIoPin(0, 12, false); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 12, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + DigitalIoPin *d6 = new DigitalIoPin(0, 23, false); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 23, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + DigitalIoPin *d7 = new DigitalIoPin(0, 11, false); + Chip_IOCON_PinMuxSet (LPC_IOCON, 0, 11, (IOCON_FUNC1 | IOCON_MODE_INACT | IOCON_DIGMODE_EN)); + + rs->write(false); + en->write(false); + d4->write(false); + d5->write(false); + d6->write(false); + d7->write(false); + // LCD init. + LiquidCrystal *lcd = new LiquidCrystal(rs, en, d4, d5, d6, d7); + // LCD configure display geometry. + lcd->begin(16, 2); + lcd->setCursor (0, 0); + lcd->print("Hello there"); + lcd->setCursor (0, 1); + lcd->print("Starting..."); +}