diff --git a/src/Makefile b/src/Makefile index 4e1b50a90..3535bcb92 100755 --- a/src/Makefile +++ b/src/Makefile @@ -131,6 +131,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \ framebuffer.o \ array.o \ usbdbg.o \ + wifi_dbg.o \ cambus.o \ ov9650.o \ ov2640.o \ diff --git a/src/omv/Makefile b/src/omv/Makefile index 9c86fe82d..cc26aade4 100644 --- a/src/omv/Makefile +++ b/src/omv/Makefile @@ -9,6 +9,7 @@ SRCS += $(addprefix , \ framebuffer.c \ array.c \ usbdbg.c \ + wifi_dbg.c \ cambus.c \ ov9650.c \ ov2640.c \ diff --git a/src/omv/main.c b/src/omv/main.c index 4c7f6df3e..200c39346 100644 --- a/src/omv/main.c +++ b/src/omv/main.c @@ -53,6 +53,7 @@ #include "sensor.h" #include "usbdbg.h" +#include "wifi_dbg.h" #include "sdram.h" #include "fb_alloc.h" #include "ff_wrapper.h" @@ -271,6 +272,14 @@ void NORETURN __stack_chk_fail(void) } #endif +typedef struct apply_settings_user +{ + wifi_dbg_settings_t wifi_dbg_settings; +} +apply_settings_user_t; + +extern char *strncpy(char *dst, const char *src, size_t n); + static bool ini_handler_callback_is_true(const char *value) { int i = ini_atoi(value); @@ -285,7 +294,7 @@ static bool ini_handler_callback_is_true(const char *value) int ini_handler_callback(void *user, const char *section, const char *name, const char *value) { - user = user; + apply_settings_user_t *apply_settings_user = (apply_settings_user_t *) user; #define MATCH(s, n) ((strcmp(section, (s)) == 0) && (strcmp(name, (n)) == 0)) @@ -298,6 +307,22 @@ int ini_handler_callback(void *user, const char *section, const char *name, cons MP_STATE_PORT(pyb_stdio_uart) = pyb_uart_type.make_new((mp_obj_t) &pyb_uart_type, MP_ARRAY_SIZE(args), 0, args); } + } else if (MATCH("BootSettings", "WiFiMode")) { + apply_settings_user->wifi_dbg_settings.wifi_mode = ini_atoi(value); + } else if (MATCH("BootSettings", "ClientModeSSID")) { + strncpy(apply_settings_user->wifi_dbg_settings.wifi_client_ssid, name, SSID_MAX); + } else if (MATCH("BootSettings", "ClientModePass")) { + strncpy(apply_settings_user->wifi_dbg_settings.wifi_client_pass, name, PASS_MAX); + } else if (MATCH("BootSettings", "ClientModeType")) { + apply_settings_user->wifi_dbg_settings.wifi_client_type = ini_atoi(value); + } else if (MATCH("BootSettings", "AccessPointModeSSID")) { + strncpy(apply_settings_user->wifi_dbg_settings.wifi_ap_ssid, name, SSID_MAX); + } else if (MATCH("BootSettings", "AccessPointModePass")) { + strncpy(apply_settings_user->wifi_dbg_settings.wifi_ap_pass, name, SSID_MAX); + } else if (MATCH("BootSettings", "AccessPointModeType")) { + apply_settings_user->wifi_dbg_settings.wifi_ap_type = ini_atoi(value); + } else if (MATCH("BootSettings", "BoardName")) { + strncpy(apply_settings_user->wifi_dbg_settings.wifi_board_name, name, NAME_MAX); } else { return 0; } @@ -314,7 +339,9 @@ FRESULT apply_settings(const char *path) if (f_res == FR_OK) { if (nlr_push(&nlr) == 0) { - ini_parse(&vfs_fat->fatfs, path, ini_handler_callback, NULL); + apply_settings_user_t apply_settings_user = {}; + ini_parse(&vfs_fat->fatfs, path, ini_handler_callback, &apply_settings_user); + wifi_dbg_apply_settings(&apply_settings_user.wifi_dbg_settings); nlr_pop(); } } @@ -441,6 +468,7 @@ soft_reset: py_fir_init0(); servo_init(); usbdbg_init(); + wifi_dbg_init(); if (first_soft_reset) { rtc_init_start(false); @@ -465,7 +493,7 @@ soft_reset: vfs_fat->flags = 0; sdcard_init_vfs(vfs_fat, 1); - // Try to mount the SD card + // Try to mount the SD card FRESULT res = f_mount(&vfs_fat->fatfs); if (res != FR_OK) { __fatal_error("Could not mount SD card\n"); diff --git a/src/omv/wifi_dbg.c b/src/omv/wifi_dbg.c new file mode 100644 index 000000000..c95529572 --- /dev/null +++ b/src/omv/wifi_dbg.c @@ -0,0 +1,65 @@ +/* This file is part of the OpenMV project. + * Copyright (c) 2013-2018 Ibrahim Abdelkader & Kwabena W. Agyeman + * This work is licensed under the MIT license, see the file LICENSE for details. + */ + +#include +#include "wifi_dbg.h" + +// To avoid writing extra code just re-use the USBDBG code as the interface that does the actual work. +// The only tricky part is that you don't have USB transactions anymore. So, you need to buffer 6 bytes +// in a fifo until you have 6 of them to execute a control phase. Then, push the rest into the data phase +// as described by the length in the control phase header. Buffering on the wifi network will definately +// cause all RX bytes to be in one long giant burst. You have to write the code to handle this... + +extern void usbdbg_data_in(void *buffer, int length); +extern void usbdbg_data_out(void *buffer, int length); +extern void usbdbg_control(void *buffer, uint8_t brequest, uint32_t wlength); + +void wifi_dbg_init() +{ + // Get wifi debug into a known state. Since this is called by all OpenMV Cams you should not toggle any + // pins unless you detect the wifi module was previously setup... + // Also, reset regular USB CDC DBG access if things were setup before. +} + +void wifi_dbg_apply_settings(wifi_dbg_settings_t *settings) +{ + switch(settings->wifi_mode) { + case WIFI_DBG_DISABLED: // Don't init anything. + break; + case WIFI_DBG_ENABLED_CLIENT_MODE: + // Start the wifi module up in client mode. + // Additionally, make network.WINC() return a python object of the setup wifi module and make + // winc.connect()/winc.disconnect() do nothing. This should allow the user to use the wifi module + // normally in their scripts in debug mode. + // You should have all the settings you need to init the wifi module in the settings struct. + // Disable regular USB CDC DBG if this works... two folks can't share the interface. + // For data transfer create a TCP server after setting up the wifi. You will then UDP broadcast + // your IP address along with the port you chose for the TCP server. OpenMV IDE will connect to this. + break; + case WIFI_DBG_ENABLED_AP_MODE: + // Start the wifi module up in ap mode. + // Additionally, make network.WINC() return a python object of the setup wifi module and make + // winc.connect()/winc.disconnect() do nothing. This should allow the user to use the wifi module + // normally in their scripts in debug mode. + // You should have all the settings you need to init the wifi module in the settings struct. + // Disable regular USB CDC DBG if this works... two folks can't share the interface. + // For data transfer create a TCP server after setting up the wifi. You will then UDP broadcast + // your IP address along with the port you chose for the TCP server. OpenMV IDE will connect to this. + break; + default: // Don't init anything. + break; + } +} + +void wifi_dbg_beacon() +{ + // Call this every second via a timer calback or something if wifi is enabled. + // You need to broadcast a UDP message on the OPENMVCAM_BROADCAST_PORT port. + // The contents of the message should be "ip:port:board_name", e.g. "192.168.2.1:4321:Ibrahim's cam". + // OpenMV splits the message using the ":" character. The port can by anything (whatever the module picks randomly). + // The IP address must be in dot format. Finally, the string can have whatever in it. + // If broadcasting is working the IDE should display a new board option to connect to when you hit connect. + // I'd get this working first for both AP and client mode before working on the rest of the code. +} diff --git a/src/omv/wifi_dbg.h b/src/omv/wifi_dbg.h new file mode 100644 index 000000000..376fe9e11 --- /dev/null +++ b/src/omv/wifi_dbg.h @@ -0,0 +1,47 @@ +/* This file is part of the OpenMV project. + * Copyright (c) 2013-2018 Ibrahim Abdelkader & Kwabena W. Agyeman + * This work is licensed under the MIT license, see the file LICENSE for details. + */ +#ifndef __WIFI_DBG_H__ +#define __WIFI_DBG_H__ + +#define SSID_MAX 63 +#define PASS_MAX 63 +#define NAME_MAX 63 + +#define OPENMVCAM_BROADCAST_PORT 0xABD1 + +typedef enum wifi_dbg_wifi_mode +{ + WIFI_DBG_DISABLED = 0, + WIFI_DBG_ENABLED_CLIENT_MODE = 1, + WIFI_DBG_ENABLED_AP_MODE = 2 +} +wifi_dbg_wifi_mode_t; + +typedef enum wifi_dbg_wifi_type +{ + WIFI_DBG_OPEN, + WIFI_DBG_WPA, + WIFI_DBG_WEP +} +wifi_dbg_wifi_type_t; + +typedef struct wifi_dbg_settings +{ + wifi_dbg_wifi_mode_t wifi_mode; + char wifi_client_ssid[SSID_MAX+1]; + char wifi_client_pass[PASS_MAX+1]; + wifi_dbg_wifi_type_t wifi_client_type; + char wifi_ap_ssid[SSID_MAX+1]; + char wifi_ap_pass[PASS_MAX+1]; + wifi_dbg_wifi_type_t wifi_ap_type; + char wifi_board_name[NAME_MAX+1]; +} +wifi_dbg_settings_t; + +void wifi_dbg_init(); +void wifi_dbg_apply_settings(wifi_dbg_settings_t *settings); +void wifi_dbg_beacon(); + +#endif /* __WIFI_DBG_H__ */