#include #include #include #include #include #include #include #include "pinout.h" #include "lcd.h" #include "ds_rtc.h" #include "ee.h" #include "lcd/lcdbuf.h" #include "screens/app_gui.h" #include "app_config.h" /* PINOUT Keypad - UART RX - receives symbols from STM8 LCD - HD44780 14 - RS (H-data, L-command) 15 - EN (CLK) 21,20,19,18 - D7,D6,D5,D4 RW tied low (always write) TODO backlight switching I2C 16 - SDA0 17 - SCL0 EEPROM 24C32 - addr 1010_000 RTC DS3231 - addr 1101_000 Relay 5, 4, 22, 26 - active high Moisture 28 - ADC2 0-3V */ void setup_output(uint num) { gpio_set_dir(num, GPIO_OUT); gpio_put(num, 0); gpio_set_function(num, GPIO_FUNC_SIO); } #define KEYPAD_BUFFER_LEN 10 static uint8_t keypad_buffer[KEYPAD_BUFFER_LEN]; static uint8_t keypad_buffer_wp = 0; static uint8_t keypad_buffer_rp = 0; // RX interrupt handler void irq_uart() { while (uart_is_readable(uart0)) { uint8_t ch = uart_getc(uart0); if (keypad_buffer[keypad_buffer_wp] == 0) { keypad_buffer[keypad_buffer_wp] = ch; keypad_buffer_wp++; if (keypad_buffer_wp >= KEYPAD_BUFFER_LEN) { keypad_buffer_wp = 0; } } } } int __attribute__((noreturn)) main() { // picotool binary info bi_decl(bi_1pin_with_name(PIN_LED, "LED")); bi_decl(bi_1pin_with_name(PIN_RE1, "RE1")); bi_decl(bi_1pin_with_name(PIN_RE2, "RE2")); bi_decl(bi_1pin_with_name(PIN_RE3, "RE3")); bi_decl(bi_1pin_with_name(PIN_RE4, "RE4")); bi_decl(bi_1pin_with_name(PIN_RE5, "RE5")); bi_decl(bi_1pin_with_name(PIN_RE6, "RE6")); bi_decl(bi_1pin_with_name(PIN_LCD_RS, "LCD RS")); bi_decl(bi_1pin_with_name(PIN_LCD_E, "LCD CLK")); bi_decl(bi_1pin_with_name(PIN_LCD_D7, "LCD D7")); bi_decl(bi_1pin_with_name(PIN_LCD_D6, "LCD D6")); bi_decl(bi_1pin_with_name(PIN_LCD_D5, "LCD D5")); bi_decl(bi_1pin_with_name(PIN_LCD_D4, "LCD D4")); bi_decl(bi_2pins_with_func(PIN_I2C_SDA, PIN_I2C_SCL, GPIO_FUNC_I2C)); bi_decl(bi_1pin_with_name(PIN_MOISTURE, "ADC (moisture)")); bi_decl(bi_program_description("Zavlaha Kuchynka")); setup_default_uart(); irq_set_exclusive_handler(UART0_IRQ, irq_uart); irq_set_enabled(UART0_IRQ, true); uart_set_irq_enables(uart0, 1, 0); /* On-board LED */ setup_output(PIN_LED); /* Valve relays */ setup_output(PIN_RE1); setup_output(PIN_RE2); setup_output(PIN_RE3); setup_output(PIN_RE4); setup_output(PIN_RE5); setup_output(PIN_RE6); /* LCD */ setup_output(PIN_LCD_RS); setup_output(PIN_LCD_RW); setup_output(PIN_LCD_E); setup_output(PIN_LCD_D7); setup_output(PIN_LCD_D6); setup_output(PIN_LCD_D5); setup_output(PIN_LCD_D4); /* I2C */ i2c_init(i2c0, 100 * 1000); // 100 kbps - play it safe gpio_set_function(PIN_I2C_SDA, GPIO_FUNC_I2C); gpio_set_function(PIN_I2C_SCL, GPIO_FUNC_I2C); gpio_pull_up(PIN_I2C_SDA); gpio_pull_up(PIN_I2C_SCL); /* ADC for moisture */ adc_init(); adc_gpio_init(PIN_MOISTURE); appconfig_load(); lcd_init(); gui_init(); for(;;) { // Check if any key was pushed uint32_t interrupts = save_and_disable_interrupts(); GuiEvent event = GUI_EVENT_NONE; if (keypad_buffer[keypad_buffer_rp] != 0) { char ch = keypad_buffer[keypad_buffer_rp]; keypad_buffer[keypad_buffer_rp] = 0; keypad_buffer_rp++; if (keypad_buffer_rp >= KEYPAD_BUFFER_LEN) { keypad_buffer_rp = 0; } event = ch; // there is 1:1 mapping for keypad ASCII } restore_interrupts(interrupts); gui_loop_iter(event); // TODO scheduler logic } // // struct LcdBuffer lcd; // LcdBuffer_Init(&lcd, CGROM_A00, CGRAM_CZ); // // LcdBuffer_Write(&lcd, 0, 0, "ěščřŽÝÁÍ pyčo!"); // LcdBuffer_Flush(&lcd); // // char buf[100]; // while (1) { // struct rtc_time time; // if (0 == rtc_get_time(&time)) { // sprintf(buf, "čas: %02d:%02d:%02d", time.hour, time.minute, time.second); // LcdBuffer_Write(&lcd, 2, 2, buf); // } // LcdBuffer_Flush(&lcd); // // sleep_ms(1000); // } #if 0 // while (1) { // int y; // lcd_clear(); // // y = 0; // for (int j = 0; j < 80; j += 20) { // lcd_xy(0, y++); // for (int i = j; i < j + 20; i++) { // lcd_putc(i); // } // } // // sleep_ms(5000); // lcd_clear(); // // y = 0; // for (int j = 80; j < 160; j += 20) { // lcd_xy(0, y++); // for (int i = j; i < j + 20; i++) { // lcd_putc(i); // } // } // // sleep_ms(5000); // lcd_clear(); // // y = 0; // for (int j = 160; j < 240; j += 20) { // lcd_xy(0, y++); // for (int i = j; i < j + 20; i++) { // lcd_putc(i); // } // } // // sleep_ms(5000); // lcd_clear(); // // for (int i = 240; i < 256; i++) { // lcd_putc(i); // } // // sleep_ms(5000); // } lcd_puts("HELLO WORLD!"); uint8_t ee_data[1] = {}; int ee_rv = ee_read(0, ee_data, 1); printf("ee rd rv = %d, val %02x", ee_rv, ee_data[0]); ee_data[0]++; ee_rv = ee_write(0, ee_data, 1); printf("ee wr rv = %d", ee_rv); int boot_count = ee_data[0]; uint cnt = 0; char buf[20]; while (1) { lcd_clear(); sprintf(buf, "ZAVLAHA-Boot=%d", boot_count); lcd_puts(buf); // Try to read RTC struct rtc_time time; if (0 == rtc_get_time(&time)) { sprintf(buf, "%02d:%02d:%02d", time.hour, time.minute, time.second); lcd_xy(0, 2); lcd_puts(buf); } else { lcd_xy(0, 2); lcd_puts("RTC err!"); } gpio_put(PIN_LED, 1); // LED on uint16_t moisture = moisture_read(); sprintf(buf, "ADC = %lu", moisture); lcd_xy(0, 1); lcd_puts(buf); lcd_xy(15, 3); lcd_putc('0' + cnt); sleep_ms(100); gpio_put(PIN_LED, 0); // LED off sleep_ms(100); // demo that valve control works cnt += 1; if (cnt == 5) { cnt = 0; } open_valve(cnt); } #endif }