diff --git a/ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/88MZ100_7.4_BETA-0.3.bin b/ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/88MZ100_7.4_BETA-0.3.bin new file mode 100644 index 00000000..fc9a9e12 Binary files /dev/null and b/ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/88MZ100_7.4_BETA-0.3.bin differ diff --git a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/led.c b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/led.c index 78a8dd71..87469298 100644 --- a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/led.c +++ b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/led.c @@ -1,26 +1,48 @@ -#include -#include -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "driver/gpio.h" #include "led.h" +#include "driver/gpio.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "freertos/timers.h" #include "proto.h" +#include +#include +#include +#include -void init_led() -{ - gpio_config_t led1 = {}; - led1.intr_type = GPIO_INTR_DISABLE; - led1.mode = GPIO_MODE_OUTPUT; - led1.pin_bit_mask = ((1ULL<= 0 && led_index < NUM_LEDS) { + gpio_set_level(led_pins[led_index], 0); + } } -void led_set(int nr, bool state) -{ - gpio_set_level(nr, state); +void init_led() { + gpio_config_t led1 = {}; + led1.intr_type = GPIO_INTR_DISABLE; + led1.mode = GPIO_MODE_OUTPUT; + led1.pin_bit_mask = ((1ULL << LED1) | (1ULL << LED2)); + led1.pull_down_en = 0; + led1.pull_up_en = 0; + gpio_config(&led1); + + for (int i = 0; i < NUM_LEDS; i++) { + led_timers[i] = xTimerCreate("led_timer", pdMS_TO_TICKS(50), pdFALSE, (void *)i, led_timer_callback); + } +} + +void led_flash(int nr) { + gpio_set_level(led_pins[nr], 1); + if (nr >= 0 && nr < NUM_LEDS) { + xTimerStart(led_timers[nr], 0); + } +} + +void led_set(int nr, bool state) { + gpio_set_level(nr, state); } \ No newline at end of file diff --git a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/led.h b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/led.h index 5b7e200a..a76467c7 100644 --- a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/led.h +++ b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/led.h @@ -1,4 +1,6 @@ #pragma once +#include void init_led(); -void led_set(int nr, bool state); \ No newline at end of file +void led_set(int nr, bool state); +void led_flash(int nr); diff --git a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/main.c b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/main.c index 8e7e67af..3ddbb350 100644 --- a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/main.c +++ b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/main.c @@ -1,10 +1,6 @@ // Ported to ESP32-C6 By ATC1441(ATCnetz.de) for OpenEPaperLink at ~08.2023 #include "main.h" -#include -#include -#include -#include #include "driver/gpio.h" #include "driver/uart.h" #include "esp_err.h" @@ -16,21 +12,27 @@ #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/task.h" +#include "led.h" #include "proto.h" #include "radio.h" #include "sdkconfig.h" #include "second_uart.h" -#include "soc/uart_struct.h" #include "soc/lp_uart_reg.h" +#include "soc/uart_struct.h" #include "utils.h" -#include "led.h" +#include +#include +#include +#include +#include +#include static const char *TAG = "MAIN"; const uint8_t channelList[6] = {11, 15, 20, 25, 26, 27}; #define DATATYPE_NOUPDATE 0 -#define HW_TYPE 0xFF +#define HW_TYPE 0xC6 #define MAX_PENDING_MACS 250 #define HOUSEKEEPING_INTERVAL 60UL @@ -38,7 +40,7 @@ const uint8_t channelList[6] = {11, 15, 20, 25, 26, 27}; struct pendingData pendingDataArr[MAX_PENDING_MACS]; // VERSION GOES HERE! -uint16_t version = 0x0017; +uint16_t version = 0x0018; #define RAW_PKT_PADDING 2 @@ -69,6 +71,8 @@ uint8_t curPower = 10; uint8_t curPendingData = 0; uint8_t curNoUpdate = 0; +bool highspeedSerial = false; + void sendXferCompleteAck(uint8_t *dst); void sendCancelXfer(uint8_t *dst); void espNotifyAPInfo(); @@ -191,7 +195,7 @@ void processSerial(uint8_t lastchar) { static uint8_t *serialbufferp; static uint8_t bytesRemain = 0; static uint32_t lastSerial = 0; - static uint32_t blockStartTime = 0; + static uint32_t blockStartTime = 0; if ((RXState != ZBS_RX_WAIT_HEADER) && ((getMillis() - lastSerial) > 1000)) { RXState = ZBS_RX_WAIT_HEADER; ESP_LOGI(TAG, "UART Timeout"); @@ -206,9 +210,9 @@ void processSerial(uint8_t lastchar) { cmdbuffer[3] = lastchar; if (isSame(cmdbuffer + 1, ">D>", 3)) { - pr("ACK>\n"); + pr("ACK>"); blockStartTime = getMillis(); - ESP_LOGI(TAG, "Starting BlkData"); + ESP_LOGI(TAG, "Starting BlkData, %lu ms after request", blockStartTime - nextBlockAttempt ); blockPosition = 0; RXState = ZBS_RX_WAIT_BLOCKDATA; } @@ -252,11 +256,21 @@ void processSerial(uint8_t lastchar) { // TODO RESET US HERE RXState = ZBS_RX_WAIT_HEADER; } + if (isSame(cmdbuffer, "HSPD", 4)) { + pr("ACK>"); + ESP_LOGI(TAG, "HSPD In, switching to 2000000"); + delay(100); + uart_switch_speed(2000000); + delay(100); + highspeedSerial = true; + pr("ACK>"); + RXState = ZBS_RX_WAIT_HEADER; + } break; case ZBS_RX_WAIT_BLOCKDATA: blockbuffer[blockPosition++] = 0xAA ^ lastchar; if (blockPosition >= 4100) { - ESP_LOGI(TAG, "Blockdata fully received %lu", getMillis() - blockStartTime); + ESP_LOGI(TAG, "Blockdata fully received in %lu ms, %lu ms after the request", getMillis() - blockStartTime, getMillis() - nextBlockAttempt); RXState = ZBS_RX_WAIT_HEADER; } break; @@ -272,12 +286,12 @@ void processSerial(uint8_t lastchar) { if (slot == -1) slot = findFreeSlot(); if (slot != -1) { memcpy(&(pendingDataArr[slot]), serialbuffer, sizeof(struct pendingData)); - pr("ACK>\n"); + pr("ACK>"); } else { - pr("NOQ>\n"); + pr("NOQ>"); } } else { - pr("NOK>\n"); + pr("NOK>"); } RXState = ZBS_RX_WAIT_HEADER; @@ -290,11 +304,10 @@ void processSerial(uint8_t lastchar) { if (bytesRemain == 0) { if (checkCRC(serialbuffer, sizeof(struct pendingData))) { struct pendingData *pd = (struct pendingData *) serialbuffer; - // deleteAllPendingDataForVer((uint8_t *)&pd->availdatainfo.dataVer); deleteAllPendingDataForMac((uint8_t *) &pd->targetMac); - pr("ACK>\n"); + pr("ACK>"); } else { - pr("NOK>\n"); + pr("NOK>"); } RXState = ZBS_RX_WAIT_HEADER; @@ -316,10 +329,11 @@ void processSerial(uint8_t lastchar) { curPower = scp->power; radioSetChannel(scp->channel); radioSetTxPower(scp->power); - pr("ACK>\n"); + ESP_LOGI(TAG, "Set channel: %d power: %d", curChannel, curPower); + pr("ACK>"); } else { SCPfailed: - pr("NOK>\n"); + pr("NOK>"); } RXState = ZBS_RX_WAIT_HEADER; } @@ -381,17 +395,17 @@ void espNotifyTimeOut(const uint8_t *src) { } } void espNotifyAPInfo() { - pr("TYP>%02X\n", HW_TYPE); - pr("VER>%04X\n", version); + pr("TYP>%02X", HW_TYPE); + pr("VER>%04X", version); pr("MAC>%02X%02X", mSelfMac[0], mSelfMac[1]); pr("%02X%02X", mSelfMac[2], mSelfMac[3]); pr("%02X%02X", mSelfMac[4], mSelfMac[5]); - pr("%02X%02X\n", mSelfMac[6], mSelfMac[7]); - pr("ZCH>%02X\n", curChannel); - pr("ZPW>%02X\n", curPower); + pr("%02X%02X", mSelfMac[6], mSelfMac[7]); + pr("ZCH>%02X", curChannel); + pr("ZPW>%02X", curPower); countSlots(); - pr("PEN>%02X\n", curPendingData); - pr("NOP>%02X\n", curNoUpdate); + pr("PEN>%02X", curPendingData); + pr("NOP>%02X", curNoUpdate); } // process data from tag @@ -450,18 +464,17 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) { if (blockStartTimer == 0) { if (requestDataDownload) { - // check if we need to download the first block; we need to give the ESP32 some additional time to cache the file - if (blockReq->blockId == 0) { - blockRequestAck->pleaseWaitMs = 450; + if (highspeedSerial == true) { + blockRequestAck->pleaseWaitMs = 220; } else { - blockRequestAck->pleaseWaitMs = 450; + blockRequestAck->pleaseWaitMs = 550; } } else { // block is already in buffer - blockRequestAck->pleaseWaitMs = 50; + blockRequestAck->pleaseWaitMs = 30; } } else { - blockRequestAck->pleaseWaitMs = 50; + blockRequestAck->pleaseWaitMs = 30; } blockStartTimer = getMillis() + blockRequestAck->pleaseWaitMs; @@ -624,8 +637,8 @@ void sendPong(void *buf) { } void app_main(void) { - init_nvs(); - init_led(); + init_nvs(); + init_led(); init_second_uart(); esp_event_loop_create_default(); @@ -639,23 +652,23 @@ void app_main(void) { radioSetChannel(curChannel); radioSetTxPower(10); - pr("RES>\n"); - pr("RDY>\n"); + pr("RES>"); + pr("RDY>"); housekeepingTimer = getMillis(); while (1) { while ((getMillis() - housekeepingTimer) < ((1000 * HOUSEKEEPING_INTERVAL) - 100)) { int8_t ret = commsRxUnencrypted(radiorxbuffer); if (ret > 1) { - led_set(LED1, 1); + led_flash(0); // received a packet, lets see what it is switch (getPacketType(radiorxbuffer)) { case PKT_AVAIL_DATA_REQ: if (ret == 28) { // old version of the AvailDataReq struct, set all the new fields to zero, so it will pass the CRC - processAvailDataReq(radiorxbuffer); memset(radiorxbuffer + 1 + sizeof(struct MacFrameBcast) + sizeof(struct oldAvailDataReq), 0, sizeof(struct AvailDataReq) - sizeof(struct oldAvailDataReq) + 2); + processAvailDataReq(radiorxbuffer); } else if (ret == 40) { // new version of the AvailDataReq struct processAvailDataReq(radiorxbuffer); @@ -683,22 +696,24 @@ void app_main(void) { } break; default: - pr("t=%02X\n", getPacketType(radiorxbuffer)); + ESP_LOGI(TAG, "t=%02X" , getPacketType(radiorxbuffer)); break; } - led_set(LED1, 0); + } else if (blockStartTimer == 0) { + vTaskDelay(10 / portTICK_PERIOD_MS); } + uint8_t curr_char; while (getRxCharSecond(&curr_char)) processSerial(curr_char); if (blockStartTimer) { - // BUG: uint32 overflowing; this will break every once in a while. Don't know how to fix this other than ugly global variables if (getMillis() > blockStartTimer) { sendBlockData(); blockStartTimer = 0; } } } + for (uint8_t cCount = 0; cCount < MAX_PENDING_MACS; cCount++) { if (pendingDataArr[cCount].attemptsLeft == 1) { if (pendingDataArr[cCount].availdatainfo.dataType != DATATYPE_NOUPDATE) { diff --git a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/radio.c b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/radio.c index 4a9027cf..62c3710a 100644 --- a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/radio.c +++ b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/radio.c @@ -1,7 +1,4 @@ -#include -#include -#include -#include +#include "radio.h" #include "driver/gpio.h" #include "driver/uart.h" #include "esp_err.h" @@ -13,28 +10,31 @@ #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/task.h" +#include "led.h" #include "main.h" #include "proto.h" #include "sdkconfig.h" -#include "soc/uart_struct.h" #include "soc/lp_uart_reg.h" -#include "radio.h" +#include "soc/uart_struct.h" #include "utils.h" -#include "led.h" +#include +#include +#include +#include static const char *TAG = "RADIO"; uint8_t mSelfMac[8]; volatile uint8_t isInTransmit = 0; -QueueHandle_t packet_bufer = NULL; +QueueHandle_t packet_buffer = NULL; void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info) { - ESP_EARLY_LOGI(TAG, "RX <- : %d", frame[0]); - BaseType_t xHigherPriorityTaskWoken ; - static uint8_t inner_rxPKT[130]; + ESP_EARLY_LOGI(TAG, "RX %d", frame[0]); + BaseType_t xHigherPriorityTaskWoken; + static uint8_t inner_rxPKT[130]; memcpy(inner_rxPKT, &frame[0], frame[0] + 1); - xQueueSendFromISR(packet_bufer, (void *) &inner_rxPKT, &xHigherPriorityTaskWoken ); - portYIELD_FROM_ISR_ARG(xHigherPriorityTaskWoken ); + xQueueSendFromISR(packet_buffer, (void *)&inner_rxPKT, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR_ARG(xHigherPriorityTaskWoken); } void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error) { @@ -43,13 +43,12 @@ void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_erro } void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info) { - isInTransmit = 0; - ESP_EARLY_LOGI(TAG, "TX -> : %d", frame[0]); + isInTransmit = 0; + ESP_EARLY_LOGI(TAG, "TX %d", frame[0]); } -void radio_init() -{ - packet_bufer = xQueueCreate(32, 130); +void radio_init() { + packet_buffer = xQueueCreate(32, 130); esp_ieee802154_enable(); radioSetChannel(11); esp_ieee802154_set_panid(PROTO_PAN_ID); @@ -64,19 +63,17 @@ void radio_init() } uint32_t lastZbTx = 0; -bool radioTx(uint8_t *packet) -{ - static uint8_t txPKT[130]; - led_set(LED2, 1); +bool radioTx(uint8_t *packet) { + static uint8_t txPKT[130]; while (isInTransmit) { } while (getMillis() - lastZbTx < 6) { } + led_flash(1); memcpy(txPKT, packet, packet[0]); isInTransmit = 1; - lastZbTx = getMillis(); + lastZbTx = getMillis(); esp_ieee802154_transmit(txPKT, false); - led_set(LED2, 0); return true; } @@ -85,11 +82,10 @@ void radioSetChannel(uint8_t ch) { esp_ieee802154_set_channel(ch); } void radioSetTxPower(uint8_t power) {} int8_t commsRxUnencrypted(uint8_t *data) { - static uint8_t inner_rxPKT_out[130]; - if (xQueueReceive(packet_bufer, (void *) &inner_rxPKT_out, pdMS_TO_TICKS(100)) == pdTRUE) { - memcpy(data, &inner_rxPKT_out[1], inner_rxPKT_out[0] + 1); + static uint8_t inner_rxPKT_out[130]; + if (xQueueReceive(packet_buffer, (void *)&inner_rxPKT_out, pdMS_TO_TICKS(100)) == pdTRUE) { + memcpy(data, &inner_rxPKT_out[1], inner_rxPKT_out[0] + 1); return inner_rxPKT_out[0] - 2; } return 0; } - diff --git a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/radio.h b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/radio.h index d54d49db..2f50c751 100644 --- a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/radio.h +++ b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/radio.h @@ -1,9 +1,11 @@ #pragma once +#include +#include extern uint8_t mSelfMac[8]; void radio_init(); -bool radioTx(uint8_t *packet); +bool radioTx(uint8_t *packet); void radioSetChannel(uint8_t ch); void radioSetTxPower(uint8_t power); int8_t commsRxUnencrypted(uint8_t *data); \ No newline at end of file diff --git a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/second_uart.c b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/second_uart.c index d9023772..d6dadca0 100644 --- a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/second_uart.c +++ b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/second_uart.c @@ -51,6 +51,18 @@ void init_second_uart() { xTaskCreate(uart_event_task, "uart_event_task", 16384, NULL, 12, NULL); } +void uart_switch_speed(int baudrate) { + uart_config_t uart_config = { + .baud_rate = baudrate, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_DEFAULT, + }; + ESP_ERROR_CHECK(uart_param_config(1, &uart_config)); +} + void uartTx(uint8_t data) { uart_write_bytes(1, (const char *) &data, 1); } @@ -90,171 +102,16 @@ static void uart_event_task(void *pvParameters) { vTaskDelete(NULL); } -static void printchar(char **str, int c) { - if (str) { - **str = c; - ++(*str); - } else { - uart_write_bytes(1, (const char *) &c, 1); - } -} +void uart_printf(const char *format, ...) { + va_list args; + va_start(args, format); -#define PAD_RIGHT 1 -#define PAD_ZERO 2 + char buffer[128]; + int len = vsnprintf(buffer, sizeof(buffer), format, args); -static int prints(char **out, const char *string, int width, int pad) { - register int pc = 0, padchar = ' '; + va_end(args); - if (width > 0) { - register int len = 0; - register const char *ptr; - for (ptr = string; *ptr; ++ptr) ++len; - if (len >= width) - width = 0; - else - width -= len; - if (pad & PAD_ZERO) padchar = '0'; - } - if (!(pad & PAD_RIGHT)) { - for (; width > 0; --width) { - printchar(out, padchar); - ++pc; - } - } - for (; *string; ++string) { - printchar(out, *string); - ++pc; - } - for (; width > 0; --width) { - printchar(out, padchar); - ++pc; - } - - return pc; -} - -/* the following should be enough for 32 bit int */ -#define PRINT_BUF_LEN 12 - -static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase) { - char print_buf[PRINT_BUF_LEN]; - register char *s; - register int t, neg = 0, pc = 0; - register unsigned int u = i; - - if (i == 0) { - print_buf[0] = '0'; - print_buf[1] = '\0'; - return prints(out, print_buf, width, pad); - } - - if (sg && b == 10 && i < 0) { - neg = 1; - u = -i; - } - - s = print_buf + PRINT_BUF_LEN - 1; - *s = '\0'; - - while (u) { - t = u % b; - if (t >= 10) t += letbase - '0' - 10; - *--s = t + '0'; - u /= b; - } - - if (neg) { - if (width && (pad & PAD_ZERO)) { - printchar(out, '-'); - ++pc; - --width; - } else { - *--s = '-'; - } - } - - return pc + prints(out, s, width, pad); -} - -static int print(char **out, const char *format, va_list args) { - register int width, pad; - register int pc = 0; - char scr[2]; - - for (; *format != 0; ++format) { - if (*format == '%') { - ++format; - width = pad = 0; - if (*format == '\0') break; - if (*format == '%') goto out; - if (*format == '-') { - ++format; - pad = PAD_RIGHT; - } - while (*format == '0') { - ++format; - pad |= PAD_ZERO; - } - for (; *format >= '0' && *format <= '9'; ++format) { - width *= 10; - width += *format - '0'; - } - if (*format == 's') { - register char *s = (char *) va_arg(args, int); - pc += prints(out, s ? s : "(null)", width, pad); - continue; - } - if (*format == 'd') { - pc += printi(out, va_arg(args, int), 10, 1, width, pad, 'a'); - continue; - } - if (*format == 'x') { - pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'a'); - continue; - } - if (*format == 'X') { - pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'A'); - continue; - } - if (*format == 'u') { - pc += printi(out, va_arg(args, int), 10, 0, width, pad, 'a'); - continue; - } - if (*format == 'c') { - /* char are converted to int then pushed on the stack */ - scr[0] = (char) va_arg(args, int); - scr[1] = '\0'; - pc += prints(out, scr, width, pad); - continue; - } - } else { - out: - printchar(out, *format); - ++pc; - } - } - if (out) **out = '\0'; - va_end(args); - return pc; -} - -int u_printf(const char *format, ...) { - va_list args; - va_start(args, format); - print(0, format, args); - return 0; -} - -int u_sprintf(char *out, const char *format, ...) { - va_list args; - va_start(args, format); - return print(&out, format, args); -} - -void u_array_printf(unsigned char *data, unsigned int len) { - u_printf("{"); - for (int i = 0; i < len; ++i) { - u_printf("%X%s", data[i], i < (len) -1 ? ":" : " "); - } - u_printf("}\n"); + if (len > 0) { + uart_write_bytes(1, buffer, len); + } } \ No newline at end of file diff --git a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/second_uart.h b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/second_uart.h index 3eafd1c0..b25d4333 100644 --- a/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/second_uart.h +++ b/ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/second_uart.h @@ -1,14 +1,11 @@ #pragma once void init_second_uart(); +void uart_switch_speed(int baudrate); void uartTx(uint8_t data); bool getRxCharSecond(uint8_t *newChar); -int u_printf(const char *fmt, ...); -int u_sprintf(char *s, const char *fmt, ...); -void u_array_printf(unsigned char *data, unsigned int len); +void uart_printf(const char *format, ...); -#define pr u_printf -#define sprf u_sprintf -#define array_prf u_array_printf +#define pr uart_printf diff --git a/ESP32_AP-Flasher/data/tagtypes/E0.json b/ESP32_AP-Flasher/data/tagtypes/E0.json index 99e04246..d9481fff 100644 --- a/ESP32_AP-Flasher/data/tagtypes/E0.json +++ b/ESP32_AP-Flasher/data/tagtypes/E0.json @@ -1,7 +1,7 @@ { - "name": "TFT 320x170", + "name": "TFT 320x172", "width": 320, - "height": 170, + "height": 172, "rotatebuffer": 0, "bpp": 16, "colors": 4, @@ -16,14 +16,14 @@ "usetemplate": 1, "template": { "21": [ - { "box": [ 0, 0, 320, 170, 1 ] }, - { "text": [ 5, 5, "OpenEpaperLink AP", "calibrib30", 2, 0, 0, 1 ] }, - { "text": [ 5, 60, "IP address:", "bahnschrift20", "#888888", 0, 0, 1 ] }, - { "text": [ 120, 60, "{ap_ip}", "bahnschrift20", 0, 0, 0, 1 ] }, - { "text": [ 5, 85, "Channel:", "bahnschrift20", "#888888", 0, 0, 1 ] }, - { "text": [ 120, 85, "{ap_ch}", "bahnschrift20", 0, 0, 0, "1" ] }, - { "text": [ 5, 110, "Tag count:", "bahnschrift20", "#888888", 0, 0, 1 ] }, - { "text": [ 120, 110, "{ap_tagcount}", "bahnschrift20", 0, 0, 0, "1" ] } + { "box": [ 0, 0, 320, 172, 1 ] }, + { "text": [ 10, 15, "OpenEpaperLink AP", "calibrib30", 2, 0, 0, 1 ] }, + { "text": [ 10, 70, "IP address:", "bahnschrift20", "#888888", 0, 0, 1 ] }, + { "text": [ 120, 70, "{ap_ip}", "bahnschrift20", 0, 0, 0, 1 ] }, + { "text": [ 10, 95, "Channel:", "bahnschrift20", "#888888", 0, 0, 1 ] }, + { "text": [ 120, 95, "{ap_ch}", "bahnschrift20", 0, 0, 0, "1" ] }, + { "text": [ 10, 120, "Tag count:", "bahnschrift20", "#888888", 0, 0, 1 ] }, + { "text": [ 120, 120, "{ap_tagcount}", "bahnschrift20", 0, 0, 0, "1" ] } ] } } diff --git a/ESP32_AP-Flasher/data/www/edit.html.gz b/ESP32_AP-Flasher/data/www/edit.html.gz index d002da20..e397af05 100644 Binary files a/ESP32_AP-Flasher/data/www/edit.html.gz and b/ESP32_AP-Flasher/data/www/edit.html.gz differ diff --git a/ESP32_AP-Flasher/data/www/index.html.gz b/ESP32_AP-Flasher/data/www/index.html.gz index fe0ebc5f..de5a77f9 100644 Binary files a/ESP32_AP-Flasher/data/www/index.html.gz and b/ESP32_AP-Flasher/data/www/index.html.gz differ diff --git a/ESP32_AP-Flasher/data/www/main.js.gz b/ESP32_AP-Flasher/data/www/main.js.gz index 79187840..dab5e855 100644 Binary files a/ESP32_AP-Flasher/data/www/main.js.gz and b/ESP32_AP-Flasher/data/www/main.js.gz differ diff --git a/ESP32_AP-Flasher/include/commstructs.h b/ESP32_AP-Flasher/include/commstructs.h index 9aef661b..6e6f2b4f 100644 --- a/ESP32_AP-Flasher/include/commstructs.h +++ b/ESP32_AP-Flasher/include/commstructs.h @@ -126,4 +126,20 @@ struct tagsettings { uint8_t fixedChannel; // default 0; if set to a valid channel number, the tag will stick to that channel } __packed; +struct ledFlash { + uint8_t mode : 4; + uint8_t flashDuration : 4; + uint8_t color1; + uint8_t flashCount1 : 4; + uint8_t delay1 : 4; + uint8_t color2; + uint8_t flashCount2 : 4; + uint8_t delay2 : 4; + uint8_t color3; + uint8_t flashCount3 : 4; + uint8_t delay3 : 4; + uint8_t repeats; + uint8_t spare; +} __packed; + #pragma pack(pop) \ No newline at end of file diff --git a/ESP32_AP-Flasher/include/ips_display.h b/ESP32_AP-Flasher/include/ips_display.h new file mode 100644 index 00000000..eb86a2fe --- /dev/null +++ b/ESP32_AP-Flasher/include/ips_display.h @@ -0,0 +1,12 @@ +#include +#include + +#ifdef YELLOW_IPS_AP + +extern TFT_eSPI tft2; +extern int32_t tftid; +extern uint8_t YellowSense; + +void TFTLog(String text); + +#endif diff --git a/ESP32_AP-Flasher/include/newproto.h b/ESP32_AP-Flasher/include/newproto.h index 8b6abcce..84ceb82a 100644 --- a/ESP32_AP-Flasher/include/newproto.h +++ b/ESP32_AP-Flasher/include/newproto.h @@ -13,7 +13,7 @@ extern void processXferComplete(struct espXferComplete* xfc, bool local); extern void processXferTimeout(struct espXferComplete* xfc, bool local); extern void processDataReq(struct espAvailDataReq* adr, bool local); -extern bool sendTagCommand(const uint8_t* dst, uint8_t cmd, bool local); +extern bool sendTagCommand(const uint8_t* dst, uint8_t cmd, bool local, const uint8_t* payload = nullptr); extern bool sendAPSegmentedData(const uint8_t* dst, String data, uint16_t icons, bool inverted, bool local); extern bool showAPSegmentedInfo(const uint8_t* dst, bool local); extern void updateTaginfoitem(struct TagInfo* taginfoitem, IPAddress remoteIP); diff --git a/ESP32_AP-Flasher/include/system.h b/ESP32_AP-Flasher/include/system.h index fd0deca2..e197cee1 100644 --- a/ESP32_AP-Flasher/include/system.h +++ b/ESP32_AP-Flasher/include/system.h @@ -4,6 +4,8 @@ #define WAKEUP_REASON_BOOT 1 #define WAKEUP_REASON_GPIO 2 #define WAKEUP_REASON_NFC 3 +#define WAKEUP_REASON_BUTTON1 4 +#define WAKEUP_REASON_BUTTON2 5 #define WAKEUP_REASON_FIRSTBOOT 0xFC #define WAKEUP_REASON_NETWORK_SCAN 0xFD #define WAKEUP_REASON_WDT_RESET 0xFE diff --git a/ESP32_AP-Flasher/include/tag_db.h b/ESP32_AP-Flasher/include/tag_db.h index 1d415fb7..df19cd22 100644 --- a/ESP32_AP-Flasher/include/tag_db.h +++ b/ESP32_AP-Flasher/include/tag_db.h @@ -11,6 +11,8 @@ #define WAKEUP_REASON_BOOTUP 1 #define WAKEUP_REASON_GPIO 2 #define WAKEUP_REASON_NFC 3 +#define WAKEUP_REASON_BUTTON1 4 +#define WAKEUP_REASON_BUTTON2 5 #define RUNSTATUS_STOP 0 #define RUNSTATUS_PAUSE 1 diff --git a/ESP32_AP-Flasher/include/wifimanager.h b/ESP32_AP-Flasher/include/wifimanager.h index ae4294ac..35e47536 100644 --- a/ESP32_AP-Flasher/include/wifimanager.h +++ b/ESP32_AP-Flasher/include/wifimanager.h @@ -40,6 +40,7 @@ class WifiManager { bool waitForConnection(); void pollSerial(); + static void terminalLog(String text); public: WifiManager(); diff --git a/ESP32_AP-Flasher/platformio.ini b/ESP32_AP-Flasher/platformio.ini index 71a16e4f..fb1832c2 100644 --- a/ESP32_AP-Flasher/platformio.ini +++ b/ESP32_AP-Flasher/platformio.ini @@ -280,9 +280,13 @@ build_flags = -D FLASHER_AP_TEST=-1 -D FLASHER_AP_TXD=17 -D FLASHER_AP_RXD=18 - -D FLASHER_LED=14 + -D FLASHER_DEBUG_TXD=19 + -D FLASHER_DEBUG_RXD=20 + -D FLASHER_LED=16 + -D HAS_RGB_LED + -D FLASHER_RGB_LED=48 -D ST7789_DRIVER - -D TFT_WIDTH=170 + -D TFT_WIDTH=172 -D TFT_HEIGHT=320 -D TFT_MISO=-1 -D TFT_MOSI=13 diff --git a/ESP32_AP-Flasher/src/ips_display.cpp b/ESP32_AP-Flasher/src/ips_display.cpp index 4478c9bc..4bbc7dc5 100644 --- a/ESP32_AP-Flasher/src/ips_display.cpp +++ b/ESP32_AP-Flasher/src/ips_display.cpp @@ -1,7 +1,5 @@ -#ifdef YELLOW_IPS_AP #include #include -#include #include #include "commstructs.h" @@ -9,11 +7,45 @@ #include "storage.h" #include "tag_db.h" +#ifdef YELLOW_IPS_AP + +#include "ips_display.h" + +#define YELLOW_SENSE 8 // sense AP hardware +#define TFT_BACKLIGHT 14 + TFT_eSPI tft2 = TFT_eSPI(); -bool first_run = 0; -time_t last_update = 0; -time_t last_checkin = 0; int32_t tftid = -1; +uint8_t YellowSense = 0; +bool tftLogscreen = true; + +void TFTLog(String text) { + if (tftLogscreen == false) { + tft2.fillScreen(TFT_BLACK); + tft2.setCursor(0, 5, 2); + tftLogscreen = true; + } + if (text.isEmpty()) return; + tft2.setTextColor(TFT_SILVER); + if (text.startsWith("!")) { + tft2.setTextColor(TFT_RED); + text = text.substring(1); + } else if (text.indexOf("http") != -1) { + int httpIndex = text.indexOf("http"); + tft2.print(text.substring(0, httpIndex)); + tft2.setTextColor(TFT_YELLOW); + text = text.substring(httpIndex); + } else if (text.indexOf(":") != -1) { + int colonIndex = text.indexOf(":"); + tft2.setTextColor(TFT_SILVER); + tft2.print(text.substring(0, colonIndex + 1)); + tft2.setTextColor(TFT_WHITE); + text = text.substring(colonIndex + 1); + } else if (text.endsWith("!")) { + tft2.setTextColor(TFT_GREEN); + } + tft2.println(text); +} int32_t findId(uint8_t mac[8]) { for (uint32_t c = 0; c < tagDB.size(); c++) { @@ -42,28 +74,43 @@ void sendAvail(uint8_t wakeupReason) { } void yellow_ap_display_init(void) { + + pinMode(YELLOW_SENSE, INPUT_PULLDOWN); + vTaskDelay(100 / portTICK_PERIOD_MS); + if (digitalRead(YELLOW_SENSE) == HIGH) YellowSense = 1; + + pinMode(TFT_BACKLIGHT, OUTPUT); + digitalWrite(TFT_BACKLIGHT, HIGH); + + ledcSetup(6, 5000, 8); + ledcAttachPin(TFT_BACKLIGHT, 6); + ledcWrite(6, 255); // config.led + tft2.init(); - tft2.setRotation(3); + tft2.setRotation(YellowSense == 1 ? 1 : 3); tft2.fillScreen(TFT_BLACK); - tft2.setCursor(0, 0, 2); + tft2.setCursor(10, 5, 2); tft2.setTextColor(TFT_WHITE); - tft2.println(" Init\n"); + tft2.println("*** Initialising... ***"); + tftLogscreen = true; } void yellow_ap_display_loop(void) { + static bool first_run = 0; + static time_t last_checkin = 0; + static time_t last_update = 0; + if (millis() - last_checkin >= 60000) { sendAvail(0); last_checkin = millis(); + tftLogscreen = false; + } + if (first_run == 0) { + sendAvail(0xFC); + first_run = 1; } if (millis() - last_update >= 1000) { - if (first_run == 0) { - sendAvail(0xFC); - first_run = 1; - } - - // if ((uint32_t)WiFi.localIP() == (uint32_t)0) {} - tagRecord* tag = tagDB.at(tftid); if (tag->pending) { String filename = tag->filename; @@ -82,6 +129,7 @@ void yellow_ap_display_loop(void) { size_t bytesRead = file.readBytes((char*)spriteData, spr.width() * spr.height() * 2); file.close(); spr.pushSprite(0, 0); + tftLogscreen = false; struct espXferComplete xfc = {0}; memcpy(xfc.src, tag->mac, 8); diff --git a/ESP32_AP-Flasher/src/leds.cpp b/ESP32_AP-Flasher/src/leds.cpp index 77183142..a68b189f 100644 --- a/ESP32_AP-Flasher/src/leds.cpp +++ b/ESP32_AP-Flasher/src/leds.cpp @@ -149,6 +149,9 @@ void rgbIdleStep() { void setBrightness(int brightness) { maxledbrightness = brightness; +#ifdef YELLOW_IPS_AP + // ledcWrite(6, config.led); +#endif #ifdef HAS_RGB_LED FastLED.setBrightness(maxledbrightness); #endif @@ -180,10 +183,10 @@ void addFadeMono(uint8_t value) { } void showMono(uint8_t brightness) { -#ifdef CONFIG_IDF_TARGET_ESP32S2 - ledcWrite(7, gamma8[brightness]); -#else +#ifdef CONFIG_IDF_TARGET_ESP32 ledcWrite(7, 255 - gamma8[brightness]); +#else + ledcWrite(7, gamma8[brightness]); #endif } diff --git a/ESP32_AP-Flasher/src/makeimage.cpp b/ESP32_AP-Flasher/src/makeimage.cpp index ea891d05..35c0bd2d 100644 --- a/ESP32_AP-Flasher/src/makeimage.cpp +++ b/ESP32_AP-Flasher/src/makeimage.cpp @@ -209,8 +209,9 @@ void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) { Storage.begin(); #ifdef YELLOW_IPS_AP + extern uint8_t YellowSense; if (fileout == "direct") { - tft.setRotation(3); + tft.setRotation(YellowSense == 1 ? 1 : 3); spr.pushSprite(0, 0); return; } diff --git a/ESP32_AP-Flasher/src/newproto.cpp b/ESP32_AP-Flasher/src/newproto.cpp index 47b7af5e..da588b47 100644 --- a/ESP32_AP-Flasher/src/newproto.cpp +++ b/ESP32_AP-Flasher/src/newproto.cpp @@ -600,12 +600,16 @@ bool showAPSegmentedInfo(const uint8_t* dst, bool local) { } } -bool sendTagCommand(const uint8_t* dst, uint8_t cmd, bool local) { +bool sendTagCommand(const uint8_t* dst, uint8_t cmd, bool local, const uint8_t* payload) { struct pendingData pending = {0}; memcpy(pending.targetMac, dst, 8); pending.availdatainfo.dataType = DATATYPE_COMMAND_DATA; pending.availdatainfo.dataTypeArgument = cmd; pending.availdatainfo.nextCheckIn = 0; + if (payload != nullptr) { + memcpy(&pending.availdatainfo.dataVer, payload, sizeof(uint64_t)); + memcpy(&pending.availdatainfo.dataSize, payload + sizeof(uint64_t), sizeof(uint32_t)); + } pending.attemptsLeft = 120; Serial.printf(">Tag CMD %02X%02X%02X%02X%02X%02X%02X%02X\n\0", dst[7], dst[6], dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]); if (local) { diff --git a/ESP32_AP-Flasher/src/serialap.cpp b/ESP32_AP-Flasher/src/serialap.cpp index de8a2e4a..5f7ad4df 100644 --- a/ESP32_AP-Flasher/src/serialap.cpp +++ b/ESP32_AP-Flasher/src/serialap.cpp @@ -88,7 +88,7 @@ void txEnd() { } bool waitCmdReply() { uint32_t val = millis(); - while (millis() < val + 100) { + while (millis() < val + 200) { switch (cmdReplyValue) { case CMD_REPLY_WAIT: break; @@ -135,6 +135,7 @@ void APEnterEarlyReset() { // Reset the tag void APTagReset() { + Serial.println("Resetting tag"); uint8_t powerPins = sizeof(APpowerPins); if (powerPins > 0 && APpowerPins[0] == -1) powerPins = 0; @@ -193,7 +194,7 @@ blksend: for (c = 0; c < 32; c++) { AP_SERIAL_PORT.write(0xF5); } - delay(10); + if (apInfo.type != ESP32_C6) delay(10); txEnd(); return bd->checksum; } @@ -250,6 +251,8 @@ bool sendChannelPower(struct espSetChannelPower* scp) { } if (waitCmdReply()) { txEnd(); + apInfo.channel = scp->channel; + apInfo.power = scp->power; return true; } Serial.printf("SCP send failed in try %d\n", attempt); @@ -259,10 +262,27 @@ bool sendChannelPower(struct espSetChannelPower* scp) { return false; } bool sendPing() { + Serial.print("ping"); + int t = millis(); if (!txStart()) return false; for (uint8_t attempt = 0; attempt < 5; attempt++) { cmdReplyValue = CMD_REPLY_WAIT; AP_SERIAL_PORT.print("RDY?"); + if (waitCmdReply()) { + txEnd(); + Serial.printf(" ok, %dms\n", millis() - t); + return true; + } + } + txEnd(); + Serial.println(" failed"); + return false; +} +bool sendGetInfo() { + if (!txStart()) return false; + for (uint8_t attempt = 0; attempt < 5; attempt++) { + cmdReplyValue = CMD_REPLY_WAIT; + AP_SERIAL_PORT.print("NFO?"); if (waitCmdReply()) { txEnd(); return true; @@ -271,11 +291,11 @@ bool sendPing() { txEnd(); return false; } -bool sendGetInfo() { +bool sendHighspeed() { if (!txStart()) return false; for (uint8_t attempt = 0; attempt < 5; attempt++) { cmdReplyValue = CMD_REPLY_WAIT; - AP_SERIAL_PORT.print("NFO?"); + AP_SERIAL_PORT.print("HSPD"); if (waitCmdReply()) { txEnd(); return true; @@ -312,17 +332,15 @@ void rxCmdProcessor(void* parameter) { processBlockRequest((struct espBlockRequest*)rxcmd->data); #ifdef HAS_RGB_LED shortBlink(CRGB::Blue); -#else - quickBlink(3); #endif + quickBlink(3); break; case RX_CMD_ADR: processDataReq((struct espAvailDataReq*)rxcmd->data, true); #ifdef HAS_RGB_LED shortBlink(CRGB::Aqua); -#else - quickBlink(1); #endif + quickBlink(1); break; case RX_CMD_XFC: processXferComplete((struct espXferComplete*)rxcmd->data, true); @@ -336,6 +354,7 @@ void rxCmdProcessor(void* parameter) { case RX_CMD_RSET: Serial.println("AP did reset, resending pending\n"); refreshAllPending(); + sendChannelPower(&curChannel); break; } if (rxcmd->data) free(rxcmd->data); @@ -357,7 +376,7 @@ void rxSerialTask(void* parameter) { lastchar = AP_SERIAL_PORT.read(); switch (RXState) { case ZBS_RX_WAIT_HEADER: - // Serial.write(lastchar); + Serial.write(lastchar); // shift characters in for (uint8_t c = 0; c < 3; c++) { cmdbuffer[c] = cmdbuffer[c + 1]; @@ -413,6 +432,7 @@ void rxSerialTask(void* parameter) { pktindex = 0; packetp = (uint8_t*)calloc(sizeof(struct espBlockRequest) + 8, 1); memset(cmdbuffer, 0x00, 4); + lastAPActivity = millis(); } if (strncmp(cmdbuffer, "ADR>", 4) == 0) { RXState = ZBS_RX_WAIT_DATA_REQ; @@ -420,6 +440,7 @@ void rxSerialTask(void* parameter) { pktindex = 0; packetp = (uint8_t*)calloc(sizeof(struct espAvailDataReq) + 8, 1); memset(cmdbuffer, 0x00, 4); + lastAPActivity = millis(); } if (strncmp(cmdbuffer, "XFC>", 4) == 0) { RXState = ZBS_RX_WAIT_XFERCOMPLETE; @@ -536,21 +557,26 @@ void rxSerialTask(void* parameter) { } // end of while(1) } +#ifdef FLASHER_DEBUG_RXD +void rxSerialTask2(void* parameter) { + char lastchar = 0; + Serial2.begin(115200, SERIAL_8N1, FLASHER_DEBUG_TXD, FLASHER_DEBUG_RXD); + while (1) { + while (Serial2.available()) { + lastchar = Serial2.read(); + Serial.write(lastchar); + } + vTaskDelay(1 / portTICK_PERIOD_MS); + } +} +#endif + void ShowAPInfo() { - Serial.printf("| AP Info - type %02X |\n", apInfo.type); + Serial.printf("\n| AP Info - type %02X |\n", apInfo.type); Serial.printf("| Ch | 0x%02X |\n", apInfo.channel); Serial.printf("| Power| %02X |\n", apInfo.power); Serial.printf("| MAC | %02X%02X%02X%02X%02X%02X%02X%02X |\n", apInfo.mac[7], apInfo.mac[6], apInfo.mac[5], apInfo.mac[4], apInfo.mac[3], apInfo.mac[2], apInfo.mac[1], apInfo.mac[0]); Serial.printf("| Ver | 0x%04X |\n", apInfo.version); - - /*if (apInfo.type == SOLUM_154_SSD1619 || apInfo.type == SOLUM_29_SSD1619 || apInfo.type == SOLUM_29_UC8151 || apInfo.type == 0xE0) { - tagRecord* taginfo = nullptr; - taginfo = tagRecord::findByMAC(apInfo.mac); - if (taginfo != nullptr) { - taginfo->contentMode = 21; - taginfo->nextupdate = 0; - } - }*/ } void notifySegmentedFlash() { @@ -595,14 +621,24 @@ void segmentedShowIp() { bool bringAPOnline() { apInfo.isOnline = false; apInfo.state = AP_STATE_OFFLINE; - APTagReset(); - vTaskDelay(500 / portTICK_PERIOD_MS); + // try without rebooting + AP_SERIAL_PORT.updateBaudRate(115200); uint32_t bootTimeout = millis(); bool APrdy = false; - while ((!APrdy) && (millis() - bootTimeout < 10 * 1000)) { + while ((!APrdy) && (millis() - bootTimeout < 3 * 1000)) { APrdy = sendPing(); vTaskDelay(300 / portTICK_PERIOD_MS); } + if (!APrdy) { + APTagReset(); + vTaskDelay(500 / portTICK_PERIOD_MS); + bootTimeout = millis(); + APrdy = false; + while ((!APrdy) && (millis() - bootTimeout < 10 * 1000)) { + APrdy = sendPing(); + vTaskDelay(300 / portTICK_PERIOD_MS); + } + } if (!APrdy) { return false; } else { @@ -613,6 +649,15 @@ bool bringAPOnline() { apInfo.state = AP_STATE_OFFLINE; return false; } + if (apInfo.type == ESP32_C6) { + if (sendHighspeed()) { + AP_SERIAL_PORT.flush(); + vTaskDelay(10 / portTICK_PERIOD_MS); + AP_SERIAL_PORT.updateBaudRate(2000000); + Serial.println("switched to 2000000 baud"); + } + } + vTaskDelay(200 / portTICK_PERIOD_MS); apInfo.isOnline = true; apInfo.state = AP_STATE_ONLINE; @@ -623,6 +668,9 @@ bool bringAPOnline() { void APTask(void* parameter) { xTaskCreate(rxCmdProcessor, "rxCmdProcessor", 4000, NULL, configMAX_PRIORITIES - 10, NULL); xTaskCreate(rxSerialTask, "rxSerialTask", 1750, NULL, configMAX_PRIORITIES - 4, NULL); +#ifdef FLASHER_DEBUG_RXD + xTaskCreate(rxSerialTask2, "rxSerialTask2", 1750, NULL, configMAX_PRIORITIES - 4, NULL); +#endif #if (AP_PROCESS_PORT == FLASHER_AP_PORT) AP_SERIAL_PORT.begin(115200, SERIAL_8N1, FLASHER_AP_RXD, FLASHER_AP_TXD); @@ -638,7 +686,7 @@ void APTask(void* parameter) { bringAPOnline(); - if (checkForcedAPFlash()) { + if (checkForcedAPFlash() && FLASHER_AP_MOSI != -1) { if (apInfo.type == SOLUM_SEG_UK && apInfo.isOnline) { notifySegmentedFlash(); } @@ -666,7 +714,7 @@ void APTask(void* parameter) { uint16_t fsversion; fsversion = getAPUpdateVersion(apInfo.type); - if ((fsversion) && (apInfo.version != fsversion)) { + if ((fsversion) && (apInfo.version != fsversion) && (FLASHER_AP_MOSI != -1)) { Serial.printf("Firmware version on LittleFS: %04X\n", fsversion); Serial.printf("We're going to try to update the AP's FW in\n"); @@ -708,72 +756,74 @@ void APTask(void* parameter) { // AP unavailable, maybe time to flash? apInfo.isOnline = false; apInfo.state = AP_STATE_OFFLINE; - Serial.println("I wasn't able to connect to a ZBS (AP) tag.\n"); - Serial.printf("This could be the first time this AP is booted and the AP-tag may be unflashed. We'll try to flash it!\n"); + Serial.printf("I wasn't able to connect to a ZBS (AP) tag.\n"); + Serial.printf("This could be the first time this AP is booted and the AP-tag may be unflashed.\n"); Serial.printf("If this tag was previously flashed succesfully but this message still shows up, there's probably something wrong with the serial connections.\n"); Serial.printf("The build of this firmware expects an AP tag with TXD/RXD on ESP32 pins %d and %d, does this match with your wiring?\n", FLASHER_AP_RXD, FLASHER_AP_TXD); - Serial.printf("Performing firmware flash in about %d seconds!\n", FLASH_TIMEOUT); - flashCountDown(FLASH_TIMEOUT); - if (doAPFlash()) { - checkWaitPowerCycle(); - if (bringAPOnline()) { - // AP works - ShowAPInfo(); - if (apInfo.type == SOLUM_SEG_UK) { - segmentedShowIp(); - showAPSegmentedInfo(apInfo.mac, true); - } - refreshAllPending(); - } else { - Serial.printf("Failed to bring up the AP after successful flashing... That's not supposed to happen!\n"); - Serial.printf("This generally means that the flasher connections (MISO/MOSI/CLK/RESET/CS) are okay,\n"); - Serial.printf("but we can't (yet) talk to the AP over serial lines. Verify the pins mentioned above.\n\n"); + if (FLASHER_AP_MOSI != -1) { + Serial.printf("Performing firmware flash in about %d seconds!\n", FLASH_TIMEOUT); + flashCountDown(FLASH_TIMEOUT); + if (doAPFlash()) { + checkWaitPowerCycle(); + if (bringAPOnline()) { + // AP works + ShowAPInfo(); + if (apInfo.type == SOLUM_SEG_UK) { + segmentedShowIp(); + showAPSegmentedInfo(apInfo.mac, true); + } + refreshAllPending(); + } else { + Serial.printf("Failed to bring up the AP after successful flashing... That's not supposed to happen!\n"); + Serial.printf("This generally means that the flasher connections (MISO/MOSI/CLK/RESET/CS) are okay,\n"); + Serial.printf("but we can't (yet) talk to the AP over serial lines. Verify the pins mentioned above.\n\n"); #ifndef POWER_NO_SOFT_POWER - Serial.printf("The firmware you're using expects soft power control over the AP tag; if it can't\n"); - Serial.printf("power-cycle the AP-tag using GPIO pin %d, this can cause this very same issue.\n", APpowerPins[0]); + Serial.printf("The firmware you're using expects soft power control over the AP tag; if it can't\n"); + Serial.printf("power-cycle the AP-tag using GPIO pin %d, this can cause this very same issue.\n", APpowerPins[0]); #endif #ifdef HAS_RGB_LED - showColorPattern(CRGB::Red, CRGB::Yellow, CRGB::Red); + showColorPattern(CRGB::Red, CRGB::Yellow, CRGB::Red); +#endif + apInfo.isOnline = false; + apInfo.state = AP_STATE_FAILED; + } + } else { + // failed to flash +#ifdef HAS_RGB_LED + showColorPattern(CRGB::Red, CRGB::Red, CRGB::Red); #endif apInfo.isOnline = false; apInfo.state = AP_STATE_FAILED; - } - } else { - // failed to flash -#ifdef HAS_RGB_LED - showColorPattern(CRGB::Red, CRGB::Red, CRGB::Red); -#endif - apInfo.isOnline = false; - apInfo.state = AP_STATE_FAILED; - Serial.println("Failed to flash the AP :("); - Serial.println("Seems like you're running into some issues with the wiring, or (very small chance) the tag itself"); - Serial.println("This ESP32-build expects the following pins connected to the ZBS243:"); - Serial.println("--- ZBS243 based tag ESP32 ---"); - Serial.printf(" TXD ---------------- %02d\n", FLASHER_AP_RXD); - Serial.printf(" RXD ---------------- %02d\n", FLASHER_AP_TXD); - Serial.printf(" CS/SS ---------------- %02d\n", FLASHER_AP_SS); - Serial.printf(" MOSI ---------------- %02d\n", FLASHER_AP_MOSI); - Serial.printf(" MISO ---------------- %02d\n", FLASHER_AP_MISO); - Serial.printf(" CLK ---------------- %02d\n", FLASHER_AP_CLK); - Serial.printf(" RSET ---------------- %02d\n", FLASHER_AP_RESET); + Serial.println("Failed to flash the AP :("); + Serial.println("Seems like you're running into some issues with the wiring, or (very small chance) the tag itself"); + Serial.println("This ESP32-build expects the following pins connected to the ZBS243:"); + Serial.println("--- ZBS243 based tag ESP32 ---"); + Serial.printf(" TXD ---------------- %02d\n", FLASHER_AP_RXD); + Serial.printf(" RXD ---------------- %02d\n", FLASHER_AP_TXD); + Serial.printf(" CS/SS ---------------- %02d\n", FLASHER_AP_SS); + Serial.printf(" MOSI ---------------- %02d\n", FLASHER_AP_MOSI); + Serial.printf(" MISO ---------------- %02d\n", FLASHER_AP_MISO); + Serial.printf(" CLK ---------------- %02d\n", FLASHER_AP_CLK); + Serial.printf(" RSET ---------------- %02d\n", FLASHER_AP_RESET); #ifdef POWER_NO_SOFT_POWER - Serial.printf("Your firmware is configured without soft power control. This means you'll have to manually power-cycle the tag after flashing.\n"); + Serial.printf("Your firmware is configured without soft power control. This means you'll have to manually power-cycle the tag after flashing.\n"); #else - Serial.printf(" POWER ---------------- %02d\n", APpowerPins[0]); + Serial.printf(" POWER ---------------- %02d\n", APpowerPins[0]); #endif - Serial.println("Please verify your wiring and try again!"); - } + Serial.println("Please verify your wiring and try again!"); + } #ifdef HAS_SDCARD - if (SD_CARD_CLK == FLASHER_AP_CLK || - SD_CARD_MISO == FLASHER_AP_MISO || - SD_CARD_MOSI == FLASHER_AP_MOSI) { - Serial.println("Reseting in 30 seconds to restore SPI state!\n"); - flashCountDown(30); - ESP.restart(); - } + if (SD_CARD_CLK == FLASHER_AP_CLK || + SD_CARD_MISO == FLASHER_AP_MISO || + SD_CARD_MOSI == FLASHER_AP_MOSI) { + Serial.println("Reseting in 30 seconds to restore SPI state!\n"); + flashCountDown(30); + ESP.restart(); + } #endif + } } uint8_t attempts = 0; diff --git a/ESP32_AP-Flasher/src/web.cpp b/ESP32_AP-Flasher/src/web.cpp index d87ecabb..78a95cde 100644 --- a/ESP32_AP-Flasher/src/web.cpp +++ b/ESP32_AP-Flasher/src/web.cpp @@ -77,14 +77,16 @@ void wsSendSysteminfo() { time_t now; time(&now); static int freeSpaceLastRun = 0; + static size_t freeSpace = Storage.freeSpace(); sys["currtime"] = now; sys["heap"] = ESP.getFreeHeap(); sys["recordcount"] = tagDB.size(); sys["dbsize"] = dbSize(); if (millis() - freeSpaceLastRun > 30000) { - sys["littlefsfree"] = Storage.freeSpace(); + freeSpace = Storage.freeSpace(); freeSpaceLastRun = millis(); } + sys["littlefsfree"] = freeSpace; sys["apstate"] = apInfo.state; sys["runstate"] = config.runStatus; #if !defined(CONFIG_IDF_TARGET_ESP32) @@ -98,7 +100,7 @@ void wsSendSysteminfo() { setVarDB("ap_ch", String(apInfo.channel)); static uint32_t tagcounttimer = 0; - if (millis() - tagcounttimer > 60000) { + if (millis() - tagcounttimer > 60000 || tagcounttimer == 0) { uint32_t timeoutcount = 0; uint32_t tagcount = getTagCount(timeoutcount); char result[40]; @@ -318,9 +320,11 @@ void init_web() { if (strcmp(cmdValue, "deepsleep") == 0) { sendTagCommand(mac, CMD_DO_DEEPSLEEP, !taginfo->isExternal); } + if (strcmp(cmdValue, "ledflash") == 0) { + } request->send(200, "text/plain", "Ok, done"); } else { - request->send(200, "text/plain", "Error: mac not found"); + request->send(400, "text/plain", "Error: mac not found"); } } } else { @@ -328,6 +332,55 @@ void init_web() { } }); + server.on("/led_flash", HTTP_GET, [](AsyncWebServerRequest *request) { + // color picker: https://roger-random.github.io/RGB332_color_wheel_three.js/ + // http GET to /led_flash?mac=000000000000&pattern=3/0x1C,4,5/0xE0,3,1/0x4F,5,10/5 + // (flashDuration/color1,flashCount1,delay1/color2,flashCount2,delay2/color3,flashCount3,delay3/repeats) + if (request->hasParam("mac")) { + String dst = request->getParam("mac")->value(); + uint8_t mac[8]; + if (hex2mac(dst, mac)) { + tagRecord *taginfo = tagRecord::findByMAC(mac); + if (taginfo != nullptr) { + if (request->hasParam("pattern")) { + String pattern = request->getParam("pattern")->value(); + struct ledFlash flashData; + + int values[13]; + int numValues = sscanf( + pattern.c_str(), + "%i/%i,%i,%i/%i,%i,%i/%i,%i,%i/%i", + &values[1], &values[2], &values[3], &values[4], &values[5], + &values[6], &values[7], &values[8], &values[9], &values[10], &values[11]); + + if (numValues != 11) { + request->send(400, "text/plain", "Error: wrong number of inputs in pattern"); + return; + } else { + flashData.mode = 0; + flashData.flashDuration = values[1] & 0x0F; + flashData.color1 = values[2]; + flashData.flashCount1 = values[3] & 0x0F; + flashData.delay1 = values[4] & 0x0F; + flashData.color2 = values[5]; + flashData.flashCount2 = values[6] & 0x0F; + flashData.delay2 = values[7] & 0x0F; + flashData.color3 = values[8]; + flashData.flashCount3 = values[9] & 0x0F; + flashData.delay3 = values[10] & 0x0F; + flashData.repeats = values[11]; + flashData.spare = 0; + + const uint8_t *payload = reinterpret_cast(&flashData); + sendTagCommand(mac, CMD_DO_LEDFLASH, !taginfo->isExternal, payload); + } + } + } + } + } + request->send(400, "text/plain", "parameters are missing"); + }); + server.on("/get_ap_config", HTTP_GET, [](AsyncWebServerRequest *request) { UDPcomm udpsync; udpsync.getAPList(); diff --git a/ESP32_AP-Flasher/src/wifimanager.cpp b/ESP32_AP-Flasher/src/wifimanager.cpp index 1c2e523a..37fd0900 100644 --- a/ESP32_AP-Flasher/src/wifimanager.cpp +++ b/ESP32_AP-Flasher/src/wifimanager.cpp @@ -9,6 +9,7 @@ #include "tag_db.h" #include "udp.h" #include "web.h" +#include "ips_display.h" uint8_t WifiManager::apClients = 0; uint8_t x_buffer[100]; @@ -29,10 +30,17 @@ WifiManager::WifiManager() { WiFi.onEvent(WiFiEvent); } +void WifiManager::terminalLog(String text) { + Serial.println(text); +#ifdef YELLOW_IPS_AP + TFTLog(text); +#endif +} + void WifiManager::poll() { if (wifiStatus == AP && millis() > _nextReconnectCheck && _ssid != "") { if (apClients == 0) { - Serial.println("Attempting to reconnect to WiFi."); + terminalLog("Attempting to reconnect to WiFi."); logLine("Attempting to reconnect to WiFi."); _APstarted = false; wifiStatus = NOINIT; @@ -45,7 +53,7 @@ void WifiManager::poll() { if (wifiStatus == CONNECTED && millis() > _nextReconnectCheck) { if (WiFi.status() != WL_CONNECTED) { _connected = false; - Serial.println("WiFi connection lost. Attempting to reconnect."); + terminalLog("WiFi connection lost. Attempting to reconnect."); logLine("WiFi connection lost. Attempting to reconnect."); WiFi.reconnect(); waitForConnection(); @@ -63,12 +71,12 @@ bool WifiManager::connectToWifi() { _ssid = preferences.getString("ssid", WiFi_SSID()); _pass = preferences.getString("pw", WiFi_psk()); if (_ssid == "") { - Serial.println("No connection information specified"); - logLine("No connection information specified"); + terminalLog("No connection information saved"); + logLine("No connection information saved"); startManagementServer(); return false; } - Serial.println("Stored ssid: " + String(_ssid)); + terminalLog("Stored ssid: " + String(_ssid)); String ip = preferences.getString("ip", ""); String mask = preferences.getString("mask", ""); @@ -80,7 +88,7 @@ bool WifiManager::connectToWifi() { if (staticIP.fromString(ip) && subnetMask.fromString(mask) && gatewayIP.fromString(gw)) { if (dns.length() > 0) dnsIP.fromString(dns); WiFi.config(staticIP, gatewayIP, subnetMask, dnsIP); - Serial.println("Setting static IP"); + terminalLog("Setting static IP: " + ip); } } @@ -98,7 +106,7 @@ bool WifiManager::connectToWifi(String ssid, String pass, bool savewhensuccessfu WiFi.mode(WIFI_STA); WiFi.setSleep(WIFI_PS_NONE); - Serial.println("Connecting to WiFi..."); + terminalLog("Connecting to WiFi..."); logLine("Connecting to WiFi..."); WiFi.persistent(savewhensuccessfull); WiFi.begin(_ssid.c_str(), _pass.c_str()); @@ -112,7 +120,7 @@ bool WifiManager::waitForConnection() { while (WiFi.status() != WL_CONNECTED) { if (millis() > timeout) { - Serial.println("Unable to connect to WiFi"); + terminalLog("!Unable to connect to WiFi"); logLine("Unable to connect to WiFi"); startManagementServer(); return false; @@ -131,8 +139,8 @@ bool WifiManager::waitForConnection() { WiFi.setAutoReconnect(true); WiFi.persistent(true); IPAddress IP = WiFi.localIP(); - Serial.printf("Connected! IP Address: %s\n", IP.toString().c_str()); - logLine("Connected! IP Address: " + String(IP.toString().c_str())); + terminalLog("Connected!"); + logLine("Connected!"); _nextReconnectCheck = millis() + _reconnectIntervalCheck; wifiStatus = CONNECTED; return true; @@ -140,13 +148,13 @@ bool WifiManager::waitForConnection() { void WifiManager::startManagementServer() { if (!_APstarted) { - Serial.println("Starting configuration AP, ssid OpenEPaperLink"); + terminalLog("Starting configuration AP, ssid: OpenEPaperLink"); logLine("Starting configuration AP, ssid OpenEPaperLink"); WiFi.mode(WIFI_AP); WiFi.softAP("OpenEPaperLink", "", 1, false); WiFi.softAPsetHostname("OpenEPaperLink"); IPAddress IP = WiFi.softAPIP(); - Serial.printf("IP Address: %s\n", IP.toString().c_str()); + terminalLog("Connect to it, visit http://" + String(IP.toString().c_str()) + "/setup"); _APstarted = true; _nextReconnectCheck = millis() + _retryIntervalCheck; wifiStatus = AP; @@ -194,7 +202,7 @@ void WifiManager::WiFiEvent(WiFiEvent_t event) { eventname = "Connected to access point"; break; case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: - eventname = "Disconnected from WiFi access point"; + // eventname = "Disconnected from WiFi access point"; break; case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE: eventname = "Authentication mode of access point has changed"; @@ -208,27 +216,27 @@ void WifiManager::WiFiEvent(WiFiEvent_t event) { break; case ARDUINO_EVENT_WIFI_AP_START: - eventname = "WiFi access point started"; + // eventname = "WiFi access point started"; break; case ARDUINO_EVENT_WIFI_AP_STOP: - eventname = "WiFi access point stopped"; + // eventname = "WiFi access point stopped"; break; case ARDUINO_EVENT_WIFI_AP_STACONNECTED: apClients++; - eventname = "Client connected"; + // eventname = "Client connected"; break; case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED: apClients--; - eventname = "Client disconnected"; + // eventname = "Client disconnected"; break; case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED: - eventname = "Assigned IP address to client"; + // eventname = "Assigned IP address to client"; break; default: break; } - Serial.println(eventname); + terminalLog(eventname); logLine("WiFi event [" + String(event) + "]: " + eventname); } diff --git a/ESP32_AP-Flasher/wwwroot/edit.html b/ESP32_AP-Flasher/wwwroot/edit.html index 2ce7d145..90d2f95f 100644 --- a/ESP32_AP-Flasher/wwwroot/edit.html +++ b/ESP32_AP-Flasher/wwwroot/edit.html @@ -195,6 +195,8 @@ }