From 067d0cf93c45b2ce958e69c469dc1912f5614eed Mon Sep 17 00:00:00 2001 From: Derisis13 Date: Mon, 12 Dec 2022 20:38:15 +0100 Subject: [PATCH] feature: custom function to get addresses --- .gitignore | 6 ++-- Core/Src/main.c | 58 ++++++++++++++++++++++++++++++++++-- USB_DEVICE/App/usbd_cdc_if.c | 29 ++++++++++++------ 3 files changed, 79 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 94889f2..55a5bbe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ cmake-build-debug -cmake-build-debug/* +cmake-build-minsizerel +cmake-build-release +cmake-build-relwithdebinfo .settings -.settings/* .cproject .mxproject .project .idea -.idea/* memdump-ft2232.cfg \ No newline at end of file diff --git a/Core/Src/main.c b/Core/Src/main.c index cc15326..5e1287f 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -23,7 +23,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ -#include "usbd_cdc.h" + /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -48,7 +48,7 @@ SPI_HandleTypeDef hspi1; /* USER CODE BEGIN PV */ state st = run; -uint16_t i2c_address = 0; +uint32_t i2c_address = 0; uint32_t limit_address = 0; /* USER CODE END PV */ @@ -66,6 +66,60 @@ extern uint8_t CDC_Transmit_FS(uint8_t *Buf, uint16_t Len); /* USER CODE BEGIN 0 */ /* ----------------------------------------------------------------------------- + * Converts a hexadecimal ASCII character to it's value + * + * From https://github.com/Sasszem/oldschool-game/blob/main/save.c + * under the conditions of the MIT License: + * + * MIT License + * + * Copyright (c) 2022 László Baráth + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * -------------------------------------------------------------------------- */ +uint8_t hex_nibble(char val) { + if ('0' <= val && val <= '9') + return val - '0'; + if ('a' <= val && val <= 'f') + return val - 'a' + 10; + if ('A' <= val && val <= 'F') + return val - 'A' + 10; + return 0xFF; +} + +/* ----------------------------------------------------------------------------------------- + * Converts all characters until the first character that matches delim or until *Len + * Result is stored to dest + * Return value is the number of characters processed or 0 in case of a conversion failure + * ----------------------------------------------------------------------------------------- */ +uint8_t homegrown_scanf (uint8_t *Buf, const uint32_t *Len, uint32_t *dest, const char delim) { + uint8_t cursor = 0; + for (*dest = 0; Buf[cursor] != delim || cursor < *Len; cursor++) { + uint8_t nibble = hex_nibble(Buf[cursor]); + if (nibble == 0xFF) { + return(0); + } + *dest = *dest * 16 + nibble; + } + return (cursor); +} +/* -------------------------------------------------------------------------- * convert a hex to ascii string * input is a byte array (binary), output is a character array (str) * len is the number of bytes to convert, str needs to be at least 2x as big diff --git a/USB_DEVICE/App/usbd_cdc_if.c b/USB_DEVICE/App/usbd_cdc_if.c index 868f855..27ab8e0 100644 --- a/USB_DEVICE/App/usbd_cdc_if.c +++ b/USB_DEVICE/App/usbd_cdc_if.c @@ -22,7 +22,7 @@ #include "usbd_cdc_if.h" /* USER CODE BEGIN INCLUDE */ -#include + /* USER CODE END INCLUDE */ /* Private typedef -----------------------------------------------------------*/ @@ -32,7 +32,7 @@ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ extern state st; -extern uint16_t i2c_address; +extern uint32_t i2c_address; extern uint32_t limit_address; /* USER CODE END PV */ @@ -112,6 +112,10 @@ extern USBD_HandleTypeDef hUsbDeviceFS; /* USER CODE BEGIN EXPORTED_VARIABLES */ +extern uint8_t hex_nibble(char val); +extern uint8_t homegrown_scanf (uint8_t *Buf, const uint32_t *Len, uint32_t *dest, char delim); + + /* USER CODE END EXPORTED_VARIABLES */ /** @@ -126,7 +130,7 @@ extern USBD_HandleTypeDef hUsbDeviceFS; static int8_t CDC_Init_FS(void); static int8_t CDC_DeInit_FS(void); static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); -static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len); +static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len); /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ @@ -264,6 +268,7 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); if (st == run) { + // receive the command, set state if (Buf[0] == 'r') { switch (Buf[1]) { case 'i': @@ -306,15 +311,21 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) st = invalid; return (USBD_OK); } - if (sscanf((char *)Buf + 2, "%lx", &limit_address) != 1) { - st = invalid; - return (USBD_OK); - } - if (st == read_i2c || st == write_i2c) { - if (sscanf((char *)Buf + 2, "%*lx %hx", &i2c_address) != 1) { + // receive optional i2c address and limit address + uint8_t cursor = 3; // 3 = 2 for the command, 1 for a separator + *Len -= cursor; + if (st == write_i2c || st == read_i2c) { + cursor += homegrown_scanf(Buf + cursor, Len, &i2c_address, ' ') + 1; // + 1 for the delimiter + if (i2c_address == 0) { st = invalid; return (USBD_OK); } + *Len -= cursor; + } + homegrown_scanf(Buf + cursor, Len, &limit_address, '\n'); + if (limit_address == 0) { + st = invalid; + return (USBD_OK); } } return (USBD_OK);