summaryrefslogtreecommitdiff
path: root/LiquidCrystal.c
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-05-29 00:00:05 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2015-05-29 00:00:05 +0200
commit6d7141db0c73af34fd887fda9723c77aaaf1e349 (patch)
treeef8d2ebf816e70a4a63073700b9097b8467f2380 /LiquidCrystal.c
downloadphone_remote_nrf51-6d7141db0c73af34fd887fda9723c77aaaf1e349.tar.gz
phone_remote_nrf51-6d7141db0c73af34fd887fda9723c77aaaf1e349.tar.bz2
phone_remote_nrf51-6d7141db0c73af34fd887fda9723c77aaaf1e349.tar.xz
phone_remote_nrf51-6d7141db0c73af34fd887fda9723c77aaaf1e349.zip
o Initial import of Phone Remote firmware, forked from the old soil moisture project.
Diffstat (limited to 'LiquidCrystal.c')
-rw-r--r--LiquidCrystal.c141
1 files changed, 141 insertions, 0 deletions
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;
+}