From 6d7141db0c73af34fd887fda9723c77aaaf1e349 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 29 May 2015 00:00:05 +0200 Subject: o Initial import of Phone Remote firmware, forked from the old soil moisture project. --- LiquidCrystal.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 LiquidCrystal.c (limited to 'LiquidCrystal.c') diff --git a/LiquidCrystal.c b/LiquidCrystal.c new file mode 100644 index 0000000..becc07e --- /dev/null +++ b/LiquidCrystal.c @@ -0,0 +1,141 @@ +#include "LiquidCrystal.h" +#include "nrf_gpio.h" +#include "app_timer.h" + +/* + * Arduino | LCD | nrf51 + * D4 | DB4 | P0.16 + * D5 | DB5 | P0.17 + * D6 | DB6 | P0.18 + * D7 | DB7 | P0.10 + * D8 | RS | P0.20, register select. 0=instruction (write), 0=busy (read), 1=data + * D9 | EN | P0.23, clock, data is clocked in/out on falling edge + * D10 | DB4 | P0.24 + */ + +enum liquid_crystal_cmd { + LIQUID_CRYSTAL_CMD_CLEAR = 0x01, + LIQUID_CRYSTAL_CMD_RETURN_HOME = 0x02, + LIQUID_CRYSTAL_CMD_ENTRY_MODE_SET = 0x04, + LIQUID_CRYSTAL_CMD_DISPLAY = 0x08, + LIQUID_CRYSTAL_CMD_SHIFT = 0x10, + LIQUID_CRYSTAL_CMD_FUNCTION_SET = 0x20, + LIQUID_CRYSTAL_CMD_SET_CGRAM_ADDDRESS = 0x40, + LIQUID_CRYSTAL_CMD_SET_DDRAM_ADDDRESS = 0x80, +}; + +static struct { + uint8_t pin_db4; + uint8_t pin_db5; + uint8_t pin_db6; + uint8_t pin_db7; + uint8_t pin_rs; + uint8_t pin_en; + + app_gpiote_user_id_t gpio_user_id; +} data = { .pin_db4 = 16, .pin_db5 = 17, .pin_db6 = 18, .pin_db7 = 19, .pin_rs = + 20, .pin_en = 23, }; + +static uint32_t ticks_per_ms; + +static void event_handler() { +} + +static void wait_ms(uint32_t ms) { + uint32_t ticks; + + app_timer_cnt_get(&ticks); + + const uint32_t end_ticks = ticks + ms * ticks_per_ms; + + do { + app_timer_cnt_get(&ticks); + } while (ticks < end_ticks); +} + +static void write_4(uint8_t value) { + nrf_gpio_pin_write(data.pin_db4, value & 0x01); + nrf_gpio_pin_write(data.pin_db5, value & 0x02); + nrf_gpio_pin_write(data.pin_db6, value & 0x04); + nrf_gpio_pin_write(data.pin_db7, value & 0x08); + + nrf_gpio_pin_set(data.pin_en); + nrf_gpio_pin_clear(data.pin_en); +} + +static void write_value(uint8_t value, bool is_data) { + nrf_gpio_pin_write(data.pin_rs, is_data); + + write_4(value >> 4); + write_4(value); +} + +static void begin() { + nrf_gpio_pin_clear(data.pin_rs); + nrf_gpio_pin_clear(data.pin_en); + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50 + wait_ms(50); + + write_4(0x03); + wait_ms(5); // 4.5ms + + write_4(0x03); + wait_ms(5); // 4.5ms + + write_4(0x03); + wait_ms(5); // 4.5ms + + write_4(0x02); + + write_value(LIQUID_CRYSTAL_CMD_DISPLAY, false); + +// _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + liquid_crystal_display(true, true, true); +} + +void liquid_crystal_write_char(char chr) { + write_value(chr, true); +} + +void liquid_crystal_write_string(char *chr) { + while (*chr != '\0') { + liquid_crystal_write_char(*chr); + } +} + +uint32_t liquid_crystal_display(bool display_on, bool cursor_on, bool blink) { + uint8_t value = LIQUID_CRYSTAL_CMD_DISPLAY; + + value |= display_on ? 0x04 : 0x00; + value |= cursor_on ? 0x02 : 0x00; + value |= blink ? 0x01 : 0x00; + + write_value(value, false); + + return NRF_SUCCESS; +} + +uint32_t liquid_crystal_init(uint32_t _ticks_per_ms) { + ticks_per_ms = _ticks_per_ms; + + uint32_t err_code = app_gpiote_user_register(&data.gpio_user_id, 0x0000, + 0x0000, event_handler); + + if (err_code != NRF_SUCCESS) { + return err_code; + } + + nrf_gpio_cfg_output(data.pin_db4); + nrf_gpio_cfg_output(data.pin_db5); + nrf_gpio_cfg_output(data.pin_db6); + nrf_gpio_cfg_output(data.pin_db7); + nrf_gpio_cfg_output(data.pin_rs); + nrf_gpio_cfg_output(data.pin_en); + + begin(data); + + return NRF_SUCCESS; +} -- cgit v1.2.3