diff --git a/main/main.c b/main/main.c index 681637b..771342d 100644 --- a/main/main.c +++ b/main/main.c @@ -16,6 +16,7 @@ #include "esp_system.h" #include "esp_log.h" #include "esp_console.h" +#include "esp_sleep.h" #include "esp_vfs_dev.h" #include "nvs_flash.h" #include "esp_http_client.h" @@ -26,6 +27,7 @@ #include "linenoise/linenoise.h" #include "argtable3/argtable3.h" #include "driver/gpio.h" +#include "driver/spi_master.h" #include "esp32-wifi-manager.h" @@ -41,12 +43,24 @@ #define CONFIG_SERVO_ENABLE (0) #define CONFIG_SHOOT_DELAY_MS (30000) #define CONFIG_TIMEOUT_SHOOT (100 / portTICK_PERIOD_MS) +#define CONFIG_SLEEP_TIMEOUT (60000 / portTICK_PERIOD_MS) + +#define RTC_WAKE_IO RTC_GPIO8 +#define RTC_WAKE_PIN GPIO_INPUT_IO_0 + +#define PIN_NUM_MOSI 22 +#define PIN_NUM_CLK 23 + +#define LED_COUNT (1) +#define SPI_BUF (LED_COUNT + 2) static uint8_t id; static EventGroupHandle_t wm_event_group; -static xQueueHandle gpio_evt_queue = NULL; static xTimerHandle button_timer; +static xTimerHandle sleep_timer; +static spi_device_handle_t spi; +xQueueHandle gpio_evt_queue = NULL; static struct { struct arg_int *value; // how fast it will move in uS @@ -54,6 +68,15 @@ static struct { struct arg_end *end; } servo_args; +enum led_states { + POR, + CONNECTING, + CONNECTED, + SHOOTING +}; + +enum led_states led_state; + esp_err_t _http_event_handle(esp_http_client_event_t *evt) { //ESP_LOGI(TAG, "Returning request for %s", (char*)evt->user_data); @@ -88,6 +111,42 @@ esp_err_t _http_event_handle(esp_http_client_event_t *evt) { return ESP_OK; } +void enter_sleep() { + ESP_LOGI(TAG, "Enter deep sleep"); + + static spi_transaction_t trans[SPI_BUF]; + + int i; + for (i = 0; i < SPI_BUF; i++) { + memset(&trans[i], 0, sizeof(spi_transaction_t)); + + trans[i].length=8*4; + trans[i].flags = SPI_TRANS_USE_TXDATA; + } + + trans[1].tx_data[0] = (0b11100000 | 0); + trans[1].tx_data[1] = 0; + trans[1].tx_data[2] = 0; + trans[1].tx_data[3] = 0; + + memset(&trans[SPI_BUF - 1].tx_data, 0xFF, 4); + + for(i = 0; i < SPI_BUF; i++) { + spi_device_queue_trans(spi, &trans[i], portMAX_DELAY); + } + + esp_sleep_enable_ext0_wakeup(RTC_WAKE_PIN, 0); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + + //rtc_gpio_isolate(GPIO_INPUT_IO_0); + esp_deep_sleep_start(); +} + +void reset_sleep_timer() { + xTimerReset(sleep_timer, portMAX_DELAY); + xTimerStart(sleep_timer, portMAX_DELAY); +} + void ping() { esp_http_client_config_t config = { .url = "http://192.168.0.1/_gr", @@ -146,24 +205,50 @@ void request(char *path) { } } -void loop() { - xEventGroupWaitBits(wm_event_group, WIFI_CONNECTED, false, true, portMAX_DELAY); - ping(); - - vTaskDelay(1000 / portTICK_PERIOD_MS); +void led_loop() { + uint8_t v = 0; while(true) { - //shoot(); + if(xQueueReceive(wm_event_queue, &v, portMAX_DELAY)) { + EventBits_t ev_bits = xEventGroupGetBits(wm_event_group); + ESP_LOGI(TAG, "got event: %d", ev_bits); - if(CONFIG_SERVO_ENABLE) { - vTaskDelay(3000 / portTICK_PERIOD_MS); + static spi_transaction_t trans[SPI_BUF]; - mcpwm_set_duty_in_us(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, 1200); - vTaskDelay(200 / portTICK_PERIOD_MS); - mcpwm_set_duty_in_us(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, 1500); + int i; + for (i = 0; i < SPI_BUF; i++) { + memset(&trans[i], 0, sizeof(spi_transaction_t)); + + trans[i].length=8*4; + trans[i].flags = SPI_TRANS_USE_TXDATA; + } + + trans[1].tx_data[0] = (0b11100000 | 1); + + if(ev_bits & WIFI_CONNECTED) { + trans[1].tx_data[1] = 0; + trans[1].tx_data[2] = 127; + trans[1].tx_data[3] = 0; + } else if(ev_bits & WIFI_SCANNING) { + trans[1].tx_data[1] = 0; + trans[1].tx_data[2] = 55; + trans[1].tx_data[3] = 127; + } else if(ev_bits & WIFI_CONNECTING) { + trans[1].tx_data[1] = 127; + trans[1].tx_data[2] = 127; + trans[1].tx_data[3] = 0; + } else if(ev_bits & WIFI_IDLE) { + trans[1].tx_data[1] = 0; + trans[1].tx_data[2] = 0; + trans[1].tx_data[3] = 127; + } + + memset(&trans[SPI_BUF - 1].tx_data, 0xFF, 4); + + for(i = 0; i < SPI_BUF; i++) { + spi_device_queue_trans(spi, &trans[i], portMAX_DELAY); + } } - - vTaskDelay(CONFIG_SHOOT_DELAY_MS / portTICK_PERIOD_MS); } } @@ -227,57 +312,6 @@ void register_servo_cmd() { ESP_ERROR_CHECK( esp_console_cmd_register(&start_cmd) ); } -static void initialize_console() { - /* Disable buffering on stdin and stdout */ - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - - /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ - esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); - /* Move the caret to the beginning of the next line on '\n' */ - esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); - - /* Configure UART. Note that REF_TICK is used so that the baud rate remains - * correct while APB frequency is changing in light sleep mode. - */ - const uart_config_t uart_config = { - .baud_rate = CONFIG_CONSOLE_UART_BAUDRATE, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .use_ref_tick = true - }; - ESP_ERROR_CHECK( uart_param_config(CONFIG_CONSOLE_UART_NUM, &uart_config) ); - - /* Install UART driver for interrupt-driven reads and writes */ - ESP_ERROR_CHECK( uart_driver_install(CONFIG_CONSOLE_UART_NUM, - 256, 0, 0, NULL, 0) ); - - /* Tell VFS to use UART driver */ - esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); - - /* Initialize the console */ - esp_console_config_t console_config = { - .max_cmdline_args = 8, - .max_cmdline_length = 256, - .hint_color = atoi(LOG_COLOR_CYAN) - }; - ESP_ERROR_CHECK( esp_console_init(&console_config) ); - - /* Configure linenoise line completion library */ - /* Enable multiline editing. If not set, long commands will scroll within - * single line. - */ - linenoiseSetMultiLine(1); - - /* Tell linenoise where to get command completions and hints */ - linenoiseSetCompletionCallback(&esp_console_get_completion); - linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint); - - /* Set command history size */ - linenoiseHistorySetMaxLen(100); -} - static void IRAM_ATTR gpio_isr_handler(void* arg) { uint32_t gpio_num = (uint32_t) arg; @@ -290,28 +324,28 @@ void gpio_loop() { for(;;) { if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { - EventBits_t ev_bits = xEventGroupGetBits(wm_event_group); - - if(ev_bits & (WIFI_SCANNING|WIFI_CONNECTING)) { - ESP_LOGI(TAG, "Scan or connection in progress..."); - continue; - } - - if((ev_bits & WIFI_CONNECTED) == 0) { - ESP_LOGI(TAG, "No connectiong, connecting"); - wifi_manager_scan(); - continue; - } - uint8_t level = gpio_get_level(io_num); - printf("GPIO[%d] intr, val: %d\n", io_num, level); // don't act on state level twice if(level == state) continue; - // track level for duplicate state = level; + EventBits_t ev_bits = xEventGroupGetBits(wm_event_group); + ESP_LOGI(TAG, "gpio_loop: %d", ev_bits); + + if(level == 0 && (ev_bits & WIFI_CONNECTED) == 0) { + ESP_LOGI(TAG, "No connectiong, connecting"); + + wifi_manager_scan(); + + continue; + } + + printf("GPIO[%d] intr, val: %d\n", io_num, level); + + reset_sleep_timer(); + if(level == 0) { xTimerChangePeriod(button_timer, CONFIG_TIMEOUT_SHOOT, portMAX_DELAY); xTimerStart(button_timer, portMAX_DELAY); @@ -344,10 +378,57 @@ void gpio_init() { //start gpio task button_timer = xTimerCreate("gpio_timer", 1000, pdFALSE, (void*)NULL, handle_button_timer); + sleep_timer = xTimerCreate("sleep_timer", CONFIG_SLEEP_TIMEOUT, pdFALSE, (void*)NULL, enter_sleep); + reset_sleep_timer(); xTaskCreate(gpio_loop, "gpio_loop", 2048, NULL, 10, NULL); } +void spi_init() { + esp_err_t ret; + spi_bus_config_t buscfg={ + .mosi_io_num=PIN_NUM_MOSI, + .sclk_io_num=PIN_NUM_CLK, + .quadwp_io_num=-1, + .quadhd_io_num=-1, + .max_transfer_sz=120*320*2+8 + }; + spi_device_interface_config_t devcfg={ + .clock_speed_hz=10*1000*1000, //Clock out at 10 MHz + .mode=0, //SPI mode 0 + .queue_size=7, //We want to be able to queue 7 transactions at a time + //.pre_cb=lcd_spi_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line + }; + //Initialize the SPI bus + ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1); + ESP_ERROR_CHECK(ret); + //Attach the LCD to the SPI bus + ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi); + ESP_ERROR_CHECK(ret); + + static spi_transaction_t trans[SPI_BUF]; + + int i; + for (i = 0; i < SPI_BUF; i++) { + memset(&trans[i], 0, sizeof(spi_transaction_t)); + + trans[i].length=8*4; + trans[i].flags = SPI_TRANS_USE_TXDATA; + } + + trans[1].tx_data[0] = (0b11100000 | 1); + trans[1].tx_data[1] = 127; + trans[1].tx_data[2] = 127; + trans[1].tx_data[3] = 127; + + memset(&trans[SPI_BUF - 1].tx_data, 0xFF, 4); + + for(i = 0; i < SPI_BUF; i++) { + ret = spi_device_queue_trans(spi, &trans[i], portMAX_DELAY); + assert(ret==ESP_OK); + } +} + void app_main() { esp_err_t ret; @@ -378,41 +459,10 @@ void app_main() { } } - wifi_manager_scan(); - - //initialize_console(); - //esp_console_register_help_command(); - //register_servo_cmd(); - - pwm_init(); - - xTaskCreate(&loop, "loop", 4096, NULL, 6, NULL); - - const char* prompt = LOG_COLOR_I "grii> " LOG_RESET_COLOR; - gpio_init(); + spi_init(); - return; - while(true) { - char* line = linenoise(prompt); + xTaskCreate(&led_loop, "led_loop", 4096, NULL, 6, NULL); - if (line == NULL) { /* Ignore empty lines */ - continue; - } - - linenoiseHistoryAdd(line); - int ret; - esp_err_t err = esp_console_run(line, &ret); - if (err == ESP_ERR_NOT_FOUND) { - printf("Unrecognized command\n"); - } else if (err == ESP_ERR_INVALID_ARG) { - // command was empty - } else if (err == ESP_OK && ret != ESP_OK) { - printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(err)); - } else if (err != ESP_OK) { - printf("Internal error: %s\n", esp_err_to_name(err)); - } - /* linenoise allocates line buffer on the heap, so need to free it */ - linenoiseFree(line); - } + wifi_manager_scan(); };