diff --git a/.gitignore b/.gitignore index f281811..f685d48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ -.DS_store -other/maple-bootloader/.dep -other/maple-bootloader/TAGS -other/maple-bootloader/tags -other/maple-bootloader/cscope.out -other/maple-bootloader/build -other/maple-bootloader/*~ +.DS_store +other/maple-bootloader/.dep +other/maple-bootloader/TAGS +other/maple-bootloader/tags +other/maple-bootloader/cscope.out +other/maple-bootloader/build +other/maple-bootloader/*~ +*.o +tools/src/stm32flash/src/parsers/parsers.a diff --git a/tools/src/stm32flash_serial/src/dev_table.o b/tools/src/stm32flash_serial/src/dev_table.o index 096f555..4ccec39 100644 Binary files a/tools/src/stm32flash_serial/src/dev_table.o and b/tools/src/stm32flash_serial/src/dev_table.o differ diff --git a/tools/src/stm32flash_serial/src/i2c.c b/tools/src/stm32flash_serial/src/i2c.c index 9079e01..10e6bb1 100644 --- a/tools/src/stm32flash_serial/src/i2c.c +++ b/tools/src/stm32flash_serial/src/i2c.c @@ -32,7 +32,7 @@ #include "port.h" -#if defined(__WIN32__) || defined(__CYGWIN__) || defined(__APPLE__) +#if !defined(__linux__) static port_err_t i2c_open(struct port_interface *port, struct port_options *ops) diff --git a/tools/src/stm32flash_serial/src/i2c.o b/tools/src/stm32flash_serial/src/i2c.o index 349064b..ad9b4e8 100644 Binary files a/tools/src/stm32flash_serial/src/i2c.o and b/tools/src/stm32flash_serial/src/i2c.o differ diff --git a/tools/src/stm32flash_serial/src/init.o b/tools/src/stm32flash_serial/src/init.o index 85f0f9b..36468ac 100644 Binary files a/tools/src/stm32flash_serial/src/init.o and b/tools/src/stm32flash_serial/src/init.o differ diff --git a/tools/src/stm32flash_serial/src/main.o b/tools/src/stm32flash_serial/src/main.o index de818c7..4b9c8bf 100644 Binary files a/tools/src/stm32flash_serial/src/main.o and b/tools/src/stm32flash_serial/src/main.o differ diff --git a/tools/src/stm32flash_serial/src/parsers/binary.o b/tools/src/stm32flash_serial/src/parsers/binary.o index e25fa95..51dd2d5 100644 Binary files a/tools/src/stm32flash_serial/src/parsers/binary.o and b/tools/src/stm32flash_serial/src/parsers/binary.o differ diff --git a/tools/src/stm32flash_serial/src/parsers/hex.o b/tools/src/stm32flash_serial/src/parsers/hex.o index 6055d4e..1de9478 100644 Binary files a/tools/src/stm32flash_serial/src/parsers/hex.o and b/tools/src/stm32flash_serial/src/parsers/hex.o differ diff --git a/tools/src/stm32flash_serial/src/parsers/parsers.a b/tools/src/stm32flash_serial/src/parsers/parsers.a index d782c6a..0429510 100644 Binary files a/tools/src/stm32flash_serial/src/parsers/parsers.a and b/tools/src/stm32flash_serial/src/parsers/parsers.a differ diff --git a/tools/src/stm32flash_serial/src/port.o b/tools/src/stm32flash_serial/src/port.o index 7ffb437..ab56ff0 100644 Binary files a/tools/src/stm32flash_serial/src/port.o and b/tools/src/stm32flash_serial/src/port.o differ diff --git a/tools/src/stm32flash_serial/src/serial_common.o b/tools/src/stm32flash_serial/src/serial_common.o index cfca421..615e5f9 100644 Binary files a/tools/src/stm32flash_serial/src/serial_common.o and b/tools/src/stm32flash_serial/src/serial_common.o differ diff --git a/tools/src/stm32flash_serial/src/serial_platform.o b/tools/src/stm32flash_serial/src/serial_platform.o index 9dfe3c6..cbc38db 100644 Binary files a/tools/src/stm32flash_serial/src/serial_platform.o and b/tools/src/stm32flash_serial/src/serial_platform.o differ diff --git a/tools/src/stm32flash_serial/src/serial_posix.c b/tools/src/stm32flash_serial/src/serial_posix.c index 46b8a94..30b5ff8 100644 --- a/tools/src/stm32flash_serial/src/serial_posix.c +++ b/tools/src/stm32flash_serial/src/serial_posix.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -197,13 +198,27 @@ static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, return PORT_ERR_OK; } +static int startswith(const char *haystack, const char *needle) { + return strncmp(haystack, needle, strlen(needle)) == 0; +} + +static int is_tty(const char *path) { + char resolved[PATH_MAX]; + + if(!realpath(path, resolved)) return 0; + + if(startswith(resolved, "/dev/tty")) return 1; + + return 0; +} + static port_err_t serial_posix_open(struct port_interface *port, struct port_options *ops) { serial_t *h; /* 1. check device name match */ - if (strncmp(ops->device, "/dev/tty", strlen("/dev/tty"))) + if (!is_tty(ops->device)) return PORT_ERR_NODEV; /* 2. check options */ diff --git a/tools/src/stm32flash_serial/src/serial_w32.c b/tools/src/stm32flash_serial/src/serial_w32.c index cf5cd39..56772c0 100644 --- a/tools/src/stm32flash_serial/src/serial_w32.c +++ b/tools/src/stm32flash_serial/src/serial_w32.c @@ -1,342 +1,341 @@ -/* - stm32flash - Open Source ST STM32 flash program for *nix - Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2010 Gareth McMullin - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "port.h" - -struct serial { - HANDLE fd; - DCB oldtio; - DCB newtio; - char setup_str[11]; -}; - -static serial_t *serial_open(const char *device) -{ - serial_t *h = calloc(sizeof(serial_t), 1); - char *devName; - - /* timeout in ms */ - COMMTIMEOUTS timeouts = {MAXDWORD, MAXDWORD, 500, 0, 0}; - - /* Fix the device name if required */ - if (strlen(device) > 4 && device[0] != '\\') { - devName = calloc(1, strlen(device) + 5); - sprintf(devName, "\\\\.\\%s", device); - } else { - devName = (char *)device; - } - - /* Create file handle for port */ - h->fd = CreateFile(devName, GENERIC_READ | GENERIC_WRITE, - 0, /* Exclusive access */ - NULL, /* No security */ - OPEN_EXISTING, - 0, /* No overlap */ - NULL); - - if (devName != device) - free(devName); - - if (h->fd == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_FILE_NOT_FOUND) - fprintf(stderr, "File not found: %s\n", device); - return NULL; - } - - SetupComm(h->fd, 4096, 4096); /* Set input and output buffer size */ - - SetCommTimeouts(h->fd, &timeouts); - - SetCommMask(h->fd, EV_ERR); /* Notify us of error events */ - - GetCommState(h->fd, &h->oldtio); /* Retrieve port parameters */ - GetCommState(h->fd, &h->newtio); /* Retrieve port parameters */ - - /* PurgeComm(h->fd, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); */ - - return h; -} - -static void serial_flush(const serial_t *h) -{ - /* We shouldn't need to flush in non-overlapping (blocking) mode */ - /* tcflush(h->fd, TCIFLUSH); */ -} - -static void serial_close(serial_t *h) -{ - serial_flush(h); - SetCommState(h->fd, &h->oldtio); - CloseHandle(h->fd); - free(h); -} - -static port_err_t serial_setup(serial_t *h, - const serial_baud_t baud, - const serial_bits_t bits, - const serial_parity_t parity, - const serial_stopbit_t stopbit) -{ - switch (baud) { - case SERIAL_BAUD_1200: h->newtio.BaudRate = CBR_1200; break; - /* case SERIAL_BAUD_1800: h->newtio.BaudRate = CBR_1800; break; */ - case SERIAL_BAUD_2400: h->newtio.BaudRate = CBR_2400; break; - case SERIAL_BAUD_4800: h->newtio.BaudRate = CBR_4800; break; - case SERIAL_BAUD_9600: h->newtio.BaudRate = CBR_9600; break; - case SERIAL_BAUD_19200: h->newtio.BaudRate = CBR_19200; break; - case SERIAL_BAUD_38400: h->newtio.BaudRate = CBR_38400; break; - case SERIAL_BAUD_57600: h->newtio.BaudRate = CBR_57600; break; - case SERIAL_BAUD_115200: h->newtio.BaudRate = CBR_115200; break; - case SERIAL_BAUD_128000: h->newtio.BaudRate = CBR_128000; break; - case SERIAL_BAUD_256000: h->newtio.BaudRate = CBR_256000; break; - /* These are not defined in WinBase.h and might work or not */ - case SERIAL_BAUD_230400: h->newtio.BaudRate = 230400; break; - case SERIAL_BAUD_460800: h->newtio.BaudRate = 460800; break; - case SERIAL_BAUD_500000: h->newtio.BaudRate = 500000; break; - case SERIAL_BAUD_576000: h->newtio.BaudRate = 576000; break; - case SERIAL_BAUD_921600: h->newtio.BaudRate = 921600; break; - case SERIAL_BAUD_1000000: h->newtio.BaudRate = 1000000; break; - case SERIAL_BAUD_1500000: h->newtio.BaudRate = 1500000; break; - case SERIAL_BAUD_2000000: h->newtio.BaudRate = 2000000; break; - case SERIAL_BAUD_INVALID: - - default: - return PORT_ERR_UNKNOWN; - } - - switch (bits) { - case SERIAL_BITS_5: h->newtio.ByteSize = 5; break; - case SERIAL_BITS_6: h->newtio.ByteSize = 6; break; - case SERIAL_BITS_7: h->newtio.ByteSize = 7; break; - case SERIAL_BITS_8: h->newtio.ByteSize = 8; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (parity) { - case SERIAL_PARITY_NONE: h->newtio.Parity = NOPARITY; break; - case SERIAL_PARITY_EVEN: h->newtio.Parity = EVENPARITY; break; - case SERIAL_PARITY_ODD: h->newtio.Parity = ODDPARITY; break; - - default: - return PORT_ERR_UNKNOWN; - } - - switch (stopbit) { - case SERIAL_STOPBIT_1: h->newtio.StopBits = ONESTOPBIT; break; - case SERIAL_STOPBIT_2: h->newtio.StopBits = TWOSTOPBITS; break; - - default: - return PORT_ERR_UNKNOWN; - } - - /* reset the settings */ - h->newtio.fOutxCtsFlow = FALSE; - h->newtio.fOutxDsrFlow = FALSE; - h->newtio.fOutX = FALSE; - h->newtio.fInX = FALSE; - h->newtio.fNull = 0; - h->newtio.fAbortOnError = 0; - - /* set the settings */ - serial_flush(h); - if (!SetCommState(h->fd, &h->newtio)) - return PORT_ERR_UNKNOWN; - - snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", - serial_get_baud_int(baud), - serial_get_bits_int(bits), - serial_get_parity_str(parity), - serial_get_stopbit_int(stopbit) - ); - return PORT_ERR_OK; -} - -static port_err_t serial_w32_open(struct port_interface *port, - struct port_options *ops) -{ - serial_t *h; - - /* 1. check device name match */ - /* Roger Clark. Added support for com10 and higher numbers */ - if (!((strlen(ops->device) == 4 || strlen(ops->device) == 5) - && !strncmp(ops->device, "COM", 3) && isdigit(ops->device[3])) - && !(!strncmp(ops->device, "\\\\.\\COM", strlen("\\\\.\\COM")) - && isdigit(ops->device[strlen("\\\\.\\COM")]))) - return PORT_ERR_NODEV; - - /* 2. check options */ - if (ops->baudRate == SERIAL_BAUD_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) - return PORT_ERR_UNKNOWN; - if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) - return PORT_ERR_UNKNOWN; - - /* 3. open it */ - h = serial_open(ops->device); - if (h == NULL) - return PORT_ERR_UNKNOWN; - - /* 4. set options */ - if (serial_setup(h, ops->baudRate, - serial_get_bits(ops->serial_mode), - serial_get_parity(ops->serial_mode), - serial_get_stopbit(ops->serial_mode) - ) != PORT_ERR_OK) { - serial_close(h); - return PORT_ERR_UNKNOWN; - } - - port->private = h; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_close(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - serial_close(h); - port->private = NULL; - return PORT_ERR_OK; -} - -static port_err_t serial_w32_read(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - ReadFile(h->fd, pos, nbyte, &r, NULL); - if (r == 0) - return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_write(struct port_interface *port, void *buf, - size_t nbyte) -{ - serial_t *h; - DWORD r; - uint8_t *pos = (uint8_t *)buf; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - while (nbyte) { - if (!WriteFile(h->fd, pos, nbyte, &r, NULL)) - return PORT_ERR_UNKNOWN; - if (r < 1) - return PORT_ERR_UNKNOWN; - - nbyte -= r; - pos += r; - } - return PORT_ERR_OK; -} - -static port_err_t serial_w32_gpio(struct port_interface *port, - serial_gpio_t n, int level) -{ - serial_t *h; - int bit; - - h = (serial_t *)port->private; - if (h == NULL) - return PORT_ERR_UNKNOWN; - - switch (n) { - case GPIO_RTS: - bit = level ? SETRTS : CLRRTS; - break; - - case GPIO_DTR: - bit = level ? SETDTR : CLRDTR; - break; - - case GPIO_BRK: - if (level == 0) - return PORT_ERR_OK; - if (EscapeCommFunction(h->fd, SETBREAK) == 0) - return PORT_ERR_UNKNOWN; - usleep(500000); - if (EscapeCommFunction(h->fd, CLRBREAK) == 0) - return PORT_ERR_UNKNOWN; - return PORT_ERR_OK; - - default: - return PORT_ERR_UNKNOWN; - } - - /* handle RTS/DTR */ - if (EscapeCommFunction(h->fd, bit) == 0) - return PORT_ERR_UNKNOWN; - - return PORT_ERR_OK; -} - -static const char *serial_w32_get_cfg_str(struct port_interface *port) -{ - serial_t *h; - - h = (serial_t *)port->private; - return h ? h->setup_str : "INVALID"; -} - -struct port_interface port_serial = { - .name = "serial_w32", - .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, - .open = serial_w32_open, - .close = serial_w32_close, - .read = serial_w32_read, - .write = serial_w32_write, - .gpio = serial_w32_gpio, - .get_cfg_str = serial_w32_get_cfg_str, -}; +/* + stm32flash - Open Source ST STM32 flash program for *nix + Copyright (C) 2010 Geoffrey McRae + Copyright (C) 2010 Gareth McMullin + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "serial.h" +#include "port.h" + +struct serial { + HANDLE fd; + DCB oldtio; + DCB newtio; + char setup_str[11]; +}; + +static serial_t *serial_open(const char *device) +{ + serial_t *h = calloc(sizeof(serial_t), 1); + char *devName; + + /* timeout in ms */ + COMMTIMEOUTS timeouts = {MAXDWORD, MAXDWORD, 500, 0, 0}; + + /* Fix the device name if required */ + if (strlen(device) > 4 && device[0] != '\\') { + devName = calloc(1, strlen(device) + 5); + sprintf(devName, "\\\\.\\%s", device); + } else { + devName = (char *)device; + } + + /* Create file handle for port */ + h->fd = CreateFile(devName, GENERIC_READ | GENERIC_WRITE, + 0, /* Exclusive access */ + NULL, /* No security */ + OPEN_EXISTING, + 0, /* No overlap */ + NULL); + + if (devName != device) + free(devName); + + if (h->fd == INVALID_HANDLE_VALUE) { + if (GetLastError() == ERROR_FILE_NOT_FOUND) + fprintf(stderr, "File not found: %s\n", device); + return NULL; + } + + SetupComm(h->fd, 4096, 4096); /* Set input and output buffer size */ + + SetCommTimeouts(h->fd, &timeouts); + + SetCommMask(h->fd, EV_ERR); /* Notify us of error events */ + + GetCommState(h->fd, &h->oldtio); /* Retrieve port parameters */ + GetCommState(h->fd, &h->newtio); /* Retrieve port parameters */ + + /* PurgeComm(h->fd, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); */ + + return h; +} + +static void serial_flush(const serial_t *h) +{ + /* We shouldn't need to flush in non-overlapping (blocking) mode */ + /* tcflush(h->fd, TCIFLUSH); */ +} + +static void serial_close(serial_t *h) +{ + serial_flush(h); + SetCommState(h->fd, &h->oldtio); + CloseHandle(h->fd); + free(h); +} + +static port_err_t serial_setup(serial_t *h, + const serial_baud_t baud, + const serial_bits_t bits, + const serial_parity_t parity, + const serial_stopbit_t stopbit) +{ + switch (baud) { + case SERIAL_BAUD_1200: h->newtio.BaudRate = CBR_1200; break; + /* case SERIAL_BAUD_1800: h->newtio.BaudRate = CBR_1800; break; */ + case SERIAL_BAUD_2400: h->newtio.BaudRate = CBR_2400; break; + case SERIAL_BAUD_4800: h->newtio.BaudRate = CBR_4800; break; + case SERIAL_BAUD_9600: h->newtio.BaudRate = CBR_9600; break; + case SERIAL_BAUD_19200: h->newtio.BaudRate = CBR_19200; break; + case SERIAL_BAUD_38400: h->newtio.BaudRate = CBR_38400; break; + case SERIAL_BAUD_57600: h->newtio.BaudRate = CBR_57600; break; + case SERIAL_BAUD_115200: h->newtio.BaudRate = CBR_115200; break; + case SERIAL_BAUD_128000: h->newtio.BaudRate = CBR_128000; break; + case SERIAL_BAUD_256000: h->newtio.BaudRate = CBR_256000; break; + /* These are not defined in WinBase.h and might work or not */ + case SERIAL_BAUD_230400: h->newtio.BaudRate = 230400; break; + case SERIAL_BAUD_460800: h->newtio.BaudRate = 460800; break; + case SERIAL_BAUD_500000: h->newtio.BaudRate = 500000; break; + case SERIAL_BAUD_576000: h->newtio.BaudRate = 576000; break; + case SERIAL_BAUD_921600: h->newtio.BaudRate = 921600; break; + case SERIAL_BAUD_1000000: h->newtio.BaudRate = 1000000; break; + case SERIAL_BAUD_1500000: h->newtio.BaudRate = 1500000; break; + case SERIAL_BAUD_2000000: h->newtio.BaudRate = 2000000; break; + case SERIAL_BAUD_INVALID: + + default: + return PORT_ERR_UNKNOWN; + } + + switch (bits) { + case SERIAL_BITS_5: h->newtio.ByteSize = 5; break; + case SERIAL_BITS_6: h->newtio.ByteSize = 6; break; + case SERIAL_BITS_7: h->newtio.ByteSize = 7; break; + case SERIAL_BITS_8: h->newtio.ByteSize = 8; break; + + default: + return PORT_ERR_UNKNOWN; + } + + switch (parity) { + case SERIAL_PARITY_NONE: h->newtio.Parity = NOPARITY; break; + case SERIAL_PARITY_EVEN: h->newtio.Parity = EVENPARITY; break; + case SERIAL_PARITY_ODD: h->newtio.Parity = ODDPARITY; break; + + default: + return PORT_ERR_UNKNOWN; + } + + switch (stopbit) { + case SERIAL_STOPBIT_1: h->newtio.StopBits = ONESTOPBIT; break; + case SERIAL_STOPBIT_2: h->newtio.StopBits = TWOSTOPBITS; break; + + default: + return PORT_ERR_UNKNOWN; + } + + /* reset the settings */ + h->newtio.fOutxCtsFlow = FALSE; + h->newtio.fOutxDsrFlow = FALSE; + h->newtio.fOutX = FALSE; + h->newtio.fInX = FALSE; + h->newtio.fNull = 0; + h->newtio.fAbortOnError = 0; + + /* set the settings */ + serial_flush(h); + if (!SetCommState(h->fd, &h->newtio)) + return PORT_ERR_UNKNOWN; + + snprintf(h->setup_str, sizeof(h->setup_str), "%u %d%c%d", + serial_get_baud_int(baud), + serial_get_bits_int(bits), + serial_get_parity_str(parity), + serial_get_stopbit_int(stopbit) + ); + return PORT_ERR_OK; +} + +static port_err_t serial_w32_open(struct port_interface *port, + struct port_options *ops) +{ + serial_t *h; + + /* 1. check device name match */ + if (!((strlen(ops->device) == 4 || strlen(ops->device) == 5) + && !strncmp(ops->device, "COM", 3) && isdigit(ops->device[3])) + && !(!strncmp(ops->device, "\\\\.\\COM", strlen("\\\\.\\COM")) + && isdigit(ops->device[strlen("\\\\.\\COM")]))) + return PORT_ERR_NODEV; + + /* 2. check options */ + if (ops->baudRate == SERIAL_BAUD_INVALID) + return PORT_ERR_UNKNOWN; + if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) + return PORT_ERR_UNKNOWN; + if (serial_get_parity(ops->serial_mode) == SERIAL_PARITY_INVALID) + return PORT_ERR_UNKNOWN; + if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) + return PORT_ERR_UNKNOWN; + + /* 3. open it */ + h = serial_open(ops->device); + if (h == NULL) + return PORT_ERR_UNKNOWN; + + /* 4. set options */ + if (serial_setup(h, ops->baudRate, + serial_get_bits(ops->serial_mode), + serial_get_parity(ops->serial_mode), + serial_get_stopbit(ops->serial_mode) + ) != PORT_ERR_OK) { + serial_close(h); + return PORT_ERR_UNKNOWN; + } + + port->private = h; + return PORT_ERR_OK; +} + +static port_err_t serial_w32_close(struct port_interface *port) +{ + serial_t *h; + + h = (serial_t *)port->private; + if (h == NULL) + return PORT_ERR_UNKNOWN; + + serial_close(h); + port->private = NULL; + return PORT_ERR_OK; +} + +static port_err_t serial_w32_read(struct port_interface *port, void *buf, + size_t nbyte) +{ + serial_t *h; + DWORD r; + uint8_t *pos = (uint8_t *)buf; + + h = (serial_t *)port->private; + if (h == NULL) + return PORT_ERR_UNKNOWN; + + while (nbyte) { + ReadFile(h->fd, pos, nbyte, &r, NULL); + if (r == 0) + return PORT_ERR_TIMEDOUT; + if (r < 0) + return PORT_ERR_UNKNOWN; + + nbyte -= r; + pos += r; + } + return PORT_ERR_OK; +} + +static port_err_t serial_w32_write(struct port_interface *port, void *buf, + size_t nbyte) +{ + serial_t *h; + DWORD r; + uint8_t *pos = (uint8_t *)buf; + + h = (serial_t *)port->private; + if (h == NULL) + return PORT_ERR_UNKNOWN; + + while (nbyte) { + if (!WriteFile(h->fd, pos, nbyte, &r, NULL)) + return PORT_ERR_UNKNOWN; + if (r < 1) + return PORT_ERR_UNKNOWN; + + nbyte -= r; + pos += r; + } + return PORT_ERR_OK; +} + +static port_err_t serial_w32_gpio(struct port_interface *port, + serial_gpio_t n, int level) +{ + serial_t *h; + int bit; + + h = (serial_t *)port->private; + if (h == NULL) + return PORT_ERR_UNKNOWN; + + switch (n) { + case GPIO_RTS: + bit = level ? SETRTS : CLRRTS; + break; + + case GPIO_DTR: + bit = level ? SETDTR : CLRDTR; + break; + + case GPIO_BRK: + if (level == 0) + return PORT_ERR_OK; + if (EscapeCommFunction(h->fd, SETBREAK) == 0) + return PORT_ERR_UNKNOWN; + usleep(500000); + if (EscapeCommFunction(h->fd, CLRBREAK) == 0) + return PORT_ERR_UNKNOWN; + return PORT_ERR_OK; + + default: + return PORT_ERR_UNKNOWN; + } + + /* handle RTS/DTR */ + if (EscapeCommFunction(h->fd, bit) == 0) + return PORT_ERR_UNKNOWN; + + return PORT_ERR_OK; +} + +static const char *serial_w32_get_cfg_str(struct port_interface *port) +{ + serial_t *h; + + h = (serial_t *)port->private; + return h ? h->setup_str : "INVALID"; +} + +struct port_interface port_serial = { + .name = "serial_w32", + .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, + .open = serial_w32_open, + .close = serial_w32_close, + .read = serial_w32_read, + .write = serial_w32_write, + .gpio = serial_w32_gpio, + .get_cfg_str = serial_w32_get_cfg_str, +}; diff --git a/tools/src/stm32flash_serial/src/stm32.c b/tools/src/stm32flash_serial/src/stm32.c index ca95b3e..74047d2 100644 --- a/tools/src/stm32flash_serial/src/stm32.c +++ b/tools/src/stm32flash_serial/src/stm32.c @@ -784,7 +784,7 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) return STM32_ERR_UNKNOWN; } - s_err = stm32_get_ack_timeout(stm, STM32_SECTERASE_TIMEOUT); + s_err = stm32_get_ack_timeout(stm, pages * STM32_SECTERASE_TIMEOUT); if (s_err != STM32_ERR_OK) { fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); if (port->flags & PORT_STRETCH_W diff --git a/tools/src/stm32flash_serial/src/stm32.o b/tools/src/stm32flash_serial/src/stm32.o index 7fdf18a..e214211 100644 Binary files a/tools/src/stm32flash_serial/src/stm32.o and b/tools/src/stm32flash_serial/src/stm32.o differ diff --git a/tools/src/stm32flash_serial/src/utils.o b/tools/src/stm32flash_serial/src/utils.o index 46f6ca5..f588ba0 100644 Binary files a/tools/src/stm32flash_serial/src/utils.o and b/tools/src/stm32flash_serial/src/utils.o differ diff --git a/tools/win/stm32flash.exe b/tools/win/stm32flash.exe index c6481d8..911c0cc 100644 Binary files a/tools/win/stm32flash.exe and b/tools/win/stm32flash.exe differ