From a60b736834c1dd224a1501d88cdd8b8b81a9aff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Fri, 23 Feb 2018 10:55:49 +0100 Subject: [PATCH] massive utils refactoring, renames, avr libc utils cleaning --- .../Class/CDC/Src/usbd_cdc.c.rej | 328 ------------------ .../Class/MSC/Inc/usbd_msc.h.rej | 60 ---- .../Class/MSC/Src/usbd_msc.c.rej | 35 -- .../Class/MSC/Src/usbd_msc_scsi.c.rej | 37 -- .../Core/Inc/usbd_def.h | 4 +- .../Core/Inc/usbd_def.h.rej | 62 ---- cortex_handlers.c | 2 +- framework/resources.c | 36 +- framework/resources.h | 10 + framework/settings.c | 2 +- framework/system_settings.c | 5 +- framework/unit_base.h | 1 + gex.mk | 2 +- platform/cfg_utils.c | 299 ++++++++++++++++ platform/cfg_utils.h | 153 ++++++++ platform/hw_utils.c | 275 +-------------- platform/hw_utils.h | 91 +---- platform/lock_jumper.c | 11 +- platform/status_led.c | 8 +- tasks/task_main.c | 2 - units/1wire/_ow_init.c | 2 +- units/1wire/_ow_settings.c | 4 +- units/adc/_adc_init.c | 2 +- units/adc/_adc_settings.c | 12 +- units/digital_in/_din_settings.c | 28 +- units/digital_out/_dout_settings.c | 14 +- units/fcap/_fcap_settings.c | 32 +- units/i2c/_i2c_settings.c | 12 +- units/neopixel/_npx_init.c | 2 +- units/neopixel/_npx_settings.c | 4 +- units/sipo/_sipo_init.c | 6 +- units/sipo/_sipo_settings.c | 18 +- units/spi/_spi_settings.c | 24 +- units/usart/_usart_settings.c | 102 +++--- utils/avr_atoi.c | 35 -- utils/avr_atol.c | 36 -- utils/avr_strtod.c | 22 +- utils/avr_strtol.c | 37 +- utils/avr_strtoul.c | 30 +- utils/avrlibc.c | 7 + utils/avrlibc.h | 55 +-- utils/snprintf.c | 2 +- utils/str_utils.c | 107 ------ utils/str_utils.h | 51 --- 44 files changed, 731 insertions(+), 1336 deletions(-) delete mode 100644 USB/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c.rej delete mode 100644 USB/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h.rej delete mode 100644 USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c.rej delete mode 100644 USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c.rej delete mode 100644 USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h.rej create mode 100644 platform/cfg_utils.c create mode 100644 platform/cfg_utils.h delete mode 100644 utils/avr_atoi.c delete mode 100644 utils/avr_atol.c create mode 100644 utils/avrlibc.c diff --git a/USB/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c.rej b/USB/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c.rej deleted file mode 100644 index b76520b..0000000 --- a/USB/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c.rej +++ /dev/null @@ -1,328 +0,0 @@ ---- Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c (date 1511202099000) -+++ Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c (revision ) -@@ -59,6 +59,7 @@ - */ - - /* Includes ------------------------------------------------------------------*/ -+#include "usbd_msc.h" // for rejecting bad control messages - #include "usbd_cdc.h" - #include "usbd_desc.h" - #include "usbd_ctlreq.h" -@@ -103,34 +104,7 @@ - * @{ - */ - -- --static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, -- uint8_t cfgidx); -- --static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, -- uint8_t cfgidx); -- --static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, -- USBD_SetupReqTypedef *req); -- --static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, -- uint8_t epnum); -- --static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, -- uint8_t epnum); -- --static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev); -- --static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length); -- --static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length); -- --static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length); -- --static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length); -- --uint8_t *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length); -- -+#ifndef CDC_COMPOSITE - /* USB Standard Device Descriptor */ - __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = - { -@@ -156,7 +130,7 @@ - - - /* CDC interface class callbacks structure */ --USBD_ClassTypeDef USBD_CDC = -+USBD_ClassTypeDef USBD_CDC = - { - USBD_CDC_Init, - USBD_CDC_DeInit, -@@ -172,6 +146,7 @@ - USBD_CDC_GetFSCfgDesc, - USBD_CDC_GetOtherSpeedCfgDesc, - USBD_CDC_GetDeviceQualifierDescriptor, -+ NULL - }; - - /* USB CDC device Configuration Descriptor */ -@@ -456,6 +431,7 @@ - 0x00, - 0x00 /* bInterval */ - }; -+#endif - - /** - * @} -@@ -463,7 +439,7 @@ - - /** @defgroup USBD_CDC_Private_Functions - * @{ -- */ -+ */ - - /** - * @brief USBD_CDC_Init -@@ -472,7 +448,7 @@ - * @param cfgidx: Configuration index - * @retval status - */ --static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, -+uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, - uint8_t cfgidx) - { - uint8_t ret = 0; -@@ -514,18 +490,18 @@ - CDC_CMD_PACKET_SIZE); - - -- pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef)); -+ pdev->pClassData2 = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef)); - -- if(pdev->pClassData == NULL) -+ if(pdev->pClassData2 == NULL) - { - ret = 1; - } - else - { -- hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - - /* Init physical Interface components */ -- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); -+ ((USBD_CDC_ItfTypeDef *)pdev->pUserData2)->Init(); - - /* Init Xfer states */ - hcdc->TxState =0; -@@ -560,7 +536,7 @@ - * @param cfgidx: Configuration index - * @retval status - */ --static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, -+uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, - uint8_t cfgidx) - { - uint8_t ret = 0; -@@ -579,11 +555,11 @@ - - - /* DeInit physical Interface components */ -- if(pdev->pClassData != NULL) -+ if(pdev->pClassData2 != NULL) - { -- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit(); -- USBD_free(pdev->pClassData); -- pdev->pClassData = NULL; -+ ((USBD_CDC_ItfTypeDef *)pdev->pUserData2)->DeInit(); -+ USBD_free(pdev->pClassData2); -+ pdev->pClassData2 = NULL; - } - - return ret; -@@ -596,20 +572,23 @@ - * @param req: usb requests - * @retval status - */ --static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, -+uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) - { -- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - static uint8_t ifalt = 0; - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - case USB_REQ_TYPE_CLASS : -+ if (req->bRequest == BOT_GET_MAX_LUN) break; // Not ours! -+ if (req->bRequest == BOT_RESET) break; // Not ours! -+ - if (req->wLength) - { - if (req->bmRequest & 0x80) - { -- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, -+ ((USBD_CDC_ItfTypeDef *)pdev->pUserData2)->Control(req->bRequest, - (uint8_t *)hcdc->data, - req->wLength); - USBD_CtlSendData (pdev, -@@ -629,7 +608,7 @@ - } - else - { -- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, -+ ((USBD_CDC_ItfTypeDef *)pdev->pUserData2)->Control(req->bRequest, - (uint8_t*)req, - 0); - } -@@ -661,14 +640,15 @@ - * @param epnum: endpoint number - * @retval status - */ --static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) -+uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) - { -- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - -- if(pdev->pClassData != NULL) -+ if(pdev->pClassData2 != NULL) - { - - hcdc->TxState = 0; -+ USBD_CDC_TransmitDone(pdev); - - return USBD_OK; - } -@@ -685,18 +665,18 @@ - * @param epnum: endpoint number - * @retval status - */ --static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) -+uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) - { -- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - - /* Get the received data length */ - hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum); - - /* USB data will be immediately processed, this allow next USB traffic being - NAKed till the end of the application Xfer */ -- if(pdev->pClassData != NULL) -+ if(pdev->pClassData2 != NULL) - { -- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); -+ ((USBD_CDC_ItfTypeDef *)pdev->pUserData2)->Receive(hcdc->RxBuffer, &hcdc->RxLength); - - return USBD_OK; - } -@@ -715,13 +695,13 @@ - * @param epnum: endpoint number - * @retval status - */ --static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev) -+uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev) - { -- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - -- if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF)) -+ if((pdev->pUserData2 != NULL) && (hcdc->CmdOpCode != 0xFF)) - { -- ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, -+ ((USBD_CDC_ItfTypeDef *)pdev->pUserData2)->Control(hcdc->CmdOpCode, - (uint8_t *)hcdc->data, - hcdc->CmdLength); - hcdc->CmdOpCode = 0xFF; -@@ -730,6 +710,7 @@ - return USBD_OK; - } - -+#ifndef CDC_COMPOSITE - /** - * @brief USBD_CDC_GetFSCfgDesc - * Return configuration descriptor -@@ -737,7 +718,7 @@ - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ --static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) -+uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) - { - *length = sizeof (USBD_CDC_CfgFSDesc); - return USBD_CDC_CfgFSDesc; -@@ -750,7 +731,7 @@ - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ --static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) -+uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) - { - *length = sizeof (USBD_CDC_CfgHSDesc); - return USBD_CDC_CfgHSDesc; -@@ -763,7 +744,7 @@ - * @param length : pointer data length - * @retval pointer to descriptor buffer - */ --static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length) -+uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length) - { - *length = sizeof (USBD_CDC_OtherSpeedCfgDesc); - return USBD_CDC_OtherSpeedCfgDesc; -@@ -780,6 +761,7 @@ - *length = sizeof (USBD_CDC_DeviceQualifierDesc); - return USBD_CDC_DeviceQualifierDesc; - } -+#endif - - /** - * @brief USBD_CDC_RegisterInterface -@@ -794,7 +776,7 @@ - - if(fops != NULL) - { -- pdev->pUserData= fops; -+ pdev->pUserData2= fops; - ret = USBD_OK; - } - -@@ -811,7 +793,7 @@ - uint8_t *pbuff, - uint16_t length) - { -- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - - hcdc->TxBuffer = pbuff; - hcdc->TxLength = length; -@@ -829,7 +811,7 @@ - uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, - uint8_t *pbuff) - { -- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - - hcdc->RxBuffer = pbuff; - -@@ -845,9 +827,9 @@ - */ - uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) - { -- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - -- if(pdev->pClassData != NULL) -+ if(pdev->pClassData2 != NULL) - { - if(hcdc->TxState == 0) - { -@@ -882,10 +864,10 @@ - */ - uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) - { -- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; -+ USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData2; - - /* Suspend or Resume USB Out process */ -- if(pdev->pClassData != NULL) -+ if(pdev->pClassData2 != NULL) - { - if(pdev->dev_speed == USBD_SPEED_HIGH ) - { diff --git a/USB/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h.rej b/USB/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h.rej deleted file mode 100644 index 0178a15..0000000 --- a/USB/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h.rej +++ /dev/null @@ -1,60 +0,0 @@ ---- Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h (date 1511202099000) -+++ Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h (revision ) -@@ -58,9 +58,10 @@ - #define BOT_RESET 0xFF - #define USB_MSC_CONFIG_DESC_SIZ 32 - -- -+#ifndef MSC_CUSTOM_EPS - #define MSC_EPIN_ADDR 0x81 --#define MSC_EPOUT_ADDR 0x01 -+#define MSC_EPOUT_ADDR 0x01 -+#endif - - /** - * @} -@@ -107,7 +108,7 @@ - USBD_MSC_BOT_HandleTypeDef; - - /* Structure for MSC process */ --extern USBD_ClassTypeDef USBD_MSC; -+extern USBD_ClassTypeDef USBD_MSC; - #define USBD_MSC_CLASS &USBD_MSC - - uint8_t USBD_MSC_RegisterStorage (USBD_HandleTypeDef *pdev, -@@ -118,8 +119,34 @@ - - /** - * @} -- */ -+ */ - -+// XXX "static" moved here for use in composite driver -+ -+uint8_t USBD_MSC_Init (USBD_HandleTypeDef *pdev, -+ uint8_t cfgidx); -+ -+uint8_t USBD_MSC_DeInit (USBD_HandleTypeDef *pdev, -+ uint8_t cfgidx); -+ -+uint8_t USBD_MSC_Setup (USBD_HandleTypeDef *pdev, -+ USBD_SetupReqTypedef *req); -+ -+uint8_t USBD_MSC_DataIn (USBD_HandleTypeDef *pdev, -+ uint8_t epnum); -+ -+ -+uint8_t USBD_MSC_DataOut (USBD_HandleTypeDef *pdev, -+ uint8_t epnum); -+ -+uint8_t *USBD_MSC_GetHSCfgDesc (uint16_t *length); -+ -+uint8_t *USBD_MSC_GetFSCfgDesc (uint16_t *length); -+ -+uint8_t *USBD_MSC_GetOtherSpeedCfgDesc (uint16_t *length); -+ -+uint8_t *USBD_MSC_GetDeviceQualifierDescriptor (uint16_t *length); -+ - #ifdef __cplusplus - } - #endif diff --git a/USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c.rej b/USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c.rej deleted file mode 100644 index 89a284e..0000000 --- a/USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c.rej +++ /dev/null @@ -1,35 +0,0 @@ ---- Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c (date 1511202099000) -+++ Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c (revision ) -@@ -116,7 +116,7 @@ - * @{ - */ - -- -+#ifndef MSC_COMPOSITE - USBD_ClassTypeDef USBD_MSC = - { - USBD_MSC_Init, -@@ -279,6 +279,7 @@ - 0x01, - 0x00, - }; -+#endif - /** - * @} - */ -@@ -530,6 +531,7 @@ - return 0; - } - -+#ifndef MSC_COMPOSITE - /** - * @brief USBD_MSC_GetHSCfgDesc - * return configuration descriptor -@@ -576,6 +578,7 @@ - *length = sizeof (USBD_MSC_DeviceQualifierDesc); - return USBD_MSC_DeviceQualifierDesc; - } -+#endif - - /** - * @brief USBD_MSC_RegisterStorage diff --git a/USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c.rej b/USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c.rej deleted file mode 100644 index 5c782ae..0000000 --- a/USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c.rej +++ /dev/null @@ -1,37 +0,0 @@ ---- Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c (date 1511202099000) -+++ Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c (revision ) -@@ -190,14 +190,27 @@ - INVALID_CDB); - return -1; - } -- -- if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 ) -+ -+ // XXX THIS SECTION IS MODIFIED FOR NOTIFY! -+ // https://www.microchip.com/forums/m401735.aspx -+ int8_t changeStatus = ((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun); -+ if(changeStatus != 0) - { -- SCSI_SenseCode(pdev, -- lun, -- NOT_READY, -- MEDIUM_NOT_PRESENT); -- -+ if (changeStatus == -1) -+ { -+ SCSI_SenseCode(pdev, -+ lun, -+ UNIT_ATTENTION, -+ MEDIUM_HAVE_CHANGED); -+ } -+ else -+ { -+ SCSI_SenseCode(pdev, -+ lun, -+ NOT_READY, -+ MEDIUM_NOT_PRESENT); -+ } -+ - hmsc->bot_state = USBD_BOT_NO_DATA; - return -1; - } diff --git a/USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h index 843cf47..a574ab7 100644 --- a/USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ b/USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -265,8 +265,8 @@ typedef struct _USBD_HandleTypeDef #define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) -#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) -#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) +#define LOBYTE(x) ((uint8_t)((x) & 0x00FF)) +#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00) >>8)) #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) diff --git a/USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h.rej b/USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h.rej deleted file mode 100644 index 2d5fa3c..0000000 --- a/USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h.rej +++ /dev/null @@ -1,62 +0,0 @@ ---- Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h (date 1511202099000) -+++ Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h (revision ) -@@ -99,6 +99,7 @@ - #define USB_DESC_TYPE_ENDPOINT 5 - #define USB_DESC_TYPE_DEVICE_QUALIFIER 6 - #define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 -+#define USB_DESC_TYPE_IFACE_ASSOCIATION 11 - #define USB_DESC_TYPE_BOS 0x0F - - #define USB_CONFIG_REMOTE_WAKEUP 2 -@@ -147,7 +148,7 @@ - - typedef struct usb_setup_req - { -- -+ - uint8_t bmRequest; - uint8_t bRequest; - uint16_t wValue; -@@ -230,7 +231,7 @@ - uint32_t dev_config_status; - USBD_SpeedTypeDef dev_speed; - USBD_EndpointTypeDef ep_in[15]; -- USBD_EndpointTypeDef ep_out[15]; -+ USBD_EndpointTypeDef ep_out[15]; - uint32_t ep0_state; - uint32_t ep0_data_len; - uint8_t dev_state; -@@ -242,10 +243,14 @@ - - USBD_SetupReqTypedef request; - USBD_DescriptorsTypeDef *pDesc; -- USBD_ClassTypeDef *pClass; -- void *pClassData; -- void *pUserData; -- void *pData; -+ USBD_ClassTypeDef *pClass; // the composite class -+ void *pClassData; -+ void *pUserData; -+ void *pClassData2; // used for secondary class -+ void *pUserData2; // used for secondary class -+ void *pClassData3; // used for tertiary class -+ void *pUserData3; // used for tertiary class -+ void *pData; // this is a pointer to the low level registers struct - } USBD_HandleTypeDef; - - /** -@@ -262,8 +267,14 @@ - - #define LOBYTE(x) ((uint8_t)(x & 0x00FF)) - #define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) -+ -+#ifndef MIN - #define MIN(a, b) (((a) < (b)) ? (a) : (b)) -+#endif -+ -+#ifndef MAX - #define MAX(a, b) (((a) > (b)) ? (a) : (b)) -+#endif - - - #if defined ( __GNUC__ ) diff --git a/cortex_handlers.c b/cortex_handlers.c index f4022cb..cefc825 100644 --- a/cortex_handlers.c +++ b/cortex_handlers.c @@ -34,7 +34,7 @@ void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) // && (__CORTEX_M >= 3) #if VERBOSE_HARDFAULT -void __attribute__((used)) HardFault_DumpRegisters( uint32_t *origStack, uint32_t lr_value) +void __attribute__((used)) HardFault_DumpRegisters(const uint32_t *origStack, uint32_t lr_value) { /* These are volatile to try and prevent the compiler/linker optimising them away as the variables never actually get used. If the debugger won't show the diff --git a/framework/resources.c b/framework/resources.c index 0968585..5422c71 100644 --- a/framework/resources.c +++ b/framework/resources.c @@ -6,6 +6,7 @@ #include "unit.h" #include "resources.h" #include "hw_utils.h" +#include "cfg_utils.h" #include "unit_registry.h" static bool rsc_initialized = false; @@ -50,6 +51,27 @@ const char * rsc_get_name(Resource rsc) return rsc_names[rsc - R_EXTI15 - 1]; } +/** Convert a pin to resource handle */ +Resource rsc_portpin2rsc(char port_name, uint8_t pin_number, bool *suc) +{ + assert_param(suc != NULL); + + if(port_name < 'A' || port_name >= ('A'+PORTS_COUNT)) { + dbg("Bad port: %c", port_name); // TODO proper report + *suc = false; + return R_NONE; + } + + if(pin_number > 15) { + dbg("Bad pin: %d", pin_number); // TODO proper report + *suc = false; + return R_NONE; + } + + uint8_t num = (uint8_t) (port_name - 'A'); + + return R_PA0 + num*16 + pin_number; +} const char * rsc_get_owner_name(Resource rsc) { @@ -120,17 +142,11 @@ error_t rsc_claim_range(Unit *unit, Resource rsc0, Resource rsc1) return E_SUCCESS; } - error_t rsc_claim_gpios(Unit *unit, char port_name, uint16_t pins) { - bool suc = true; - for (int i = 0; i < 16; i++) { if (pins & (1 << i)) { - Resource rsc = hw_pin2resource(port_name, (uint8_t) i, &suc); - if (!suc) return E_BAD_CONFIG; - - TRY(rsc_claim(unit, rsc)); + TRY(rsc_claim_pin(unit, port_name, (uint8_t)i)); } } return E_SUCCESS; @@ -140,7 +156,7 @@ error_t rsc_claim_gpios(Unit *unit, char port_name, uint16_t pins) error_t rsc_claim_pin(Unit *unit, char port_name, uint8_t pin) { bool suc = true; - Resource rsc = hw_pin2resource(port_name, pin, &suc); + Resource rsc = rsc_portpin2rsc(port_name, pin, &suc); if (!suc) return E_BAD_CONFIG; TRY(rsc_claim(unit, rsc)); return E_SUCCESS; @@ -241,7 +257,7 @@ void rsc_print_all_available(IniWriter *iw) if (i%16 == 0) { // here we print the previous port if (bitmap != 0) { - iw_string(iw, pinmask2str(bitmap, iwbuffer)); + iw_string(iw, cfg_pinmask_encode(bitmap, iwbuffer, 0)); bitmap = 0; } @@ -256,7 +272,7 @@ void rsc_print_all_available(IniWriter *iw) } // the last one if (bitmap != 0) { - iw_string(iw, pinmask2str(bitmap, iwbuffer)); + iw_string(iw, cfg_pinmask_encode(bitmap, iwbuffer, 0)); } iw_newline(iw); iw_newline(iw); diff --git a/framework/resources.h b/framework/resources.h index 7ee9f4f..ad1b2c5 100644 --- a/framework/resources.h +++ b/framework/resources.h @@ -94,6 +94,16 @@ void rsc_free(Unit *unit, Resource rsc); */ void rsc_free_range(Unit *unit, Resource rsc0, Resource rsc1); +/** + * Convert pin name and number to a resource enum + * + * @param port_name - char 'A'..'Z' + * @param pin_number - number 0..15 + * @param suc - set to false on failure, left unchanged on success + * @return the resource, or R_NONE + */ +Resource rsc_portpin2rsc(char port_name, uint8_t pin_number, bool *suc); + /** * Get name of a resource by the Resource enum. * Uses a static buffer, DO NOT store the returned pointer. diff --git a/framework/settings.c b/framework/settings.c index f4360bc..2673dae 100644 --- a/framework/settings.c +++ b/framework/settings.c @@ -2,7 +2,6 @@ // Created by MightyPork on 2017/11/26. // -#include "utils/avrlibc.h" #include "platform.h" #include "utils/hexdump.h" #include "settings.h" @@ -10,6 +9,7 @@ #include "system_settings.h" #include "utils/str_utils.h" #include "unit_base.h" +#include "utils/avrlibc.h" // pre-declarations static void savebuf_flush(PayloadBuilder *pb, bool final); diff --git a/framework/system_settings.c b/framework/system_settings.c index 117340e..73f8ae7 100644 --- a/framework/system_settings.c +++ b/framework/system_settings.c @@ -6,6 +6,7 @@ #include "system_settings.h" #include "utils/str_utils.h" #include "platform/lock_jumper.h" +#include "cfg_utils.h" struct system_settings SystemSettings; @@ -77,12 +78,12 @@ bool systemsettings_load_ini(const char *restrict key, const char *restrict valu { bool suc = true; if (streq(key, "expose_vcom")) { - bool yn = str_parse_yn(value, &suc); + bool yn = cfg_bool_parse(value, &suc); if (suc) SystemSettings.visible_vcom = yn; } if (streq(key, "ini_comments")) { - bool yn = str_parse_yn(value, &suc); + bool yn = cfg_bool_parse(value, &suc); if (suc) SystemSettings.ini_comments = yn; } diff --git a/framework/unit_base.h b/framework/unit_base.h index 6ad667b..5d012e1 100644 --- a/framework/unit_base.h +++ b/framework/unit_base.h @@ -8,6 +8,7 @@ #include "platform.h" #include "unit.h" #include "hw_utils.h" +#include "cfg_utils.h" #include "resources.h" #include "utils/str_utils.h" #include "utils/malloc_safe.h" diff --git a/gex.mk b/gex.mk index 91ca96f..a6d40c6 100644 --- a/gex.mk +++ b/gex.mk @@ -95,7 +95,7 @@ GEX_CDEFS = $(GEX_CDEFS_BASE) \ -DUSE_STACK_MONITOR=1 \ -DUSE_DEBUG_UART=1 \ -DDEBUG_MALLOC=0 \ - -DDEBUG_RSC=0 + -DDEBUG_RSC=1 endif diff --git a/platform/cfg_utils.c b/platform/cfg_utils.c new file mode 100644 index 0000000..b8bef60 --- /dev/null +++ b/platform/cfg_utils.c @@ -0,0 +1,299 @@ +// +// Created by MightyPork on 2018/02/23. +// + +#include "cfg_utils.h" +#include "hw_utils.h" +#include "utils/avrlibc.h" +#include "utils/str_utils.h" + +/** Parse a string representation of a pin directly to a resource constant */ +Resource cfg_pinrsc_parse(const char *str, bool *suc) +{ + char pname; + uint8_t pnum; + + if (!cfg_portpin_parse(str, &pname, &pnum)) { + *suc = false; + return R_NONE; + } + + return rsc_portpin2rsc(pname, pnum, suc); +} + +/** Convert a resource to a pin name - uses a static buffer, result must not be stored! */ +char *cfg_pinrsc_encode(Resource rsc) +{ + static char buf[4]; + uint32_t index = rsc - R_PA0; + uint32_t portnum = (index/16); + uint8_t pinnum = (uint8_t) (index % 16); + if (portnum >= PORTS_COUNT) return ""; + buf[0] = (char) ('A' + portnum); + if (pinnum>9) { + buf[1] = '1'; + buf[2] = (char) ('0' + (pinnum - 10)); + buf[3] = 0; + } else { + buf[1] = (char) ('0' + pinnum); + buf[2] = 0; + } + return buf; +} + +/** Parse single pin */ +bool cfg_portpin_parse(const char *value, char *targetName, uint8_t *targetNumber) +{ + // discard leading 'P' + if (value[0] == 'P') { + value++; + } + + size_t len = strlen(value); + if (len<2||len>3) return false; + + *targetName = (uint8_t) value[0]; + if (!(*targetName >= 'A' && *targetName <= 'H')) return false; + + // lets just hope it's OK + *targetNumber = (uint8_t) avr_atoi(value + 1); + return true; +} + +/** Parse port name */ +bool cfg_port_parse(const char *value, char *targetName) +{ + *targetName = (uint8_t) value[0]; + if (!(*targetName >= 'A' && *targetName < 'A' + PORTS_COUNT)) return false; + return true; +} + +/** Parse a list of pin numbers with ranges and commans/semicolons to a bitmask */ +uint32_t cfg_pinmask_parse_32(const char *value, bool *suc) +{ + uint32_t bits = 0; + uint32_t acu = 0; + bool inrange = false; + uint32_t rangestart = 0; + + // shortcut if none are set + if (value[0] == 0) return 0; + + char c; + do { + c = *value++; + if (c == ' ' || c == '\t') { + // skip + } + else if (c >= '0' && c <= '9') { + acu = acu*10 + (c-'0'); + } + else if (c == ',' || c == ';' || c == 0) { + // end of number or range + if (!inrange) rangestart = acu; + + // swap them if they're in the wrong order + if (acu < rangestart) { + uint32_t swp = acu; + acu = rangestart; + rangestart = swp; + } + + if (rangestart > 31) rangestart = 31; + if (acu > 31) acu = 31; + + for(uint32_t i=rangestart; i <= acu; i++) { + bits |= 1<>= 1; + } + + if (bit) { + if (!on) { + start = (uint32_t) i; + on = true; + } + } else { + if (on) { + if (!first) { + b += SPRINTF(b, ", "); + } + + if (start == (uint32_t)(i - 1)) { + b += SPRINTF(b, "%"PRIu32, start); + } else { + b += SPRINTF(b, "%"PRIu32"-%"PRIu32, start, i - 1); + } + + first = false; + on = false; + } + } + } + } else { + for (int32_t i = 31; i >= -1; i--) { + if (i == -1) { + bit = false; + } else { + bit = 0 != (pins & 0x80000000); + pins <<= 1; + } + + if (bit) { + if (!on) { + start = (uint32_t) i; + on = true; + } + } else { + if (on) { + if (!first) { + b += SPRINTF(b, ", "); + } + + if (start == (uint32_t) (i + 1)) { + b += SPRINTF(b, "%"PRIu32, start); + } else { + b += SPRINTF(b, "%"PRIu32"-%"PRIu32, start, i + 1); + } + + first = false; + on = false; + } + } + } + } + + return buffer; +} + +bool cfg_bool_parse(const char *str, bool *suc) +{ + // TODO implement strcasecmp without the locale crap from newlib and use it here + if (streq(str, "Y")) return true; + if (streq(str, "N")) return false; + + if (streq(str, "1")) return true; + if (streq(str, "0")) return false; + + if (streq(str, "H")) return true; + if (streq(str, "L")) return false; + + if (streq(str, "YES")) return true; + if (streq(str, "NO")) return false; + + if (streq(str, "ON")) return true; + if (streq(str, "OFF")) return false; + + *suc = false; + return false; +} + +/** Convert number to one of 2 options */ +const char *cfg_enum2_encode(uint32_t n, + uint32_t na, const char *a, + uint32_t nb, const char *b) +{ + if (n == nb) return b; + return a; +} + +/** Convert number to one of 3 options */ +const char *cfg_enum3_encode(uint32_t n, + uint32_t na, const char *a, + uint32_t nb, const char *b, + uint32_t nc, const char *c) +{ + if (n == nb) return b; + if (n == nc) return c; + return a; +} + +/** Convert number to one of 4 options */ +const char *cfg_enum4_encode(uint32_t n, + uint32_t na, const char *a, + uint32_t nb, const char *b, + uint32_t nc, const char *c, + uint32_t nd, const char *d) +{ + if (n == nb) return b; + if (n == nc) return c; + if (n == nd) return d; + return a; +} + +uint32_t cfg_enum2_parse(const char *value, + const char *a, uint32_t na, + const char *b, uint32_t nb, + bool *suc) +{ + if (streq(value, a)) return na; + if (streq(value, b)) return nb; + *suc = false; + return na; +} + +uint32_t cfg_enum3_parse(const char *value, + const char *a, uint32_t na, + const char *b, uint32_t nb, + const char *c, uint32_t nc, + bool *suc) +{ + if (streq(value, a)) return na; + if (streq(value, b)) return nb; + if (streq(value, c)) return nc; + *suc = false; + return na; +} + +uint32_t cfg_enum4_parse(const char *value, + const char *a, uint32_t na, + const char *b, uint32_t nb, + const char *c, uint32_t nc, + const char *d, uint32_t nd, + bool *suc) +{ + if (streq(value, a)) return na; + if (streq(value, b)) return nb; + if (streq(value, c)) return nc; + if (streq(value, d)) return nd; + *suc = false; + return na; +} diff --git a/platform/cfg_utils.h b/platform/cfg_utils.h new file mode 100644 index 0000000..05f8ebe --- /dev/null +++ b/platform/cfg_utils.h @@ -0,0 +1,153 @@ +// +// Created by MightyPork on 2018/02/23. +// + +#ifndef GEX_F072_CFG_UTILS_H +#define GEX_F072_CFG_UTILS_H + +#include "platform.h" +#include "rsc_enum.h" +#include "utils/avrlibc.h" + +/** + * Parse a pin name (e.g. PA0 or A0) to port name and pin number + * + * @param str - source string + * @param targetName - output: port name (one character) + * @param targetNumber - output: pin number 0-15 + * @return success + */ +bool cfg_portpin_parse(const char *str, char *targetName, uint8_t *targetNumber); + +/** + * Parse a string representation of a pin directly to a resource constant + * + * @param[in] str - source string - e.g. PA0 or A0 + * @param[out] suc - written to false on failure + * @return the parsed resource + */ +Resource cfg_pinrsc_parse(const char *str, bool *suc); + +/** + * Convert a resource to a pin name - uses a static buffer, result must not be stored! + * + * @param[in] rsc - resource to print + * @return a pointer to a static buffer used for exporting the names + */ +char *cfg_pinrsc_encode(Resource rsc); + +/** + * Parse a port name (one character) - validates that it's within range + * + * @param value - source string + * @param targetName - output: port name (one character) + * @return success + */ +bool cfg_port_parse(const char *value, char *targetName); + +/** + * Parse a list of pin numbers with ranges and commands/semicolons to a bitmask. + * Supported syntax: + * - comma separated numbers + * - numbers connected by dash or colon form a range (can be in any order) + * + * @param value - source string + * @param suc - set to False if parsing failed + * @return the resulting bitmap + */ +uint32_t cfg_pinmask_parse_32(const char *value, bool *suc); + +/** same as cfg_pinmask_parse_32(), but with a cast to u16 */ +static inline uint16_t cfg_pinmask_parse(const char *value, bool *suc) +{ + return (uint16_t) cfg_pinmask_parse_32(value, suc); +} + +/** + * Convert a pin bitmap to the ASCII format understood by str_parse_pinmask() + * + * @param[in] pins - sparse pin map + * @param[out] buffer - output string buffer + * @param[in] ascending - use ordering 0..31 rather than 31..0 + * @return the output buffer + */ +char *cfg_pinmask_encode(uint32_t pins, char *buffer, bool ascending); + + +/** Parse Y/N to bool */ +bool cfg_bool_parse(const char *str, bool *suc); + +/** Convert number to one of 4 options */ +const char *cfg_enum2_encode(uint32_t n, + uint32_t na, const char *a, + uint32_t nb, const char *b); + +/** Convert number to one of 4 options */ +const char *cfg_enum3_encode(uint32_t n, + uint32_t na, const char *a, + uint32_t nb, const char *b, + uint32_t nc, const char *c); + +/** Convert number to one of 4 options */ +const char *cfg_enum4_encode(uint32_t n, + uint32_t na, const char *a, + uint32_t nb, const char *b, + uint32_t nc, const char *c, + uint32_t nd, const char *d); + +/** Convert string to one of two numeric options */ +uint32_t cfg_enum2_parse(const char *tpl, + const char *a, uint32_t na, + const char *b, uint32_t nb, + bool *suc); + +/** Convert string to one of three numeric options */ +uint32_t cfg_enum3_parse(const char *tpl, + const char *a, uint32_t na, + const char *b, uint32_t nb, + const char *c, uint32_t nc, + bool *suc); + +/** Convert string to one of four numeric options */ +uint32_t cfg_enum4_parse(const char *tpl, + const char *a, uint32_t na, + const char *b, uint32_t nb, + const char *c, uint32_t nc, + const char *d, uint32_t nd, + bool *suc); + +/** Convert bool to a Y or N constant string */ +#define str_yn(cond) ((cond) ? ("Y") : ("N")) + + +static inline uint8_t cfg_u8_parse(const char *value, bool *suc) +{ + return (uint8_t) avr_atoi(value); +} + +static inline int8_t cfg_i8_parse(const char *value, bool *suc) +{ + return (int8_t) avr_atoi(value); +} + +static inline uint16_t cfg_u16_parse(const char *value, bool *suc) +{ + return (uint16_t) avr_atoi(value); +} + +static inline int16_t cfg_i16_parse(const char *value, bool *suc) +{ + return (int16_t) avr_atoi(value); +} + +static inline uint32_t cfg_u32_parse(const char *value, bool *suc) +{ + return (uint32_t) avr_atoi(value); +} + +static inline int32_t cfg_i32_parse(const char *value, bool *suc) +{ + return (int32_t) avr_atoi(value); +} + +#endif //GEX_F072_CFG_UTILS_H diff --git a/platform/hw_utils.c b/platform/hw_utils.c index 3753ef8..3fdd9ac 100644 --- a/platform/hw_utils.c +++ b/platform/hw_utils.c @@ -6,7 +6,6 @@ #include "utils/avrlibc.h" #include "hw_utils.h" - /** Convert pin number to LL bitfield */ uint32_t hw_pin2ll(uint8_t pin_number, bool *suc) { @@ -36,210 +35,18 @@ GPIO_TypeDef *hw_port2periph(char port_name, bool *suc) return GPIO_PERIPHS[num]; } -/** Convert a pin to resource handle */ -Resource hw_pin2resource(char port_name, uint8_t pin_number, bool *suc) -{ - assert_param(suc != NULL); - - if(port_name < 'A' || port_name >= ('A'+PORTS_COUNT)) { - dbg("Bad port: %c", port_name); // TODO proper report - *suc = false; - return R_NONE; - } - - if(pin_number > 15) { - dbg("Bad pin: %d", pin_number); // TODO proper report - *suc = false; - return R_NONE; - } - - uint8_t num = (uint8_t) (port_name - 'A'); - - return R_PA0 + num*16 + pin_number; -} - -/** Parse single pin */ -bool parse_pin(const char *value, char *targetName, uint8_t *targetNumber) -{ - // discard leading 'P' - if (value[0] == 'P') { - value++; - } - - size_t len = strlen(value); - if (len<2||len>3) return false; - - *targetName = (uint8_t) value[0]; - if (!(*targetName >= 'A' && *targetName <= 'H')) return false; - - // lets just hope it's OK - *targetNumber = (uint8_t) avr_atoi(value + 1); - return true; -} - -/** Parse port name */ -bool parse_port_name(const char *value, char *targetName) +/** Convert a pin resource to it's LL lib values */ +bool hw_pinrsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin) { - *targetName = (uint8_t) value[0]; - if (!(*targetName >= 'A' && *targetName < 'A' + PORTS_COUNT)) return false; + uint32_t index = rsc - R_PA0; + uint32_t pname = (index/16); + uint8_t pnum = (uint8_t) (index % 16); + if (pname >= PORTS_COUNT) return false; + *port = GPIO_PERIPHS[pname]; + *llpin = LL_GPIO_PINS[pnum]; return true; } -/** Parse a list of pin numbers with ranges and commans/semicolons to a bitmask */ -uint32_t parse_pinmask(const char *value, bool *suc) -{ - uint32_t bits = 0; - uint32_t acu = 0; - bool inrange = false; - uint32_t rangestart = 0; - - // shortcut if none are set - if (value[0] == 0) return 0; - - char c; - do { - c = *value++; - if (c == ' ' || c == '\t') { - // skip - } - else if (c >= '0' && c <= '9') { - acu = acu*10 + (c-'0'); - } - else if (c == ',' || c == ';' || c == 0) { - // end of number or range - if (!inrange) rangestart = acu; - - // swap them if they're in the wrong order - if (acu < rangestart) { - uint32_t swp = acu; - acu = rangestart; - rangestart = swp; - } - - if (rangestart > 31) rangestart = 31; - if (acu > 31) acu = 31; - - for(uint32_t i=rangestart; i <= acu; i++) { - bits |= 1<= -1; i--) { - bool bit; - - if (i == -1) { - bit = false; - } else { - bit = 0 != (pins & 0x80000000); - pins <<= 1; - } - - if (bit) { - if (!on) { - start = (uint32_t) i; - on = true; - } - } else { - if (on) { - if (!first) { - b += SPRINTF(b, ", "); - } - - if (start == (uint32_t)(i+1)) { - b += SPRINTF(b, "%"PRIu32, start); - } - else { - b += SPRINTF(b, "%"PRIu32"-%"PRIu32, start, i + 1); - } - - first = false; - on = false; - } - } - } - - return buffer; -} - -char * pinmask2str_up(uint32_t pins, char *buffer) -{ - char *b = buffer; - uint32_t start = 0; - bool on = false; - bool first = true; - - // shortcut if none are set - if (pins == 0) { - buffer[0] = 0; - return buffer; - } - - for (int32_t i = 0; i <= 32; i++) { - bool bit; - - if (i == 32) { - bit = false; - } else { - bit = 0 != (pins & 1); - pins >>= 1; - } - - if (bit) { - if (!on) { - start = (uint32_t) i; - on = true; - } - } else { - if (on) { - if (!first) { - b += SPRINTF(b, ", "); - } - - if (start == (uint32_t)(i-1)) { - b += SPRINTF(b, "%"PRIu32, start); - } - else { - b += SPRINTF(b, "%"PRIu32"-%"PRIu32, start, i - 1); - } - - first = false; - on = false; - } - } - } - - return buffer; -} - #pragma GCC push_options #pragma GCC optimize ("O2") /** spread a packed pinfield using a mask */ @@ -285,25 +92,13 @@ uint32_t pinmask_pack_32(uint32_t spread, uint32_t mask) return result; } -/** Convert spread port pin number to a packed index using a mask */ -uint8_t pinmask_translate(uint32_t mask, uint8_t index) -{ - int cnt = 0; - for (int i = 0; i<32; i++) { - if (mask & (1<resources, rsc)) { + if (RSC_IS_HELD(unit->resources, (Resource)rsc)) { rsc_dbg("Freeing pin %s", rsc_get_name((Resource)rsc)); GPIO_TypeDef *port = GPIO_PERIPHS[(rsc-R_PA0) / 16]; uint32_t ll_pin = LL_GPIO_PINS[(rsc-R_PA0)%16]; @@ -360,8 +155,8 @@ error_t hw_configure_sparse_pins(char port_name, uint16_t mask, GPIO_TypeDef **p } /** Solve a timer/counter's count and prescaller value */ -bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, - uint16_t *presc, uint32_t *count, float *real_freq) +bool hw_solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, + uint16_t *presc, uint32_t *count, float *real_freq) { if (required_freq == 0) return false; @@ -394,54 +189,6 @@ bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, return true; } - -/** Parse a string representation of a pin directly to a resource constant */ -Resource parse_pin2rsc(const char *str, bool *suc) -{ - char pname; - uint8_t pnum; - - if (!parse_pin(str, &pname, &pnum)) { - *suc = false; - return R_NONE; - } - - return hw_pin2resource(pname, pnum, suc); -} - -/** Convert a resource to a pin name - uses a static buffer, result must not be stored! */ -char *str_rsc2pin(Resource rsc) -{ - static char buf[4]; - uint32_t index = rsc - R_PA0; - uint32_t portnum = (index/16); - uint8_t pinnum = (uint8_t) (index % 16); - if (portnum >= PORTS_COUNT) return ""; - buf[0] = (char) ('A' + portnum); - if (pinnum>9) { - buf[1] = '1'; - buf[2] = (char) ('0' + (pinnum - 10)); - buf[3] = 0; - } else { - buf[1] = (char) ('0' + pinnum); - buf[2] = 0; - } - return buf; -} - -/** Convert a pin resource to it's LL lib values */ -bool pinRsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin) -{ - uint32_t index = rsc - R_PA0; - uint32_t pname = (index/16); - uint8_t pnum = (uint8_t) (index % 16); - if (pname >= PORTS_COUNT) return false; - *port = GPIO_PERIPHS[pname]; - *llpin = LL_GPIO_PINS[pnum]; - return true; -} - - void hw_periph_clock_enable(void *periph) { // GPIOs are enabled by default on start-up diff --git a/platform/hw_utils.h b/platform/hw_utils.h index c5f4c89..5f9d358 100644 --- a/platform/hw_utils.h +++ b/platform/hw_utils.h @@ -21,16 +21,6 @@ */ uint32_t hw_pin2ll(uint8_t pin_number, bool *suc); -/** - * Convert pin name and number to a resource enum - * - * @param port_name - char 'A'..'Z' - * @param pin_number - number 0..15 - * @param suc - set to false on failure, left unchanged on success - * @return the resource, or R_NONE - */ -Resource hw_pin2resource(char port_name, uint8_t pin_number, bool *suc); - /** * Convert port name to peripheral instance * @@ -40,25 +30,6 @@ Resource hw_pin2resource(char port_name, uint8_t pin_number, bool *suc); */ GPIO_TypeDef *hw_port2periph(char port_name, bool *suc); -/** - * Parse a pin name (e.g. PA0 or A0) to port name and pin number - * - * @param str - source string - * @param targetName - output: port name (one character) - * @param targetNumber - output: pin number 0-15 - * @return success - */ -bool parse_pin(const char *str, char *targetName, uint8_t *targetNumber); - -/** - * Parse a string representation of a pin directly to a resource constant - * - * @param[in] str - source string - e.g. PA0 or A0 - * @param[out] suc - written to false on failure - * @return the parsed resource - */ -Resource parse_pin2rsc(const char *str, bool *suc); - /** * Convert a pin resource to it's LL lib values * @@ -67,56 +38,7 @@ Resource parse_pin2rsc(const char *str, bool *suc); * @param[out] llpin - output LL pin mask * @return success */ -bool pinRsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin); - -/** - * Convert a resource to a pin name - uses a static buffer, result must not be stored! - * - * @param[in] rsc - resource to print - * @return a pointer to a static buffer used for exporting the names - */ -char *str_rsc2pin(Resource rsc); - -/** - * Parse a port name (one character) - validates that it's within range - * - * @param value - source string - * @param targetName - output: port name (one character) - * @return success - */ -bool parse_port_name(const char *value, char *targetName); - -/** - * Parse a list of pin numbers with ranges and commands/semicolons to a bitmask. - * Supported syntax: - * - comma separated numbers - * - numbers connected by dash or colon form a range (can be in any order) - * - * @param value - source string - * @param suc - set to False if parsing failed - * @return the resulting bitmap - */ -uint32_t parse_pinmask(const char *value, bool *suc); - -/** - * Convert a pin bitmap to the ASCII format understood by str_parse_pinmask() - * This is the downto variant (15..0) - * - * @param pins - sparse pin map - * @param buffer - output string buffer - * @return the output buffer - */ -char * pinmask2str(uint32_t pins, char *buffer); - -/** - * Convert a pin bitmap to the ASCII format understood by str_parse_pinmask() - * This is the ascending variant (0..15) - * - * @param pins - sparse pin map - * @param buffer - output string buffer - * @return the output buffer - */ -char * pinmask2str_up(uint32_t pins, char *buffer); +bool hw_pinrsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin) __attribute__((warn_unused_result)); /** * Spread packed port pins using a mask @@ -148,13 +70,6 @@ static inline uint16_t pinmask_pack(uint32_t spread, uint32_t mask) return (uint16_t) pinmask_pack_32(spread, mask); } -/** - * Convert spread port pin number to a packed index using a mask - * - * eg. with a mask 0b1010 and index 3, the result is 1 (bit 1 of the packed - 0bX0) - */ -uint8_t pinmask_translate(uint32_t mask, uint8_t index); - /** * Set all GPIO resources held by unit to analog. * This is a part of unit teardown. @@ -219,8 +134,8 @@ void hw_periph_clock_disable(void *periph); * @param[out] real_freq - field for storing the computed real frequency * @return true on success */ -bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, - uint16_t *presc, uint32_t *count, float *real_freq); +bool hw_solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, + uint16_t *presc, uint32_t *count, float *real_freq) __attribute__((warn_unused_result)); #define hw_wait_while(call, timeout) \ do { \ diff --git a/platform/lock_jumper.c b/platform/lock_jumper.c index 81315e5..6ea50f4 100644 --- a/platform/lock_jumper.c +++ b/platform/lock_jumper.c @@ -26,16 +26,11 @@ void LockJumper_Init(void) { bool suc = true; - // Resolve and claim resource - Resource rsc = hw_pin2resource(LOCK_JUMPER_PORT, LOCK_JUMPER_PIN, &suc); + Resource pinrsc = rsc_portpin2rsc(LOCK_JUMPER_PORT, LOCK_JUMPER_PIN, &suc); assert_param(suc); - assert_param(E_SUCCESS == rsc_claim(&UNIT_SYSTEM, rsc)); - - // Resolve pin - lock_periph = hw_port2periph(LOCK_JUMPER_PORT, &suc); - lock_llpin = hw_pin2ll(LOCK_JUMPER_PIN, &suc); - assert_param(suc); + assert_param(E_SUCCESS == rsc_claim(&UNIT_SYSTEM, pinrsc)); + assert_param(hw_pinrsc2ll(pinrsc, &lock_periph, &lock_llpin)); // Configure for input LL_GPIO_SetPinMode(lock_periph, lock_llpin, LL_GPIO_MODE_INPUT); diff --git a/platform/status_led.c b/platform/status_led.c index dc50d26..cc66f2f 100644 --- a/platform/status_led.c +++ b/platform/status_led.c @@ -50,13 +50,7 @@ static inline void led_off(void) /** Set up the LED */ void Indicator_Init(void) { - bool suc = true; - - // Resolve and claim resource - Resource rsc = hw_pin2resource(STATUS_LED_PORT, STATUS_LED_PIN, &suc); - assert_param(suc); - - assert_param(E_SUCCESS == rsc_claim(&UNIT_SYSTEM, rsc)); + assert_param(E_SUCCESS == rsc_claim_pin(&UNIT_SYSTEM, STATUS_LED_PORT, STATUS_LED_PIN)); } /** Set indicator ON */ diff --git a/tasks/task_main.c b/tasks/task_main.c index 17e9757..0653154 100644 --- a/tasks/task_main.c +++ b/tasks/task_main.c @@ -12,8 +12,6 @@ #include "usbd_msc.h" #include "task_main.h" -extern void plat_init(void); - /* TaskUsbEvent function */ void TaskMain(void const * argument) { diff --git a/units/1wire/_ow_init.c b/units/1wire/_ow_init.c index 0893d10..713a886 100644 --- a/units/1wire/_ow_init.c +++ b/units/1wire/_ow_init.c @@ -40,7 +40,7 @@ error_t OW_init(Unit *unit) // --- Parse config --- priv->ll_pin = hw_pin2ll(priv->pin_number, &suc); priv->port = hw_port2periph(priv->port_name, &suc); - Resource rsc = hw_pin2resource(priv->port_name, priv->pin_number, &suc); + Resource rsc = rsc_portpin2rsc(priv->port_name, priv->pin_number, &suc); if (!suc) return E_BAD_CONFIG; // --- Claim resources --- diff --git a/units/1wire/_ow_settings.c b/units/1wire/_ow_settings.c index c43b3bf..105e086 100644 --- a/units/1wire/_ow_settings.c +++ b/units/1wire/_ow_settings.c @@ -44,10 +44,10 @@ error_t OW_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "pin")) { - suc = parse_pin(value, &priv->port_name, &priv->pin_number); + suc = cfg_portpin_parse(value, &priv->port_name, &priv->pin_number); } else if (streq(key, "parasitic")) { - priv->parasitic = str_parse_yn(value, &suc); + priv->parasitic = cfg_bool_parse(value, &suc); } else { return E_BAD_KEY; diff --git a/units/adc/_adc_init.c b/units/adc/_adc_init.c index f285d61..59779ce 100644 --- a/units/adc/_adc_init.c +++ b/units/adc/_adc_init.c @@ -35,7 +35,7 @@ error_t UADC_SetSampleRate(Unit *unit, uint32_t hertz) uint16_t presc; uint32_t count; - if (!solve_timer(PLAT_APB1_HZ, hertz, true, &presc, &count, &priv->real_frequency)) { + if (!hw_solve_timer(PLAT_APB1_HZ, hertz, true, &presc, &count, &priv->real_frequency)) { dbg("Failed to resolve timer params."); return E_BAD_VALUE; } diff --git a/units/adc/_adc_settings.c b/units/adc/_adc_settings.c index ae1e33b..de71cea 100644 --- a/units/adc/_adc_settings.c +++ b/units/adc/_adc_settings.c @@ -48,20 +48,20 @@ error_t UADC_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "channels")) { - priv->cfg.channels = parse_pinmask(value, &suc); + priv->cfg.channels = cfg_pinmask_parse_32(value, &suc); } else if (streq(key, "sample_time")) { - priv->cfg.sample_time = (uint8_t) avr_atoi(value); + priv->cfg.sample_time = cfg_u8_parse(value, &suc); if (priv->cfg.sample_time > 7) return E_BAD_VALUE; } else if (streq(key, "frequency")) { - priv->cfg.frequency = (uint32_t) avr_atoi(value); + priv->cfg.frequency = cfg_u32_parse(value, &suc); } else if (streq(key, "buffer_size")) { - priv->cfg.buffer_size = (uint32_t) avr_atoi(value); + priv->cfg.buffer_size = cfg_u32_parse(value, &suc); } else if (streq(key, "avg_factor")) { - priv->cfg.averaging_factor = (uint16_t) avr_atoi(value); + priv->cfg.averaging_factor = cfg_u16_parse(value, &suc); if (priv->cfg.averaging_factor > 1000) return E_BAD_VALUE; } else { @@ -80,7 +80,7 @@ void UADC_writeIni(Unit *unit, IniWriter *iw) iw_comment(iw, "Enabled channels, comma separated"); iw_comment(iw, " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17"); iw_comment(iw, "A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 C0 C1 C2 C3 C4 C5 Tsens Vref"); - iw_entry(iw, "channels", "%s", pinmask2str_up(priv->cfg.channels, unit_tmp512)); + iw_entry(iw, "channels", cfg_pinmask_encode(priv->cfg.channels, unit_tmp512, true)); iw_cmt_newline(iw); iw_comment(iw, "Sampling time (0-7)"); diff --git a/units/digital_in/_din_settings.c b/units/digital_in/_din_settings.c index 5c5f235..3073e11 100644 --- a/units/digital_in/_din_settings.c +++ b/units/digital_in/_din_settings.c @@ -57,28 +57,28 @@ error_t DIn_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "port")) { - suc = parse_port_name(value, &priv->port_name); + suc = cfg_port_parse(value, &priv->port_name); } else if (streq(key, "pins")) { - priv->pins = parse_pinmask(value, &suc); + priv->pins = cfg_pinmask_parse(value, &suc); } else if (streq(key, "pull-up")) { - priv->pullup = parse_pinmask(value, &suc); + priv->pullup = cfg_pinmask_parse(value, &suc); } else if (streq(key, "pull-down")) { - priv->pulldown = parse_pinmask(value, &suc); + priv->pulldown = cfg_pinmask_parse(value, &suc); } else if (streq(key, "trig-rise")) { - priv->trig_rise = parse_pinmask(value, &suc); + priv->trig_rise = cfg_pinmask_parse(value, &suc); } else if (streq(key, "trig-fall")) { - priv->trig_fall = parse_pinmask(value, &suc); + priv->trig_fall = cfg_pinmask_parse(value, &suc); } else if (streq(key, "auto-trigger")) { - priv->def_auto = parse_pinmask(value, &suc); + priv->def_auto = cfg_pinmask_parse(value, &suc); } else if (streq(key, "hold-off")) { - priv->trig_holdoff = (uint16_t) avr_atoi(value); + priv->trig_holdoff = cfg_u16_parse(value, &suc); } else { return E_BAD_KEY; @@ -97,21 +97,21 @@ void DIn_writeIni(Unit *unit, IniWriter *iw) iw_entry(iw, "port", "%c", priv->port_name); iw_comment(iw, "Pins (comma separated, supports ranges)"); - iw_entry(iw, "pins", "%s", pinmask2str(priv->pins, unit_tmp512)); + iw_entry(iw, "pins", cfg_pinmask_encode(priv->pins, unit_tmp512, 0)); iw_comment(iw, "Pins with pull-up"); - iw_entry(iw, "pull-up", "%s", pinmask2str(priv->pullup, unit_tmp512)); + iw_entry(iw, "pull-up", cfg_pinmask_encode(priv->pullup, unit_tmp512, 0)); iw_comment(iw, "Pins with pull-down"); - iw_entry(iw, "pull-down", "%s", pinmask2str(priv->pulldown, unit_tmp512)); + iw_entry(iw, "pull-down", cfg_pinmask_encode(priv->pulldown, unit_tmp512, 0)); iw_cmt_newline(iw); iw_comment(iw, "Trigger pins activated by rising/falling edge"); - iw_entry(iw, "trig-rise", "%s", pinmask2str(priv->trig_rise, unit_tmp512)); - iw_entry(iw, "trig-fall", "%s", pinmask2str(priv->trig_fall, unit_tmp512)); + iw_entry(iw, "trig-rise", cfg_pinmask_encode(priv->trig_rise, unit_tmp512, 0)); + iw_entry(iw, "trig-fall", cfg_pinmask_encode(priv->trig_fall, unit_tmp512, 0)); iw_comment(iw, "Trigger pins auto-armed by default"); - iw_entry(iw, "auto-trigger", "%s", pinmask2str(priv->def_auto, unit_tmp512)); + iw_entry(iw, "auto-trigger", cfg_pinmask_encode(priv->def_auto, unit_tmp512, 0)); iw_comment(iw, "Triggers hold-off time (ms)"); iw_entry(iw, "hold-off", "%d", (int)priv->trig_holdoff); diff --git a/units/digital_out/_dout_settings.c b/units/digital_out/_dout_settings.c index 99cc1b3..61844fe 100644 --- a/units/digital_out/_dout_settings.c +++ b/units/digital_out/_dout_settings.c @@ -44,16 +44,16 @@ error_t DOut_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "port")) { - suc = parse_port_name(value, &priv->port_name); + suc = cfg_port_parse(value, &priv->port_name); } else if (streq(key, "pins")) { - priv->pins = (uint16_t) parse_pinmask(value, &suc); + priv->pins = cfg_pinmask_parse(value, &suc); } else if (streq(key, "initial")) { - priv->initial = (uint16_t) parse_pinmask(value, &suc); + priv->initial = cfg_pinmask_parse(value, &suc); } else if (streq(key, "open-drain")) { - priv->open_drain = (uint16_t) parse_pinmask(value, &suc); + priv->open_drain = cfg_pinmask_parse(value, &suc); } else { return E_BAD_KEY; @@ -72,11 +72,11 @@ void DOut_writeIni(Unit *unit, IniWriter *iw) iw_entry(iw, "port", "%c", priv->port_name); iw_comment(iw, "Pins (comma separated, supports ranges)"); - iw_entry(iw, "pins", "%s", pinmask2str(priv->pins, unit_tmp512)); + iw_entry(iw, "pins", cfg_pinmask_encode(priv->pins, unit_tmp512, 0)); iw_comment(iw, "Initially high pins"); - iw_entry(iw, "initial", "%s", pinmask2str(priv->initial, unit_tmp512)); + iw_entry(iw, "initial", cfg_pinmask_encode(priv->initial, unit_tmp512, 0)); iw_comment(iw, "Open-drain pins"); - iw_entry(iw, "open-drain", "%s", pinmask2str(priv->open_drain, unit_tmp512)); + iw_entry(iw, "open-drain", cfg_pinmask_encode(priv->open_drain, unit_tmp512, 0)); } diff --git a/units/fcap/_fcap_settings.c b/units/fcap/_fcap_settings.c index c6ba14b..c0034e4 100644 --- a/units/fcap/_fcap_settings.c +++ b/units/fcap/_fcap_settings.c @@ -55,27 +55,27 @@ error_t UFCAP_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "pin")) { - suc = parse_pin(value, &priv->conf.signal_pname, &priv->conf.signal_pnum); + suc = cfg_portpin_parse(value, &priv->conf.signal_pname, &priv->conf.signal_pnum); } else if (streq(key, "active-level")) { - priv->conf.active_level = (bool) avr_atoi(value); + priv->conf.active_level = cfg_bool_parse(value, &suc); } else if (streq(key, "input-filter")) { - priv->conf.dfilter = (uint8_t) avr_atoi(value); + priv->conf.dfilter = cfg_u8_parse(value, &suc); } else if (streq(key, "direct-presc")) { - priv->conf.direct_presc = (uint8_t) avr_atoi(value); + priv->conf.direct_presc = cfg_u8_parse(value, &suc); } else if (streq(key, "direct-time")) { - priv->conf.direct_msec = (uint16_t) avr_atoi(value); + priv->conf.direct_msec = cfg_u16_parse(value, &suc); } else if (streq(key, "initial-mode")) { - priv->conf.startmode = (enum fcap_opmode) str_parse_4(value, - "N", OPMODE_IDLE, - "I", OPMODE_INDIRECT_CONT, - "D", OPMODE_DIRECT_CONT, - "F", OPMODE_FREE_COUNTER, - &suc); + priv->conf.startmode = (enum fcap_opmode) cfg_enum4_parse(value, + "N", OPMODE_IDLE, + "I", OPMODE_INDIRECT_CONT, + "D", OPMODE_DIRECT_CONT, + "F", OPMODE_FREE_COUNTER, + &suc); } else{ return E_BAD_KEY; @@ -110,10 +110,10 @@ void UFCAP_writeIni(Unit *unit, IniWriter *iw) iw_cmt_newline(iw); iw_comment(iw, "Mode on startup: N-none, I-indirect, D-direct, F-free count"); - iw_entry(iw, "initial-mode", "%s", str_4(priv->conf.startmode, - OPMODE_IDLE, "N", - OPMODE_INDIRECT_CONT, "I", - OPMODE_DIRECT_CONT, "D", - OPMODE_FREE_COUNTER, "F")); + iw_entry(iw, "initial-mode", cfg_enum4_encode(priv->conf.startmode, + OPMODE_IDLE, "N", + OPMODE_INDIRECT_CONT, "I", + OPMODE_DIRECT_CONT, "D", + OPMODE_FREE_COUNTER, "F")); } diff --git a/units/i2c/_i2c_settings.c b/units/i2c/_i2c_settings.c index 72ec502..32ac280 100644 --- a/units/i2c/_i2c_settings.c +++ b/units/i2c/_i2c_settings.c @@ -49,19 +49,19 @@ error_t UI2C_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "device")) { - priv->periph_num = (uint8_t) avr_atoi(value); + priv->periph_num = cfg_u8_parse(value, &suc); } else if (streq(key, "remap")) { - priv->remap = (uint8_t) avr_atoi(value); + priv->remap = cfg_u8_parse(value, &suc); } else if (streq(key, "analog-filter")) { - priv->anf = str_parse_yn(value, &suc); + priv->anf = cfg_bool_parse(value, &suc); } else if (streq(key, "digital-filter")) { - priv->dnf = (uint8_t) avr_atoi(value); + priv->dnf = cfg_u8_parse(value, &suc); } else if (streq(key, "speed")) { - priv->speed = (uint8_t) avr_atoi(value); + priv->speed = cfg_u8_parse(value, &suc); } else { return E_BAD_KEY; @@ -99,7 +99,7 @@ void UI2C_writeIni(Unit *unit, IniWriter *iw) iw_entry(iw, "speed", "%d", (int)priv->speed); iw_comment(iw, "Analog noise filter enable (Y,N)"); - iw_entry(iw, "analog-filter", "%s", str_yn(priv->anf)); + iw_entry(iw, "analog-filter", str_yn(priv->anf)); iw_comment(iw, "Digital noise filter bandwidth (0-15)"); iw_entry(iw, "digital-filter", "%d", (int)priv->dnf); diff --git a/units/neopixel/_npx_init.c b/units/neopixel/_npx_init.c index f27a0f0..89735a0 100644 --- a/units/neopixel/_npx_init.c +++ b/units/neopixel/_npx_init.c @@ -32,7 +32,7 @@ error_t Npx_init(Unit *unit) // --- Parse config --- priv->ll_pin = hw_pin2ll(priv->pin_number, &suc); priv->port = hw_port2periph(priv->port_name, &suc); - Resource rsc = hw_pin2resource(priv->port_name, priv->pin_number, &suc); + Resource rsc = rsc_portpin2rsc(priv->port_name, priv->pin_number, &suc); if (!suc) return E_BAD_CONFIG; // --- Claim resources --- diff --git a/units/neopixel/_npx_settings.c b/units/neopixel/_npx_settings.c index cbbfbe9..8322eff 100644 --- a/units/neopixel/_npx_settings.c +++ b/units/neopixel/_npx_settings.c @@ -37,10 +37,10 @@ error_t Npx_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "pin")) { - suc = parse_pin(value, &priv->port_name, &priv->pin_number); + suc = cfg_portpin_parse(value, &priv->port_name, &priv->pin_number); } else if (streq(key, "pixels")) { - priv->pixels = (uint16_t) avr_atoi(value); + priv->pixels = cfg_u16_parse(value, &suc); } else { return E_BAD_KEY; diff --git a/units/sipo/_sipo_init.c b/units/sipo/_sipo_init.c index ed0db40..73c58cd 100644 --- a/units/sipo/_sipo_init.c +++ b/units/sipo/_sipo_init.c @@ -41,19 +41,19 @@ error_t USIPO_init(Unit *unit) // --- Parse config --- priv->store_ll = hw_pin2ll(priv->store_pnum, &suc); priv->store_port = hw_port2periph(priv->store_pname, &suc); - Resource store_rsc = hw_pin2resource(priv->store_pname, priv->store_pnum, &suc); + Resource store_rsc = rsc_portpin2rsc(priv->store_pname, priv->store_pnum, &suc); if (!suc) return E_BAD_CONFIG; TRY(rsc_claim(unit, store_rsc)); priv->shift_ll = hw_pin2ll(priv->shift_pnum, &suc); priv->shift_port = hw_port2periph(priv->shift_pname, &suc); - Resource shift_rsc = hw_pin2resource(priv->shift_pname, priv->shift_pnum, &suc); + Resource shift_rsc = rsc_portpin2rsc(priv->shift_pname, priv->shift_pnum, &suc); if (!suc) return E_BAD_CONFIG; TRY(rsc_claim(unit, shift_rsc)); priv->clear_ll = hw_pin2ll(priv->clear_pnum, &suc); priv->clear_port = hw_port2periph(priv->clear_pname, &suc); - Resource clear_rsc = hw_pin2resource(priv->clear_pname, priv->clear_pnum, &suc); + Resource clear_rsc = rsc_portpin2rsc(priv->clear_pname, priv->clear_pnum, &suc); if (!suc) return E_BAD_CONFIG; TRY(rsc_claim(unit, clear_rsc)); diff --git a/units/sipo/_sipo_settings.c b/units/sipo/_sipo_settings.c index 52c3a88..4cdce37 100644 --- a/units/sipo/_sipo_settings.c +++ b/units/sipo/_sipo_settings.c @@ -64,30 +64,30 @@ error_t USIPO_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "store-pin")) { - suc = parse_pin(value, &priv->store_pname, &priv->store_pnum); + suc = cfg_portpin_parse(value, &priv->store_pname, &priv->store_pnum); } else if (streq(key, "shift-pin")) { - suc = parse_pin(value, &priv->shift_pname, &priv->shift_pnum); + suc = cfg_portpin_parse(value, &priv->shift_pname, &priv->shift_pnum); } else if (streq(key, "clear-pin")) { - suc = parse_pin(value, &priv->clear_pname, &priv->clear_pnum); + suc = cfg_portpin_parse(value, &priv->clear_pname, &priv->clear_pnum); } else if (streq(key, "store-pol")) { - priv->store_pol = (bool) avr_atoi(value); + priv->store_pol = cfg_bool_parse(value, &suc); } else if (streq(key, "shift-pol")) { - priv->shift_pol = (bool) avr_atoi(value); + priv->shift_pol = cfg_bool_parse(value, &suc); } else if (streq(key, "clear-pol")) { - priv->clear_pol = (bool) avr_atoi(value); + priv->clear_pol = cfg_bool_parse(value, &suc); } else if (streq(key, "data-port")) { - suc = parse_port_name(value, &priv->data_pname); + suc = cfg_port_parse(value, &priv->data_pname); } else if (streq(key, "data-pins")) { - priv->data_pins = (uint16_t) parse_pinmask(value, &suc); + priv->data_pins = cfg_pinmask_parse(value, &suc); } else { @@ -117,6 +117,6 @@ void USIPO_writeIni(Unit *unit, IniWriter *iw) iw_comment(iw, "Data port and pins"); iw_entry(iw, "data-port", "%c", priv->data_pname); - iw_entry(iw, "data-pins", "%s", pinmask2str_up(priv->data_pins, unit_tmp512)); + iw_entry(iw, "data-pins", "%s", cfg_pinmask_encode(priv->data_pins, unit_tmp512, true)); } diff --git a/units/spi/_spi_settings.c b/units/spi/_spi_settings.c index b0578a6..f9ece2f 100644 --- a/units/spi/_spi_settings.c +++ b/units/spi/_spi_settings.c @@ -58,31 +58,31 @@ error_t USPI_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "device")) { - priv->periph_num = (uint8_t) avr_atoi(value); + priv->periph_num = cfg_u8_parse(value, &suc); } else if (streq(key, "remap")) { - priv->remap = (uint8_t) avr_atoi(value); + priv->remap = cfg_u8_parse(value, &suc); } else if (streq(key, "prescaller")) { - priv->prescaller = (uint16_t ) avr_atoi(value); + priv->prescaller = cfg_u16_parse(value, &suc); } else if (streq(key, "cpol")) { - priv->cpol = (bool) avr_atoi(value); + priv->cpol = cfg_bool_parse(value, &suc); } else if (streq(key, "cpha")) { - priv->cpha = (bool) avr_atoi(value); + priv->cpha = cfg_bool_parse(value, &suc); } else if (streq(key, "tx-only")) { - priv->tx_only = str_parse_yn(value, &suc); + priv->tx_only = cfg_bool_parse(value, &suc); } else if (streq(key, "first-bit")) { - priv->lsb_first = (bool)str_parse_2(value, "MSB", 0, "LSB", 1, &suc); + priv->lsb_first = (bool) cfg_enum2_parse(value, "MSB", 0, "LSB", 1, &suc); } else if (streq(key, "port")) { - suc = parse_port_name(value, &priv->ssn_port_name); + suc = cfg_port_parse(value, &priv->ssn_port_name); } else if (streq(key, "pins")) { - priv->ssn_pins = parse_pinmask(value, &suc); + priv->ssn_pins = cfg_pinmask_parse(value, &suc); } else { return E_BAD_KEY; @@ -130,14 +130,12 @@ void USPI_writeIni(Unit *unit, IniWriter *iw) iw_entry(iw, "tx-only", str_yn(priv->tx_only)); iw_comment(iw, "Bit order (LSB or MSB first)"); - iw_entry(iw, "first-bit", str_2((uint32_t)priv->lsb_first, - 0, "MSB", - 1, "LSB")); + iw_entry(iw, "first-bit", cfg_enum2_encode((uint32_t) priv->lsb_first, 0, "MSB", 1, "LSB")); iw_cmt_newline(iw); iw_comment(iw, "SS port name"); iw_entry(iw, "port", "%c", priv->ssn_port_name); iw_comment(iw, "SS pins (comma separated, supports ranges)"); - iw_entry(iw, "pins", "%s", pinmask2str(priv->ssn_pins, unit_tmp512)); + iw_entry(iw, "pins", cfg_pinmask_encode(priv->ssn_pins, unit_tmp512, 0)); } diff --git a/units/usart/_usart_settings.c b/units/usart/_usart_settings.c index c827762..dcd2ff9 100644 --- a/units/usart/_usart_settings.c +++ b/units/usart/_usart_settings.c @@ -81,66 +81,66 @@ error_t UUSART_loadIni(Unit *unit, const char *key, const char *value) struct priv *priv = unit->data; if (streq(key, "device")) { - priv->periph_num = (uint8_t) avr_atoi(value); + priv->periph_num = cfg_u8_parse(value, &suc); } else if (streq(key, "remap")) { - priv->remap = (uint8_t) avr_atoi(value); + priv->remap = cfg_u8_parse(value, &suc); } else if (streq(key, "baud-rate")) { - priv->baudrate = (uint32_t ) avr_atoi(value); + priv->baudrate = cfg_u32_parse(value, &suc); } else if (streq(key, "parity")) { - priv->parity = (uint8_t) str_parse_3(value, - "NONE", 0, - "ODD", 1, - "EVEN", 2, &suc); + priv->parity = (uint8_t) cfg_enum3_parse(value, + "NONE", 0, + "ODD", 1, + "EVEN", 2, &suc); } else if (streq(key, "stop-bits")) { - priv->stopbits = (uint8_t) str_parse_4(value, - "0.5", 0, - "1", 1, - "1.5", 2, - "2", 3, &suc); + priv->stopbits = (uint8_t) cfg_enum4_parse(value, + "0.5", 0, + "1", 1, + "1.5", 2, + "2", 3, &suc); } else if (streq(key, "direction")) { - priv->direction = (uint8_t) str_parse_3(value, - "RX", UUSART_DIRECTION_RX, - "TX", UUSART_DIRECTION_TX, - "RXTX", UUSART_DIRECTION_RXTX, &suc); + priv->direction = (uint8_t) cfg_enum3_parse(value, + "RX", UUSART_DIRECTION_RX, + "TX", UUSART_DIRECTION_TX, + "RXTX", UUSART_DIRECTION_RXTX, &suc); } else if (streq(key, "hw-flow-control")) { - priv->hw_flow_control = (uint8_t) str_parse_4(value, - "NONE", 0, - "RTS", 1, - "CTS", 2, - "FULL", 3, &suc); + priv->hw_flow_control = (uint8_t) cfg_enum4_parse(value, + "NONE", 0, + "RTS", 1, + "CTS", 2, + "FULL", 3, &suc); } else if (streq(key, "word-width")) { - priv->width = (uint8_t ) avr_atoi(value); + priv->width = cfg_u8_parse(value, &suc); } else if (streq(key, "first-bit")) { - priv->lsb_first = (bool)str_parse_2(value, "MSB", 0, "LSB", 1, &suc); + priv->lsb_first = (bool) cfg_enum2_parse(value, "MSB", 0, "LSB", 1, &suc); } else if (streq(key, "clock-output")) { - priv->clock_output = str_parse_yn(value, &suc); + priv->clock_output = cfg_bool_parse(value, &suc); } else if (streq(key, "cpol")) { - priv->cpol = (bool) avr_atoi(value); + priv->cpol = cfg_bool_parse(value, &suc); } else if (streq(key, "cpha")) { - priv->cpha = (bool) avr_atoi(value); + priv->cpha = cfg_bool_parse(value, &suc); } else if (streq(key, "de-output")) { - priv->de_output = str_parse_yn(value, &suc); + priv->de_output = cfg_bool_parse(value, &suc); } else if (streq(key, "de-polarity")) { - priv->de_polarity = (bool) avr_atoi(value); + priv->de_polarity = cfg_bool_parse(value, &suc); } else if (streq(key, "de-assert-time")) { - priv->de_assert_time = (uint8_t) avr_atoi(value); + priv->de_assert_time = cfg_u8_parse(value, &suc); } else if (streq(key, "de-clear-time")) { - priv->de_clear_time = (uint8_t) avr_atoi(value); + priv->de_clear_time = cfg_u8_parse(value, &suc); } else { return E_BAD_KEY; @@ -180,38 +180,38 @@ void UUSART_writeIni(Unit *unit, IniWriter *iw) iw_entry(iw, "baud-rate", "%d", (int)priv->baudrate); iw_comment(iw, "Parity type (NONE, ODD, EVEN)"); - iw_entry(iw, "parity", "%s", str_3(priv->parity, - 0, "NONE", - 1, "ODD", - 2, "EVEN")); + iw_entry(iw, "parity", cfg_enum3_encode(priv->parity, + 0, "NONE", + 1, "ODD", + 2, "EVEN")); iw_comment(iw, "Number of stop bits (0.5, 1, 1.5, 2)"); - iw_entry(iw, "stop-bits", "%s", str_4(priv->stopbits, - 0, "0.5", - 1, "1", - 2, "1.5", - 3, "2")); + iw_entry(iw, "stop-bits", cfg_enum4_encode(priv->stopbits, + 0, "0.5", + 1, "1", + 2, "1.5", + 3, "2")); iw_comment(iw, "Bit order (LSB or MSB first)"); - iw_entry(iw, "first-bit", str_2((uint32_t)priv->lsb_first, - 0, "MSB", - 1, "LSB")); + iw_entry(iw, "first-bit", cfg_enum2_encode((uint32_t) priv->lsb_first, + 0, "MSB", + 1, "LSB")); iw_comment(iw, "Word width (7,8,9) - including parity bit if used"); iw_entry(iw, "word-width", "%d", (int)priv->width); iw_comment(iw, "Enabled lines (RX,TX,RXTX)"); - iw_entry(iw, "direction", str_3(priv->direction, - 1, "RX", - 2, "TX", - 3, "RXTX")); + iw_entry(iw, "direction", cfg_enum3_encode(priv->direction, + 1, "RX", + 2, "TX", + 3, "RXTX")); iw_comment(iw, "Hardware flow control (NONE, RTS, CTS, FULL)"); - iw_entry(iw, "hw-flow-control", "%s", str_4(priv->hw_flow_control, - 0, "NONE", - 1, "RTS", - 2, "CTS", - 3, "FULL")); + iw_entry(iw, "hw-flow-control", cfg_enum4_encode(priv->hw_flow_control, + 0, "NONE", + 1, "RTS", + 2, "CTS", + 3, "FULL")); iw_cmt_newline(iw); iw_comment(iw, "Generate serial clock (Y,N)"); diff --git a/utils/avr_atoi.c b/utils/avr_atoi.c deleted file mode 100644 index 48285f1..0000000 --- a/utils/avr_atoi.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2002, Marek Michalkiewicz - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. */ - -#include "avrlibc.h" - -int -avr_atoi(const char *p) -{ - return (int) avr_atol(p); -} diff --git a/utils/avr_atol.c b/utils/avr_atol.c deleted file mode 100644 index fa818b5..0000000 --- a/utils/avr_atol.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2002, Marek Michalkiewicz - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - * Neither the name of the copyright holders nor the names of - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. */ - -#include -#include "avrlibc.h" - -long -avr_atol(const char *p) -{ - return avr_strtol(p, (char **) NULL, 10); -} diff --git a/utils/avr_strtod.c b/utils/avr_strtod.c index 09d78d2..ae5d508 100644 --- a/utils/avr_strtod.c +++ b/utils/avr_strtod.c @@ -37,10 +37,10 @@ #include #include "avrlibc.h" -/* Only GCC 4.2 calls the library function to convert an unsigned long +/* Only GCC 4.2 calls the library function to convert an uint32_t to float. Other GCC-es (including 4.3) use a signed long to float conversion along with a large inline code to correct the result. */ -extern double __floatunsisf (unsigned long); +extern double __floatunsisf (uint32_t); static const float pwr_p10 [6] = { 1e+1, 1e+2, 1e+4, 1e+8, 1e+16, 1e+32 @@ -84,13 +84,13 @@ double avr_strtod (const char * nptr, char ** endptr) { union { - unsigned long u32; - float flt; + uint32_t u32; + float flt; } x; - unsigned char c; - int exp; + char c; + int32_t exp; - unsigned char flag; + uint8_t flag; #define FL_MINUS 0x01 /* number is negative */ #define FL_ANY 0x02 /* any digit was readed */ #define FL_OVFL 0x04 /* overflow was */ @@ -178,7 +178,7 @@ avr_strtod (const char * nptr, char ** endptr) do { if (i < 3200) i = (((i << 2) + i) << 1) + c; /* i = 10*i + c */ - c = *nptr++ - '0'; + c = (char) (*nptr++ - '0'); } while (c <= 9); if (flag & FL_MEXP) i = -i; @@ -189,7 +189,7 @@ avr_strtod (const char * nptr, char ** endptr) if ((flag & FL_ANY) && endptr) *endptr = (char *)nptr - 1; - x.flt = __floatunsisf (x.u32); /* manually */ + x.flt = (float) __floatunsisf (x.u32); /* manually */ if ((flag & FL_MINUS) && (flag & FL_ANY)) x.flt = -x.flt; @@ -204,7 +204,7 @@ avr_strtod (const char * nptr, char ** endptr) for (pwr = 32; pwr; pwr >>= 1) { for (; exp >= pwr; exp -= pwr) { union { - unsigned long u32; + uint32_t u32; float flt; } y; y.u32 = (uint32_t) *((float *)nptr); @@ -213,7 +213,7 @@ avr_strtod (const char * nptr, char ** endptr) nptr -= sizeof(float); } if (!isfinite(x.flt) || x.flt == 0) - errno = ERANGE; + avrlibc_errno = ERANGE; } return x.flt; diff --git a/utils/avr_strtol.c b/utils/avr_strtol.c index 44d6376..0676895 100644 --- a/utils/avr_strtol.c +++ b/utils/avr_strtol.c @@ -32,6 +32,7 @@ #include #include +#include "avrlibc.h" /* * Convert a string to a long integer. @@ -39,14 +40,14 @@ * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ -long -avr_strtol(const char *nptr, char **endptr, register int base) +int32_t +avr_strtol(const char *nptr, char **endptr, register int32_t base) { - register unsigned long acc; - register unsigned char c; - register unsigned long cutoff; - register signed char any; - unsigned char flag = 0; + register uint32_t acc; + register char c; + register uint32_t cutoff; + register int8_t any; + uint8_t flag = 0; #define FL_NEG 0x01 /* number is negative */ #define FL_0X 0x02 /* number has a 0x prefix */ @@ -105,24 +106,24 @@ avr_strtol(const char *nptr, char **endptr, register int base) * Set any if any `digits' consumed; make it negative to indicate * overflow. */ -#if LONG_MIN != -LONG_MAX - 1 +#if INT32_MIN != -INT32_MAX - 1 # error "This implementation of strtol() does not work on this platform." #endif switch (base) { case 10: - cutoff = ((unsigned long)LONG_MAX + 1) / 10; + cutoff = ((uint32_t)INT32_MAX + 1) / 10; break; case 16: - cutoff = ((unsigned long)LONG_MAX + 1) / 16; + cutoff = ((uint32_t)INT32_MAX + 1) / 16; break; case 8: - cutoff = ((unsigned long)LONG_MAX + 1) / 8; + cutoff = ((uint32_t)INT32_MAX + 1) / 8; break; case 2: - cutoff = ((unsigned long)LONG_MAX + 1) / 2; + cutoff = ((uint32_t)INT32_MAX + 1) / 2; break; default: - cutoff = ((unsigned long)LONG_MAX + 1) / base; + cutoff = ((uint32_t)INT32_MAX + 1) / base; } for (acc = 0, any = 0;; c = *nptr++) { @@ -143,7 +144,7 @@ avr_strtol(const char *nptr, char **endptr, register int base) continue; } acc = acc * base + c; - if (acc > (unsigned long)LONG_MAX + 1) + if (acc > (uint32_t)INT32_MAX + 1) any = -1; else any = 1; @@ -155,13 +156,13 @@ avr_strtol(const char *nptr, char **endptr, register int base) *endptr = (char *)nptr - 2; } if (any < 0) { - acc = (flag & FL_NEG) ? LONG_MIN : LONG_MAX; - errno = ERANGE; + acc = (flag & FL_NEG) ? INT32_MIN : INT32_MAX; + avrlibc_errno = ERANGE; } else if (flag & FL_NEG) { acc = -acc; } else if ((signed long)acc < 0) { - acc = LONG_MAX; - errno = ERANGE; + acc = INT32_MAX; + avrlibc_errno = ERANGE; } return (acc); } diff --git a/utils/avr_strtoul.c b/utils/avr_strtoul.c index e632611..a8cf363 100644 --- a/utils/avr_strtoul.c +++ b/utils/avr_strtoul.c @@ -35,18 +35,18 @@ #include "avrlibc.h" /* - * Convert a string to an unsigned long integer. + * Convert a string to an uint32_t integer. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ -unsigned long -avr_strtoul(const char *nptr, char **endptr, register int base) +uint32_t +avr_strtoul(const char *nptr, char **endptr, register int32_t base) { - register unsigned long acc; - register unsigned char c; - register unsigned long cutoff; - register signed char any; + register uint32_t acc; + register char c; + register uint32_t cutoff; + register int8_t any; unsigned char flag = 0; #define FL_NEG 0x01 /* number is negative */ #define FL_0X 0x02 /* number has a 0x prefix */ @@ -102,10 +102,10 @@ avr_strtoul(const char *nptr, char **endptr, register int base) * */ switch (base) { - case 16: cutoff = ULONG_MAX / 16; break; - case 10: cutoff = ULONG_MAX / 10; break; - case 8: cutoff = ULONG_MAX / 8; break; - default: cutoff = ULONG_MAX / base; + case 16: cutoff = UINT32_MAX / 16; break; + case 10: cutoff = UINT32_MAX / 10; break; + case 8: cutoff = UINT32_MAX / 8; break; + default: cutoff = UINT32_MAX / base; } for (acc = 0, any = 0;; c = *nptr++) { @@ -126,7 +126,7 @@ avr_strtoul(const char *nptr, char **endptr, register int base) continue; } acc = acc * base + c; - any = (c > acc) ? -1 : 1; + any = (int8_t) ((c > acc) ? -1 : 1); } if (endptr) { @@ -138,8 +138,8 @@ avr_strtoul(const char *nptr, char **endptr, register int base) if (flag & FL_NEG) acc = -acc; if (any < 0) { - acc = ULONG_MAX; - errno = ERANGE; + acc = UINT32_MAX; + avrlibc_errno = ERANGE; } - return (acc); + return (uint32_t) (acc); } diff --git a/utils/avrlibc.c b/utils/avrlibc.c new file mode 100644 index 0000000..1fa5713 --- /dev/null +++ b/utils/avrlibc.c @@ -0,0 +1,7 @@ +// +// Created by MightyPork on 2018/02/23. +// + +#include + +volatile int32_t avrlibc_errno = 0; diff --git a/utils/avrlibc.h b/utils/avrlibc.h index 683d8b5..bfb666c 100644 --- a/utils/avrlibc.h +++ b/utils/avrlibc.h @@ -8,21 +8,10 @@ #ifndef GEX_AVRLIBC_H_H #define GEX_AVRLIBC_H_H -/** - * atoi() - parse decimal int from ASCII - * - * @param p - string - * @return int, 0 on failure - */ -int avr_atoi(const char *p); +#include +#include -/** - * atol() - parse decimal long int from ASCII - * - * @param p - string - * @return int, 0 on failure - */ -long avr_atol(const char *p); +extern volatile int32_t avrlibc_errno; /** * strtol() - parse integer number form string. @@ -35,25 +24,47 @@ long avr_atol(const char *p); * @param base - base 2, 10, 16.... 0 for auto * @return the number */ -long avr_strtol(const char *nptr, char **endptr, register int base); +int32_t avr_strtol(const char *nptr, char **endptr, register int32_t base); /** - * Parse double from ASCII + * like strtol(), but unsigned (and hence higher max value) * * @param nptr - string to parse * @param endptr - NULL or pointer to string where the end will be stored (first bad char) - * @return the number + * @param base - base 2, 10, 16.... 0 for auto + * @return the number */ -double avr_strtod (const char * nptr, char ** endptr); +uint32_t avr_strtoul(const char *nptr, char **endptr, register int32_t base); /** - * like strtol(), but unsigned (and hence higher max value) + * atol() - parse decimal long int from ASCII + * + * @param p - string + * @return int, 0 on failure + */ +static inline int32_t avr_atol(const char *p) +{ + return avr_strtol(p, (char **) NULL, 10); +} + +/** + * atoi() - parse decimal int from ASCII + * + * @param p - string + * @return int, 0 on failure + */ +static inline int32_t avr_atoi(const char *p) +{ + return avr_atol(p); +} + +/** + * Parse double from ASCII * * @param nptr - string to parse * @param endptr - NULL or pointer to string where the end will be stored (first bad char) - * @param base - base 2, 10, 16.... 0 for auto - * @return the number + * @return the number */ -unsigned long avr_strtoul(const char *nptr, char **endptr, register int base); +double avr_strtod (const char * nptr, char ** endptr); #endif //GEX_AVRLIBC_H_H diff --git a/utils/snprintf.c b/utils/snprintf.c index d9f2ed3..8520114 100644 --- a/utils/snprintf.c +++ b/utils/snprintf.c @@ -190,7 +190,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args { char ch; LLONG value; - LDOUBLE fvalue; + LDOUBLE fvalue = 0; char *strvalue; int min; int max; diff --git a/utils/str_utils.c b/utils/str_utils.c index 7a24869..4b77247 100644 --- a/utils/str_utils.c +++ b/utils/str_utils.c @@ -5,110 +5,3 @@ #include "str_utils.h" #include "platform.h" #include "avrlibc.h" - -bool str_parse_yn(const char *str, bool *suc) -{ - // TODO implement strcasecmp without the locale crap from newlib and use it here - if (streq(str, "Y")) return true; - if (streq(str, "N")) return false; - - if (streq(str, "1")) return true; - if (streq(str, "0")) return false; - - if (streq(str, "YES")) return true; - if (streq(str, "NO")) return false; - - *suc = false; - return false; -} - -uint8_t str_parse_01(const char *str, const char *a, const char *b, bool *suc) -{ - if (streq(str, a)) return 0; - if (streq(str, b)) return 1; - - *suc = false; - return 0; -} - -uint8_t str_parse_012(const char *str, const char *a, const char *b, const char *c, bool *suc) -{ - if (streq(str, a)) return 0; - if (streq(str, b)) return 1; - if (streq(str, c)) return 2; - - *suc = false; - return 0; -} - -/** Convert number to one of 2 options */ -const char *str_2(uint32_t n, - uint32_t na, const char *a, - uint32_t nb, const char *b) -{ - if (n == nb) return b; - return a; -} - -/** Convert number to one of 3 options */ -const char *str_3(uint32_t n, - uint32_t na, const char *a, - uint32_t nb, const char *b, - uint32_t nc, const char *c) -{ - if (n == nb) return b; - if (n == nc) return c; - return a; -} - -/** Convert number to one of 4 options */ -const char *str_4(uint32_t n, - uint32_t na, const char *a, - uint32_t nb, const char *b, - uint32_t nc, const char *c, - uint32_t nd, const char *d) -{ - if (n == nb) return b; - if (n == nc) return c; - if (n == nd) return d; - return a; -} - -uint32_t str_parse_2(const char *value, - const char *a, uint32_t na, - const char *b, uint32_t nb, - bool *suc) -{ - if (streq(value, a)) return na; - if (streq(value, b)) return nb; - *suc = false; - return na; -} - -uint32_t str_parse_3(const char *value, - const char *a, uint32_t na, - const char *b, uint32_t nb, - const char *c, uint32_t nc, - bool *suc) -{ - if (streq(value, a)) return na; - if (streq(value, b)) return nb; - if (streq(value, c)) return nc; - *suc = false; - return na; -} - -uint32_t str_parse_4(const char *value, - const char *a, uint32_t na, - const char *b, uint32_t nb, - const char *c, uint32_t nc, - const char *d, uint32_t nd, - bool *suc) -{ - if (streq(value, a)) return na; - if (streq(value, b)) return nb; - if (streq(value, c)) return nc; - if (streq(value, d)) return nd; - *suc = false; - return na; -} diff --git a/utils/str_utils.h b/utils/str_utils.h index b25e6b6..7420812 100644 --- a/utils/str_utils.h +++ b/utils/str_utils.h @@ -103,55 +103,4 @@ last_char(const char *str) return str[strlen(str) - 1]; } -/** Parse Y/N to bool */ -bool str_parse_yn(const char *str, bool *suc); - -/** Compare string with two options */ -uint8_t str_parse_01(const char *str, const char *a, const char *b, bool *suc); - -/** Compare string with three options */ -uint8_t str_parse_012(const char *str, const char *a, const char *b, const char *c, bool *suc); - -/** Convert number to one of 4 options */ -const char *str_2(uint32_t n, - uint32_t na, const char *a, - uint32_t nb, const char *b); - -/** Convert number to one of 4 options */ -const char *str_3(uint32_t n, - uint32_t na, const char *a, - uint32_t nb, const char *b, - uint32_t nc, const char *c); - -/** Convert number to one of 4 options */ -const char *str_4(uint32_t n, - uint32_t na, const char *a, - uint32_t nb, const char *b, - uint32_t nc, const char *c, - uint32_t nd, const char *d); - -/** Convert string to one of two numeric options */ -uint32_t str_parse_2(const char *tpl, - const char *a, uint32_t na, - const char *b, uint32_t nb, - bool *suc); - -/** Convert string to one of three numeric options */ -uint32_t str_parse_3(const char *tpl, - const char *a, uint32_t na, - const char *b, uint32_t nb, - const char *c, uint32_t nc, - bool *suc); - -/** Convert string to one of four numeric options */ -uint32_t str_parse_4(const char *tpl, - const char *a, uint32_t na, - const char *b, uint32_t nb, - const char *c, uint32_t nc, - const char *d, uint32_t nd, - bool *suc); - -/** Convert bool to a Y or N constant string */ -#define str_yn(cond) ((cond) ? ("Y") : ("N")) - #endif