implement relais and lcd as modules
Does NOT compile! Problem might be on the side of the ARM compiler.
This commit is contained in:
parent
c56c52e458
commit
a81c7bac77
5 changed files with 114 additions and 77 deletions
|
@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.13)
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
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
|
# Initialise pico_sdk from installed location
|
||||||
# (note this can come from environment, CMake cache etc)
|
# (note this can come from environment, CMake cache etc)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||||
|
|
||||||
|
#add_compile_options(-fmodules-ts)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
gbmanager.cpp
|
|
||||||
lcd.cpp
|
lcd.cpp
|
||||||
relais.cpp
|
relais.cpp
|
||||||
|
gbmanager.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add executable. Default name is the project name, version 0.1
|
# Add executable. Default name is the project name, version 0.1
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "lcd.h"
|
//#include "lcd.h"
|
||||||
#include "relais.h"
|
|
||||||
|
import lcd;
|
||||||
|
import relais;
|
||||||
|
|
||||||
// GPIOs used
|
// GPIOs used
|
||||||
constexpr uint I2C_SDA_PIN = 26;
|
constexpr uint I2C_SDA_PIN = 26;
|
||||||
|
@ -28,7 +30,7 @@ absolute_time_t lastPressed = get_absolute_time();
|
||||||
|
|
||||||
using std::string;
|
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();
|
absolute_time_t now = get_absolute_time();
|
||||||
if (absolute_time_diff_us(lastPressed, now) < 750000) {
|
if (absolute_time_diff_us(lastPressed, now) < 750000) {
|
||||||
return;
|
return;
|
||||||
|
@ -54,7 +56,7 @@ int main() {
|
||||||
stdio_init_all();
|
stdio_init_all();
|
||||||
|
|
||||||
// Initialize the LCD
|
// 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();
|
myLCD.clear();
|
||||||
|
|
||||||
// Initialize the temp sensor
|
// Initialize the temp sensor
|
||||||
|
|
146
src/lcd.cpp
146
src/lcd.cpp
|
@ -1,6 +1,12 @@
|
||||||
#include "pico/binary_info.h"
|
module;
|
||||||
|
|
||||||
#include "lcd.h"
|
#include <string>
|
||||||
|
|
||||||
|
#include "hardware/i2c.h"
|
||||||
|
#include "pico/binary_info.h"
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
|
||||||
|
export module lcd;
|
||||||
|
|
||||||
// commands
|
// commands
|
||||||
constexpr int LCD_CLEARDISPLAY = 0x01;
|
constexpr int LCD_CLEARDISPLAY = 0x01;
|
||||||
|
@ -29,74 +35,90 @@ constexpr int LCD_8BITMODE = 0x10;
|
||||||
constexpr int LCD_BACKLIGHT = 0x08;
|
constexpr int LCD_BACKLIGHT = 0x08;
|
||||||
constexpr int LCD_ENABLE_BIT = 0x04;
|
constexpr int LCD_ENABLE_BIT = 0x04;
|
||||||
|
|
||||||
LCD::LCD(i2c_inst_t *i2c, const uint gpio_sda, const uint gpio_scl,
|
enum class Mode { COMMAND, CHARACTER };
|
||||||
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));
|
|
||||||
|
|
||||||
sendByte(0x03, Mode::COMMAND);
|
export class LCD {
|
||||||
sendByte(0x03, Mode::COMMAND);
|
public:
|
||||||
sendByte(0x03, Mode::COMMAND);
|
LCD(i2c_inst_t *i2c, const uint gpio_sda, const uint gpio_scl,
|
||||||
sendByte(0x02, Mode::COMMAND);
|
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(0x03, Mode::COMMAND);
|
||||||
sendByte(LCD_FUNCTIONSET | LCD_2LINE, Mode::COMMAND);
|
sendByte(0x03, Mode::COMMAND);
|
||||||
sendByte(LCD_DISPLAYCONTROL | LCD_DISPLAYON, Mode::COMMAND);
|
sendByte(0x03, Mode::COMMAND);
|
||||||
clear();
|
sendByte(0x02, Mode::COMMAND);
|
||||||
}
|
|
||||||
|
|
||||||
// Go to location on LCD
|
sendByte(LCD_ENTRYMODESET | LCD_ENTRYLEFT, Mode::COMMAND);
|
||||||
void LCD::setCursor(int line, int position) {
|
sendByte(LCD_FUNCTIONSET | LCD_2LINE, Mode::COMMAND);
|
||||||
int val = (line == 0) ? 0x80 + position : 0xC0 + position;
|
sendByte(LCD_DISPLAYCONTROL | LCD_DISPLAYON, Mode::COMMAND);
|
||||||
sendByte(val, Mode::COMMAND);
|
clear();
|
||||||
cursor_x = line;
|
}
|
||||||
cursor_y = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD::sendChar(char val) { sendByte(val, Mode::CHARACTER); }
|
void sendString(const std::string &str) {
|
||||||
|
for (const char &c : str) {
|
||||||
void LCD::sendString(const std::string &str) {
|
if (c == '\n') {
|
||||||
for (const char &c : str) {
|
cursor_y++;
|
||||||
if (c == '\n') {
|
setCursor(cursor_y, 0);
|
||||||
cursor_y++;
|
} else {
|
||||||
setCursor(cursor_y, 0);
|
sendChar(c);
|
||||||
} else {
|
cursor_x++;
|
||||||
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) {
|
void clear() { sendByte(LCD_CLEARDISPLAY, Mode::COMMAND); }
|
||||||
i2c_write_blocking(i2c, i2c_addr, &val, 1, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD::toggleEnable(uint8_t val) {
|
private:
|
||||||
// Toggle enable pin on LCD display
|
void sendChar(char val) { sendByte(val, Mode::CHARACTER); }
|
||||||
// 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 i2cWriteByte(uint8_t val) {
|
||||||
void LCD::sendByte(uint8_t val, Mode mode) {
|
i2c_write_blocking(i2c, i2c_addr, &val, 1, false);
|
||||||
uint8_t high = static_cast<int>(mode) | (val & 0xF0) | LCD_BACKLIGHT;
|
}
|
||||||
uint8_t low = static_cast<int>(mode) | ((val << 4) & 0xF0) | LCD_BACKLIGHT;
|
|
||||||
|
|
||||||
i2cWriteByte(high);
|
void toggleEnable(uint8_t val) {
|
||||||
toggleEnable(high);
|
// Toggle enable pin on LCD display
|
||||||
i2cWriteByte(low);
|
// We cannot do this too quickly or things don't work
|
||||||
toggleEnable(low);
|
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<int>(mode) | (val & 0xF0) | LCD_BACKLIGHT;
|
||||||
|
uint8_t low =
|
||||||
|
static_cast<int>(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};
|
||||||
|
};
|
|
@ -1,13 +1,24 @@
|
||||||
#include "relais.h"
|
module;
|
||||||
|
|
||||||
Relais::Relais(uint gpio) : gpio{gpio} {
|
#include "hardware/gpio.h"
|
||||||
gpio_init(gpio);
|
#include "pico/stdlib.h"
|
||||||
gpio_set_dir(gpio, GPIO_OUT);
|
|
||||||
off();
|
|
||||||
}
|
|
||||||
|
|
||||||
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); }
|
void activate(bool active) { gpio_put(gpio, !active); }
|
||||||
|
|
||||||
|
void on() { activate(true); }
|
||||||
|
|
||||||
|
void off() { activate(false); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint gpio;
|
||||||
|
};
|
Loading…
Reference in a new issue