diff --git a/CMakeLists.txt b/CMakeLists.txt index 362656f..067f307 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-volatile") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-volatile -fmodules-ts") # Initialise pico_sdk from installed location # (note this can come from environment, CMake cache etc) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bdddc2f..6e2e75a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,12 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) +#add_compile_options(-fmodules-ts) + set(SOURCES - gbmanager.cpp lcd.cpp relais.cpp + gbmanager.cpp ) # Add executable. Default name is the project name, version 0.1 diff --git a/src/gbmanager.cpp b/src/gbmanager.cpp index a932d61..5ae7a7d 100644 --- a/src/gbmanager.cpp +++ b/src/gbmanager.cpp @@ -5,8 +5,10 @@ #include "pico/stdlib.h" #include "config.h" -#include "lcd.h" -#include "relais.h" +//#include "lcd.h" + +import lcd; +import relais; // GPIOs used constexpr uint I2C_SDA_PIN = 26; @@ -28,7 +30,7 @@ absolute_time_t lastPressed = get_absolute_time(); using std::string; -void buttonPressedCallback(uint gpio, uint32_t events) { +void buttonPressedCallback(uint gpio, [[maybe_unused]] uint32_t events) { absolute_time_t now = get_absolute_time(); if (absolute_time_diff_us(lastPressed, now) < 750000) { return; @@ -54,7 +56,7 @@ int main() { stdio_init_all(); // Initialize the LCD - auto myLCD = LCD(i2c1, I2C_SDA_PIN, I2C_SCL_PIN); + auto myLCD = LCD(i2c1, I2C_SDA_PIN, I2C_SCL_PIN, 16, 2); myLCD.clear(); // Initialize the temp sensor diff --git a/src/lcd.cpp b/src/lcd.cpp index 52c512e..c8cf230 100644 --- a/src/lcd.cpp +++ b/src/lcd.cpp @@ -1,6 +1,12 @@ -#include "pico/binary_info.h" +module; -#include "lcd.h" +#include + +#include "hardware/i2c.h" +#include "pico/binary_info.h" +#include "pico/stdlib.h" + +export module lcd; // commands constexpr int LCD_CLEARDISPLAY = 0x01; @@ -29,74 +35,90 @@ constexpr int LCD_8BITMODE = 0x10; constexpr int LCD_BACKLIGHT = 0x08; constexpr int LCD_ENABLE_BIT = 0x04; -LCD::LCD(i2c_inst_t *i2c, const uint gpio_sda, const uint gpio_scl, - const uint8_t i2c_addr, uint8_t num_cols, uint8_t num_lines) - : i2c{i2c}, i2c_addr{i2c_addr}, num_cols{num_cols}, num_lines{num_lines} { - i2c_init(i2c, 400 * 1000); - gpio_set_function(gpio_sda, GPIO_FUNC_I2C); - gpio_set_function(gpio_scl, GPIO_FUNC_I2C); - gpio_pull_up(gpio_sda); - gpio_pull_up(gpio_scl); - // Make the I2C pins available to picotool - bi_decl(bi_2pins_with_func(gpio_sda, gpio_scl, GPIO_FUNC_I2C)); +enum class Mode { COMMAND, CHARACTER }; - sendByte(0x03, Mode::COMMAND); - sendByte(0x03, Mode::COMMAND); - sendByte(0x03, Mode::COMMAND); - sendByte(0x02, Mode::COMMAND); +export class LCD { + public: + LCD(i2c_inst_t *i2c, const uint gpio_sda, const uint gpio_scl, + const uint8_t i2c_addr, const uint8_t num_cols = 16, + const uint8_t num_lines = 2) + : i2c{i2c}, i2c_addr{i2c_addr}, num_cols{num_cols}, num_lines{ + num_lines} { + i2c_init(i2c, 400 * 1000); + gpio_set_function(gpio_sda, GPIO_FUNC_I2C); + gpio_set_function(gpio_scl, GPIO_FUNC_I2C); + gpio_pull_up(gpio_sda); + gpio_pull_up(gpio_scl); + // Make the I2C pins available to picotool + bi_decl(bi_2pins_with_func(gpio_sda, gpio_scl, GPIO_FUNC_I2C)); - sendByte(LCD_ENTRYMODESET | LCD_ENTRYLEFT, Mode::COMMAND); - sendByte(LCD_FUNCTIONSET | LCD_2LINE, Mode::COMMAND); - sendByte(LCD_DISPLAYCONTROL | LCD_DISPLAYON, Mode::COMMAND); - clear(); -} + sendByte(0x03, Mode::COMMAND); + sendByte(0x03, Mode::COMMAND); + sendByte(0x03, Mode::COMMAND); + sendByte(0x02, Mode::COMMAND); -// Go to location on LCD -void LCD::setCursor(int line, int position) { - int val = (line == 0) ? 0x80 + position : 0xC0 + position; - sendByte(val, Mode::COMMAND); - cursor_x = line; - cursor_y = position; -} + sendByte(LCD_ENTRYMODESET | LCD_ENTRYLEFT, Mode::COMMAND); + sendByte(LCD_FUNCTIONSET | LCD_2LINE, Mode::COMMAND); + sendByte(LCD_DISPLAYCONTROL | LCD_DISPLAYON, Mode::COMMAND); + clear(); + } -void LCD::sendChar(char val) { sendByte(val, Mode::CHARACTER); } - -void LCD::sendString(const std::string &str) { - for (const char &c : str) { - if (c == '\n') { - cursor_y++; - setCursor(cursor_y, 0); - } else { - sendChar(c); - cursor_x++; + void sendString(const std::string &str) { + for (const char &c : str) { + if (c == '\n') { + cursor_y++; + setCursor(cursor_y, 0); + } else { + sendChar(c); + cursor_x++; + } } } -} -void LCD::clear() { sendByte(LCD_CLEARDISPLAY, Mode::COMMAND); } + // Go to location on LCD + void setCursor(int line, int position) { + int val = (line == 0) ? 0x80 + position : 0xC0 + position; + sendByte(val, Mode::COMMAND); + cursor_x = line; + cursor_y = position; + } -void LCD::i2cWriteByte(uint8_t val) { - i2c_write_blocking(i2c, i2c_addr, &val, 1, false); -} + void clear() { sendByte(LCD_CLEARDISPLAY, Mode::COMMAND); } -void LCD::toggleEnable(uint8_t val) { - // Toggle enable pin on LCD display - // We cannot do this too quickly or things don't work - constexpr uint64_t DELAY_US = 600; - sleep_us(DELAY_US); - i2cWriteByte(val | LCD_ENABLE_BIT); - sleep_us(DELAY_US); - i2cWriteByte(val & ~LCD_ENABLE_BIT); - sleep_us(DELAY_US); -} + private: + void sendChar(char val) { sendByte(val, Mode::CHARACTER); } -// The display is sent a byte as two separate nibble transfers -void LCD::sendByte(uint8_t val, Mode mode) { - uint8_t high = static_cast(mode) | (val & 0xF0) | LCD_BACKLIGHT; - uint8_t low = static_cast(mode) | ((val << 4) & 0xF0) | LCD_BACKLIGHT; + void i2cWriteByte(uint8_t val) { + i2c_write_blocking(i2c, i2c_addr, &val, 1, false); + } - i2cWriteByte(high); - toggleEnable(high); - i2cWriteByte(low); - toggleEnable(low); -} + void toggleEnable(uint8_t val) { + // Toggle enable pin on LCD display + // We cannot do this too quickly or things don't work + constexpr uint64_t DELAY_US = 600; + sleep_us(DELAY_US); + i2cWriteByte(val | LCD_ENABLE_BIT); + sleep_us(DELAY_US); + i2cWriteByte(val & ~LCD_ENABLE_BIT); + sleep_us(DELAY_US); + } + + // The display is sent a byte as two separate nibble transfers + void sendByte(uint8_t val, Mode mode) { + uint8_t high = static_cast(mode) | (val & 0xF0) | LCD_BACKLIGHT; + uint8_t low = + static_cast(mode) | ((val << 4) & 0xF0) | LCD_BACKLIGHT; + + i2cWriteByte(high); + toggleEnable(high); + i2cWriteByte(low); + toggleEnable(low); + } + + i2c_inst_t *i2c; + uint8_t i2c_addr; + uint8_t num_cols; + uint8_t num_lines; + uint8_t cursor_x{0}; + uint8_t cursor_y{0}; +}; \ No newline at end of file diff --git a/src/relais.cpp b/src/relais.cpp index 6742c33..39bc970 100644 --- a/src/relais.cpp +++ b/src/relais.cpp @@ -1,13 +1,24 @@ -#include "relais.h" +module; -Relais::Relais(uint gpio) : gpio{gpio} { - gpio_init(gpio); - gpio_set_dir(gpio, GPIO_OUT); - off(); -} +#include "hardware/gpio.h" +#include "pico/stdlib.h" -void Relais::activate(bool active) { gpio_put(gpio, !active); } +export module relais; -void Relais::on() { activate(true); } +export class Relais { + public: + Relais(uint gpio) : gpio{gpio} { + gpio_init(gpio); + gpio_set_dir(gpio, GPIO_OUT); + off(); + } -void Relais::off() { activate(false); } \ No newline at end of file + void activate(bool active) { gpio_put(gpio, !active); } + + void on() { activate(true); } + + void off() { activate(false); } + + private: + uint gpio; +}; \ No newline at end of file