massive utils refactoring, renames, avr libc utils cleaning

pin-io-improv
Ondřej Hruška 7 years ago
parent 8dcdaf9236
commit a60b736834
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 328
      USB/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c.rej
  2. 60
      USB/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc.h.rej
  3. 35
      USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c.rej
  4. 37
      USB/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c.rej
  5. 4
      USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h
  6. 62
      USB/STM32_USB_Device_Library/Core/Inc/usbd_def.h.rej
  7. 2
      cortex_handlers.c
  8. 36
      framework/resources.c
  9. 10
      framework/resources.h
  10. 2
      framework/settings.c
  11. 5
      framework/system_settings.c
  12. 1
      framework/unit_base.h
  13. 2
      gex.mk
  14. 299
      platform/cfg_utils.c
  15. 153
      platform/cfg_utils.h
  16. 273
      platform/hw_utils.c
  17. 91
      platform/hw_utils.h
  18. 11
      platform/lock_jumper.c
  19. 8
      platform/status_led.c
  20. 2
      tasks/task_main.c
  21. 2
      units/1wire/_ow_init.c
  22. 4
      units/1wire/_ow_settings.c
  23. 2
      units/adc/_adc_init.c
  24. 12
      units/adc/_adc_settings.c
  25. 28
      units/digital_in/_din_settings.c
  26. 14
      units/digital_out/_dout_settings.c
  27. 14
      units/fcap/_fcap_settings.c
  28. 12
      units/i2c/_i2c_settings.c
  29. 2
      units/neopixel/_npx_init.c
  30. 4
      units/neopixel/_npx_settings.c
  31. 6
      units/sipo/_sipo_init.c
  32. 18
      units/sipo/_sipo_settings.c
  33. 24
      units/spi/_spi_settings.c
  34. 42
      units/usart/_usart_settings.c
  35. 35
      utils/avr_atoi.c
  36. 36
      utils/avr_atol.c
  37. 20
      utils/avr_strtod.c
  38. 37
      utils/avr_strtol.c
  39. 30
      utils/avr_strtoul.c
  40. 7
      utils/avrlibc.c
  41. 51
      utils/avrlibc.h
  42. 2
      utils/snprintf.c
  43. 107
      utils/str_utils.c
  44. 51
      utils/str_utils.h

@ -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 )
{

@ -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

@ -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

@ -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;
}

@ -265,8 +265,8 @@ typedef struct _USBD_HandleTypeDef
#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ #define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \
(((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) #define LOBYTE(x) ((uint8_t)((x) & 0x00FF))
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) #define HIBYTE(x) ((uint8_t)(((x) & 0xFF00) >>8))
#ifndef MIN #ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b))

@ -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__ )

@ -34,7 +34,7 @@ void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName)
// && (__CORTEX_M >= 3) // && (__CORTEX_M >= 3)
#if VERBOSE_HARDFAULT #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 /* 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 away as the variables never actually get used. If the debugger won't show the

@ -6,6 +6,7 @@
#include "unit.h" #include "unit.h"
#include "resources.h" #include "resources.h"
#include "hw_utils.h" #include "hw_utils.h"
#include "cfg_utils.h"
#include "unit_registry.h" #include "unit_registry.h"
static bool rsc_initialized = false; static bool rsc_initialized = false;
@ -50,6 +51,27 @@ const char * rsc_get_name(Resource rsc)
return rsc_names[rsc - R_EXTI15 - 1]; 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) 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; return E_SUCCESS;
} }
error_t rsc_claim_gpios(Unit *unit, char port_name, uint16_t pins) error_t rsc_claim_gpios(Unit *unit, char port_name, uint16_t pins)
{ {
bool suc = true;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
if (pins & (1 << i)) { if (pins & (1 << i)) {
Resource rsc = hw_pin2resource(port_name, (uint8_t) i, &suc); TRY(rsc_claim_pin(unit, port_name, (uint8_t)i));
if (!suc) return E_BAD_CONFIG;
TRY(rsc_claim(unit, rsc));
} }
} }
return E_SUCCESS; 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) error_t rsc_claim_pin(Unit *unit, char port_name, uint8_t pin)
{ {
bool suc = true; 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; if (!suc) return E_BAD_CONFIG;
TRY(rsc_claim(unit, rsc)); TRY(rsc_claim(unit, rsc));
return E_SUCCESS; return E_SUCCESS;
@ -241,7 +257,7 @@ void rsc_print_all_available(IniWriter *iw)
if (i%16 == 0) { if (i%16 == 0) {
// here we print the previous port // here we print the previous port
if (bitmap != 0) { if (bitmap != 0) {
iw_string(iw, pinmask2str(bitmap, iwbuffer)); iw_string(iw, cfg_pinmask_encode(bitmap, iwbuffer, 0));
bitmap = 0; bitmap = 0;
} }
@ -256,7 +272,7 @@ void rsc_print_all_available(IniWriter *iw)
} }
// the last one // the last one
if (bitmap != 0) { if (bitmap != 0) {
iw_string(iw, pinmask2str(bitmap, iwbuffer)); iw_string(iw, cfg_pinmask_encode(bitmap, iwbuffer, 0));
} }
iw_newline(iw); iw_newline(iw);
iw_newline(iw); iw_newline(iw);

@ -94,6 +94,16 @@ void rsc_free(Unit *unit, Resource rsc);
*/ */
void rsc_free_range(Unit *unit, Resource rsc0, Resource rsc1); 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. * Get name of a resource by the Resource enum.
* Uses a static buffer, DO NOT store the returned pointer. * Uses a static buffer, DO NOT store the returned pointer.

@ -2,7 +2,6 @@
// Created by MightyPork on 2017/11/26. // Created by MightyPork on 2017/11/26.
// //
#include "utils/avrlibc.h"
#include "platform.h" #include "platform.h"
#include "utils/hexdump.h" #include "utils/hexdump.h"
#include "settings.h" #include "settings.h"
@ -10,6 +9,7 @@
#include "system_settings.h" #include "system_settings.h"
#include "utils/str_utils.h" #include "utils/str_utils.h"
#include "unit_base.h" #include "unit_base.h"
#include "utils/avrlibc.h"
// pre-declarations // pre-declarations
static void savebuf_flush(PayloadBuilder *pb, bool final); static void savebuf_flush(PayloadBuilder *pb, bool final);

@ -6,6 +6,7 @@
#include "system_settings.h" #include "system_settings.h"
#include "utils/str_utils.h" #include "utils/str_utils.h"
#include "platform/lock_jumper.h" #include "platform/lock_jumper.h"
#include "cfg_utils.h"
struct system_settings SystemSettings; struct system_settings SystemSettings;
@ -77,12 +78,12 @@ bool systemsettings_load_ini(const char *restrict key, const char *restrict valu
{ {
bool suc = true; bool suc = true;
if (streq(key, "expose_vcom")) { 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 (suc) SystemSettings.visible_vcom = yn;
} }
if (streq(key, "ini_comments")) { 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; if (suc) SystemSettings.ini_comments = yn;
} }

@ -8,6 +8,7 @@
#include "platform.h" #include "platform.h"
#include "unit.h" #include "unit.h"
#include "hw_utils.h" #include "hw_utils.h"
#include "cfg_utils.h"
#include "resources.h" #include "resources.h"
#include "utils/str_utils.h" #include "utils/str_utils.h"
#include "utils/malloc_safe.h" #include "utils/malloc_safe.h"

@ -95,7 +95,7 @@ GEX_CDEFS = $(GEX_CDEFS_BASE) \
-DUSE_STACK_MONITOR=1 \ -DUSE_STACK_MONITOR=1 \
-DUSE_DEBUG_UART=1 \ -DUSE_DEBUG_UART=1 \
-DDEBUG_MALLOC=0 \ -DDEBUG_MALLOC=0 \
-DDEBUG_RSC=0 -DDEBUG_RSC=1
endif endif

@ -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<<i;
}
inrange = false;
rangestart = 0;
acu = 0;
}
else if (c == '-' || c == ':') {
rangestart = acu;
inrange = true;
acu=0;
} else {
*suc = false;
}
} while (c != 0);
return bits;
}
/** Convert a pin bitmask to the ASCII format understood by str_parse_pinmask() */
char *cfg_pinmask_encode(uint32_t pins, char *buffer, bool ascending)
{
char *b = buffer;
uint32_t start = 0;
bool on = false;
bool first = true;
bool bit;
// shortcut if none are set
if (pins == 0) {
buffer[0] = 0;
return buffer;
}
if (ascending) {
for (int32_t i = 0; i <= 32; i++) {
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;
}
}
}
} 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;
}

@ -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

@ -6,7 +6,6 @@
#include "utils/avrlibc.h" #include "utils/avrlibc.h"
#include "hw_utils.h" #include "hw_utils.h"
/** Convert pin number to LL bitfield */ /** Convert pin number to LL bitfield */
uint32_t hw_pin2ll(uint8_t pin_number, bool *suc) 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]; return GPIO_PERIPHS[num];
} }
/** Convert a pin to resource handle */ /** Convert a pin resource to it's LL lib values */
Resource hw_pin2resource(char port_name, uint8_t pin_number, bool *suc) bool hw_pinrsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin)
{
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)
{ {
*targetName = (uint8_t) value[0]; uint32_t index = rsc - R_PA0;
if (!(*targetName >= 'A' && *targetName < 'A' + PORTS_COUNT)) return false; 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; 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<<i;
}
inrange = false;
rangestart = 0;
acu = 0;
}
else if (c == '-' || c == ':') {
rangestart = acu;
inrange = true;
acu=0;
} else {
*suc = false;
}
} while (c != 0);
return bits;
}
/** Convert a pin bitmask to the ASCII format understood by str_parse_pinmask() */
char * pinmask2str(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 = 31; i >= -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 push_options
#pragma GCC optimize ("O2") #pragma GCC optimize ("O2")
/** spread a packed pinfield using a mask */ /** spread a packed pinfield using a mask */
@ -285,25 +92,13 @@ uint32_t pinmask_pack_32(uint32_t spread, uint32_t mask)
return result; 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<<i)) {
if (i == index) return (uint8_t) cnt;
cnt++;
}
}
return 0;
}
#pragma GCC pop_options #pragma GCC pop_options
/** Configure unit pins as analog (part of unit teardown) */ /** Configure unit pins as analog (part of unit teardown) */
void hw_deinit_unit_pins(Unit *unit) void hw_deinit_unit_pins(Unit *unit)
{ {
for (uint32_t rsc = R_PA0; rsc <= R_PF15; rsc++) { for (uint32_t rsc = R_PA0; rsc <= R_PF15; rsc++) {
if (RSC_IS_HELD(unit->resources, rsc)) { if (RSC_IS_HELD(unit->resources, (Resource)rsc)) {
rsc_dbg("Freeing pin %s", rsc_get_name((Resource)rsc)); rsc_dbg("Freeing pin %s", rsc_get_name((Resource)rsc));
GPIO_TypeDef *port = GPIO_PERIPHS[(rsc-R_PA0) / 16]; GPIO_TypeDef *port = GPIO_PERIPHS[(rsc-R_PA0) / 16];
uint32_t ll_pin = LL_GPIO_PINS[(rsc-R_PA0)%16]; uint32_t ll_pin = LL_GPIO_PINS[(rsc-R_PA0)%16];
@ -360,7 +155,7 @@ error_t hw_configure_sparse_pins(char port_name, uint16_t mask, GPIO_TypeDef **p
} }
/** Solve a timer/counter's count and prescaller value */ /** Solve a timer/counter's count and prescaller value */
bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, bool hw_solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit,
uint16_t *presc, uint32_t *count, float *real_freq) uint16_t *presc, uint32_t *count, float *real_freq)
{ {
if (required_freq == 0) return false; 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; 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) void hw_periph_clock_enable(void *periph)
{ {
// GPIOs are enabled by default on start-up // GPIOs are enabled by default on start-up

@ -21,16 +21,6 @@
*/ */
uint32_t hw_pin2ll(uint8_t pin_number, bool *suc); 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 * 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); 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 * 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 * @param[out] llpin - output LL pin mask
* @return success * @return success
*/ */
bool pinRsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin); bool hw_pinrsc2ll(Resource rsc, GPIO_TypeDef **port, uint32_t *llpin) __attribute__((warn_unused_result));
/**
* 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);
/** /**
* Spread packed port pins using a mask * 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); 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. * Set all GPIO resources held by unit to analog.
* This is a part of unit teardown. * 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 * @param[out] real_freq - field for storing the computed real frequency
* @return true on success * @return true on success
*/ */
bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, bool hw_solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit,
uint16_t *presc, uint32_t *count, float *real_freq); uint16_t *presc, uint32_t *count, float *real_freq) __attribute__((warn_unused_result));
#define hw_wait_while(call, timeout) \ #define hw_wait_while(call, timeout) \
do { \ do { \

@ -26,16 +26,11 @@ void LockJumper_Init(void)
{ {
bool suc = true; bool suc = true;
// Resolve and claim resource Resource pinrsc = rsc_portpin2rsc(LOCK_JUMPER_PORT, LOCK_JUMPER_PIN, &suc);
Resource rsc = hw_pin2resource(LOCK_JUMPER_PORT, LOCK_JUMPER_PIN, &suc);
assert_param(suc); assert_param(suc);
assert_param(E_SUCCESS == rsc_claim(&UNIT_SYSTEM, rsc)); assert_param(E_SUCCESS == rsc_claim(&UNIT_SYSTEM, pinrsc));
assert_param(hw_pinrsc2ll(pinrsc, &lock_periph, &lock_llpin));
// Resolve pin
lock_periph = hw_port2periph(LOCK_JUMPER_PORT, &suc);
lock_llpin = hw_pin2ll(LOCK_JUMPER_PIN, &suc);
assert_param(suc);
// Configure for input // Configure for input
LL_GPIO_SetPinMode(lock_periph, lock_llpin, LL_GPIO_MODE_INPUT); LL_GPIO_SetPinMode(lock_periph, lock_llpin, LL_GPIO_MODE_INPUT);

@ -50,13 +50,7 @@ static inline void led_off(void)
/** Set up the LED */ /** Set up the LED */
void Indicator_Init(void) void Indicator_Init(void)
{ {
bool suc = true; assert_param(E_SUCCESS == rsc_claim_pin(&UNIT_SYSTEM, STATUS_LED_PORT, STATUS_LED_PIN));
// 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));
} }
/** Set indicator ON */ /** Set indicator ON */

@ -12,8 +12,6 @@
#include "usbd_msc.h" #include "usbd_msc.h"
#include "task_main.h" #include "task_main.h"
extern void plat_init(void);
/* TaskUsbEvent function */ /* TaskUsbEvent function */
void TaskMain(void const * argument) void TaskMain(void const * argument)
{ {

@ -40,7 +40,7 @@ error_t OW_init(Unit *unit)
// --- Parse config --- // --- Parse config ---
priv->ll_pin = hw_pin2ll(priv->pin_number, &suc); priv->ll_pin = hw_pin2ll(priv->pin_number, &suc);
priv->port = hw_port2periph(priv->port_name, &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; if (!suc) return E_BAD_CONFIG;
// --- Claim resources --- // --- Claim resources ---

@ -44,10 +44,10 @@ error_t OW_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "pin")) { 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")) { else if (streq(key, "parasitic")) {
priv->parasitic = str_parse_yn(value, &suc); priv->parasitic = cfg_bool_parse(value, &suc);
} }
else { else {
return E_BAD_KEY; return E_BAD_KEY;

@ -35,7 +35,7 @@ error_t UADC_SetSampleRate(Unit *unit, uint32_t hertz)
uint16_t presc; uint16_t presc;
uint32_t count; 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."); dbg("Failed to resolve timer params.");
return E_BAD_VALUE; return E_BAD_VALUE;
} }

@ -48,20 +48,20 @@ error_t UADC_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "channels")) { 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")) { 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; if (priv->cfg.sample_time > 7) return E_BAD_VALUE;
} }
else if (streq(key, "frequency")) { 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")) { 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")) { 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; if (priv->cfg.averaging_factor > 1000) return E_BAD_VALUE;
} }
else { else {
@ -80,7 +80,7 @@ void UADC_writeIni(Unit *unit, IniWriter *iw)
iw_comment(iw, "Enabled channels, comma separated"); 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, " 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_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_cmt_newline(iw);
iw_comment(iw, "Sampling time (0-7)"); iw_comment(iw, "Sampling time (0-7)");

@ -57,28 +57,28 @@ error_t DIn_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "port")) { 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")) { else if (streq(key, "pins")) {
priv->pins = parse_pinmask(value, &suc); priv->pins = cfg_pinmask_parse(value, &suc);
} }
else if (streq(key, "pull-up")) { 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")) { 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")) { 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")) { 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")) { 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")) { else if (streq(key, "hold-off")) {
priv->trig_holdoff = (uint16_t) avr_atoi(value); priv->trig_holdoff = cfg_u16_parse(value, &suc);
} }
else { else {
return E_BAD_KEY; return E_BAD_KEY;
@ -97,21 +97,21 @@ void DIn_writeIni(Unit *unit, IniWriter *iw)
iw_entry(iw, "port", "%c", priv->port_name); iw_entry(iw, "port", "%c", priv->port_name);
iw_comment(iw, "Pins (comma separated, supports ranges)"); 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_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_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_cmt_newline(iw);
iw_comment(iw, "Trigger pins activated by rising/falling edge"); 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-rise", cfg_pinmask_encode(priv->trig_rise, unit_tmp512, 0));
iw_entry(iw, "trig-fall", "%s", pinmask2str(priv->trig_fall, unit_tmp512)); iw_entry(iw, "trig-fall", cfg_pinmask_encode(priv->trig_fall, unit_tmp512, 0));
iw_comment(iw, "Trigger pins auto-armed by default"); 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_comment(iw, "Triggers hold-off time (ms)");
iw_entry(iw, "hold-off", "%d", (int)priv->trig_holdoff); iw_entry(iw, "hold-off", "%d", (int)priv->trig_holdoff);

@ -44,16 +44,16 @@ error_t DOut_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "port")) { 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")) { 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")) { 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")) { else if (streq(key, "open-drain")) {
priv->open_drain = (uint16_t) parse_pinmask(value, &suc); priv->open_drain = cfg_pinmask_parse(value, &suc);
} }
else { else {
return E_BAD_KEY; return E_BAD_KEY;
@ -72,11 +72,11 @@ void DOut_writeIni(Unit *unit, IniWriter *iw)
iw_entry(iw, "port", "%c", priv->port_name); iw_entry(iw, "port", "%c", priv->port_name);
iw_comment(iw, "Pins (comma separated, supports ranges)"); 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_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_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));
} }

@ -55,22 +55,22 @@ error_t UFCAP_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "pin")) { 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")) { 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")) { 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")) { 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")) { 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")) { else if (streq(key, "initial-mode")) {
priv->conf.startmode = (enum fcap_opmode) str_parse_4(value, priv->conf.startmode = (enum fcap_opmode) cfg_enum4_parse(value,
"N", OPMODE_IDLE, "N", OPMODE_IDLE,
"I", OPMODE_INDIRECT_CONT, "I", OPMODE_INDIRECT_CONT,
"D", OPMODE_DIRECT_CONT, "D", OPMODE_DIRECT_CONT,
@ -110,7 +110,7 @@ void UFCAP_writeIni(Unit *unit, IniWriter *iw)
iw_cmt_newline(iw); iw_cmt_newline(iw);
iw_comment(iw, "Mode on startup: N-none, I-indirect, D-direct, F-free count"); 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, iw_entry(iw, "initial-mode", cfg_enum4_encode(priv->conf.startmode,
OPMODE_IDLE, "N", OPMODE_IDLE, "N",
OPMODE_INDIRECT_CONT, "I", OPMODE_INDIRECT_CONT, "I",
OPMODE_DIRECT_CONT, "D", OPMODE_DIRECT_CONT, "D",

@ -49,19 +49,19 @@ error_t UI2C_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "device")) { 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")) { 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")) { 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")) { 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")) { else if (streq(key, "speed")) {
priv->speed = (uint8_t) avr_atoi(value); priv->speed = cfg_u8_parse(value, &suc);
} }
else { else {
return E_BAD_KEY; return E_BAD_KEY;
@ -99,7 +99,7 @@ void UI2C_writeIni(Unit *unit, IniWriter *iw)
iw_entry(iw, "speed", "%d", (int)priv->speed); iw_entry(iw, "speed", "%d", (int)priv->speed);
iw_comment(iw, "Analog noise filter enable (Y,N)"); 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_comment(iw, "Digital noise filter bandwidth (0-15)");
iw_entry(iw, "digital-filter", "%d", (int)priv->dnf); iw_entry(iw, "digital-filter", "%d", (int)priv->dnf);

@ -32,7 +32,7 @@ error_t Npx_init(Unit *unit)
// --- Parse config --- // --- Parse config ---
priv->ll_pin = hw_pin2ll(priv->pin_number, &suc); priv->ll_pin = hw_pin2ll(priv->pin_number, &suc);
priv->port = hw_port2periph(priv->port_name, &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; if (!suc) return E_BAD_CONFIG;
// --- Claim resources --- // --- Claim resources ---

@ -37,10 +37,10 @@ error_t Npx_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "pin")) { 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")) { else if (streq(key, "pixels")) {
priv->pixels = (uint16_t) avr_atoi(value); priv->pixels = cfg_u16_parse(value, &suc);
} }
else { else {
return E_BAD_KEY; return E_BAD_KEY;

@ -41,19 +41,19 @@ error_t USIPO_init(Unit *unit)
// --- Parse config --- // --- Parse config ---
priv->store_ll = hw_pin2ll(priv->store_pnum, &suc); priv->store_ll = hw_pin2ll(priv->store_pnum, &suc);
priv->store_port = hw_port2periph(priv->store_pname, &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; if (!suc) return E_BAD_CONFIG;
TRY(rsc_claim(unit, store_rsc)); TRY(rsc_claim(unit, store_rsc));
priv->shift_ll = hw_pin2ll(priv->shift_pnum, &suc); priv->shift_ll = hw_pin2ll(priv->shift_pnum, &suc);
priv->shift_port = hw_port2periph(priv->shift_pname, &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; if (!suc) return E_BAD_CONFIG;
TRY(rsc_claim(unit, shift_rsc)); TRY(rsc_claim(unit, shift_rsc));
priv->clear_ll = hw_pin2ll(priv->clear_pnum, &suc); priv->clear_ll = hw_pin2ll(priv->clear_pnum, &suc);
priv->clear_port = hw_port2periph(priv->clear_pname, &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; if (!suc) return E_BAD_CONFIG;
TRY(rsc_claim(unit, clear_rsc)); TRY(rsc_claim(unit, clear_rsc));

@ -64,30 +64,30 @@ error_t USIPO_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "store-pin")) { 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")) { 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")) { 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")) { 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")) { 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")) { 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")) { 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")) { else if (streq(key, "data-pins")) {
priv->data_pins = (uint16_t) parse_pinmask(value, &suc); priv->data_pins = cfg_pinmask_parse(value, &suc);
} }
else { else {
@ -117,6 +117,6 @@ void USIPO_writeIni(Unit *unit, IniWriter *iw)
iw_comment(iw, "Data port and pins"); iw_comment(iw, "Data port and pins");
iw_entry(iw, "data-port", "%c", priv->data_pname); 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));
} }

@ -58,31 +58,31 @@ error_t USPI_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "device")) { 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")) { else if (streq(key, "remap")) {
priv->remap = (uint8_t) avr_atoi(value); priv->remap = cfg_u8_parse(value, &suc);
} }
else if (streq(key, "prescaller")) { else if (streq(key, "prescaller")) {
priv->prescaller = (uint16_t ) avr_atoi(value); priv->prescaller = cfg_u16_parse(value, &suc);
} }
else if (streq(key, "cpol")) { else if (streq(key, "cpol")) {
priv->cpol = (bool) avr_atoi(value); priv->cpol = cfg_bool_parse(value, &suc);
} }
else if (streq(key, "cpha")) { else if (streq(key, "cpha")) {
priv->cpha = (bool) avr_atoi(value); priv->cpha = cfg_bool_parse(value, &suc);
} }
else if (streq(key, "tx-only")) { 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")) { 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")) { 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")) { else if (streq(key, "pins")) {
priv->ssn_pins = parse_pinmask(value, &suc); priv->ssn_pins = cfg_pinmask_parse(value, &suc);
} }
else { else {
return E_BAD_KEY; 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_entry(iw, "tx-only", str_yn(priv->tx_only));
iw_comment(iw, "Bit order (LSB or MSB first)"); iw_comment(iw, "Bit order (LSB or MSB first)");
iw_entry(iw, "first-bit", str_2((uint32_t)priv->lsb_first, iw_entry(iw, "first-bit", cfg_enum2_encode((uint32_t) priv->lsb_first, 0, "MSB", 1, "LSB"));
0, "MSB",
1, "LSB"));
iw_cmt_newline(iw); iw_cmt_newline(iw);
iw_comment(iw, "SS port name"); iw_comment(iw, "SS port name");
iw_entry(iw, "port", "%c", priv->ssn_port_name); iw_entry(iw, "port", "%c", priv->ssn_port_name);
iw_comment(iw, "SS pins (comma separated, supports ranges)"); 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));
} }

@ -81,66 +81,66 @@ error_t UUSART_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data; struct priv *priv = unit->data;
if (streq(key, "device")) { 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")) { 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")) { 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")) { else if (streq(key, "parity")) {
priv->parity = (uint8_t) str_parse_3(value, priv->parity = (uint8_t) cfg_enum3_parse(value,
"NONE", 0, "NONE", 0,
"ODD", 1, "ODD", 1,
"EVEN", 2, &suc); "EVEN", 2, &suc);
} }
else if (streq(key, "stop-bits")) { else if (streq(key, "stop-bits")) {
priv->stopbits = (uint8_t) str_parse_4(value, priv->stopbits = (uint8_t) cfg_enum4_parse(value,
"0.5", 0, "0.5", 0,
"1", 1, "1", 1,
"1.5", 2, "1.5", 2,
"2", 3, &suc); "2", 3, &suc);
} }
else if (streq(key, "direction")) { else if (streq(key, "direction")) {
priv->direction = (uint8_t) str_parse_3(value, priv->direction = (uint8_t) cfg_enum3_parse(value,
"RX", UUSART_DIRECTION_RX, "RX", UUSART_DIRECTION_RX,
"TX", UUSART_DIRECTION_TX, "TX", UUSART_DIRECTION_TX,
"RXTX", UUSART_DIRECTION_RXTX, &suc); "RXTX", UUSART_DIRECTION_RXTX, &suc);
} }
else if (streq(key, "hw-flow-control")) { else if (streq(key, "hw-flow-control")) {
priv->hw_flow_control = (uint8_t) str_parse_4(value, priv->hw_flow_control = (uint8_t) cfg_enum4_parse(value,
"NONE", 0, "NONE", 0,
"RTS", 1, "RTS", 1,
"CTS", 2, "CTS", 2,
"FULL", 3, &suc); "FULL", 3, &suc);
} }
else if (streq(key, "word-width")) { 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")) { 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")) { 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")) { else if (streq(key, "cpol")) {
priv->cpol = (bool) avr_atoi(value); priv->cpol = cfg_bool_parse(value, &suc);
} }
else if (streq(key, "cpha")) { else if (streq(key, "cpha")) {
priv->cpha = (bool) avr_atoi(value); priv->cpha = cfg_bool_parse(value, &suc);
} }
else if (streq(key, "de-output")) { 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")) { 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")) { 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")) { 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 { else {
return E_BAD_KEY; return E_BAD_KEY;
@ -180,20 +180,20 @@ void UUSART_writeIni(Unit *unit, IniWriter *iw)
iw_entry(iw, "baud-rate", "%d", (int)priv->baudrate); iw_entry(iw, "baud-rate", "%d", (int)priv->baudrate);
iw_comment(iw, "Parity type (NONE, ODD, EVEN)"); iw_comment(iw, "Parity type (NONE, ODD, EVEN)");
iw_entry(iw, "parity", "%s", str_3(priv->parity, iw_entry(iw, "parity", cfg_enum3_encode(priv->parity,
0, "NONE", 0, "NONE",
1, "ODD", 1, "ODD",
2, "EVEN")); 2, "EVEN"));
iw_comment(iw, "Number of stop bits (0.5, 1, 1.5, 2)"); iw_comment(iw, "Number of stop bits (0.5, 1, 1.5, 2)");
iw_entry(iw, "stop-bits", "%s", str_4(priv->stopbits, iw_entry(iw, "stop-bits", cfg_enum4_encode(priv->stopbits,
0, "0.5", 0, "0.5",
1, "1", 1, "1",
2, "1.5", 2, "1.5",
3, "2")); 3, "2"));
iw_comment(iw, "Bit order (LSB or MSB first)"); iw_comment(iw, "Bit order (LSB or MSB first)");
iw_entry(iw, "first-bit", str_2((uint32_t)priv->lsb_first, iw_entry(iw, "first-bit", cfg_enum2_encode((uint32_t) priv->lsb_first,
0, "MSB", 0, "MSB",
1, "LSB")); 1, "LSB"));
@ -201,13 +201,13 @@ void UUSART_writeIni(Unit *unit, IniWriter *iw)
iw_entry(iw, "word-width", "%d", (int)priv->width); iw_entry(iw, "word-width", "%d", (int)priv->width);
iw_comment(iw, "Enabled lines (RX,TX,RXTX)"); iw_comment(iw, "Enabled lines (RX,TX,RXTX)");
iw_entry(iw, "direction", str_3(priv->direction, iw_entry(iw, "direction", cfg_enum3_encode(priv->direction,
1, "RX", 1, "RX",
2, "TX", 2, "TX",
3, "RXTX")); 3, "RXTX"));
iw_comment(iw, "Hardware flow control (NONE, RTS, CTS, FULL)"); iw_comment(iw, "Hardware flow control (NONE, RTS, CTS, FULL)");
iw_entry(iw, "hw-flow-control", "%s", str_4(priv->hw_flow_control, iw_entry(iw, "hw-flow-control", cfg_enum4_encode(priv->hw_flow_control,
0, "NONE", 0, "NONE",
1, "RTS", 1, "RTS",
2, "CTS", 2, "CTS",

@ -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);
}

@ -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 <stdlib.h>
#include "avrlibc.h"
long
avr_atol(const char *p)
{
return avr_strtol(p, (char **) NULL, 10);
}

@ -37,10 +37,10 @@
#include <stdint.h> #include <stdint.h>
#include "avrlibc.h" #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 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. */ 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] = { static const float pwr_p10 [6] = {
1e+1, 1e+2, 1e+4, 1e+8, 1e+16, 1e+32 1e+1, 1e+2, 1e+4, 1e+8, 1e+16, 1e+32
@ -84,13 +84,13 @@ double
avr_strtod (const char * nptr, char ** endptr) avr_strtod (const char * nptr, char ** endptr)
{ {
union { union {
unsigned long u32; uint32_t u32;
float flt; float flt;
} x; } x;
unsigned char c; char c;
int exp; int32_t exp;
unsigned char flag; uint8_t flag;
#define FL_MINUS 0x01 /* number is negative */ #define FL_MINUS 0x01 /* number is negative */
#define FL_ANY 0x02 /* any digit was readed */ #define FL_ANY 0x02 /* any digit was readed */
#define FL_OVFL 0x04 /* overflow was */ #define FL_OVFL 0x04 /* overflow was */
@ -178,7 +178,7 @@ avr_strtod (const char * nptr, char ** endptr)
do { do {
if (i < 3200) if (i < 3200)
i = (((i << 2) + i) << 1) + c; /* i = 10*i + c */ i = (((i << 2) + i) << 1) + c; /* i = 10*i + c */
c = *nptr++ - '0'; c = (char) (*nptr++ - '0');
} while (c <= 9); } while (c <= 9);
if (flag & FL_MEXP) if (flag & FL_MEXP)
i = -i; i = -i;
@ -189,7 +189,7 @@ avr_strtod (const char * nptr, char ** endptr)
if ((flag & FL_ANY) && endptr) if ((flag & FL_ANY) && endptr)
*endptr = (char *)nptr - 1; *endptr = (char *)nptr - 1;
x.flt = __floatunsisf (x.u32); /* manually */ x.flt = (float) __floatunsisf (x.u32); /* manually */
if ((flag & FL_MINUS) && (flag & FL_ANY)) if ((flag & FL_MINUS) && (flag & FL_ANY))
x.flt = -x.flt; x.flt = -x.flt;
@ -204,7 +204,7 @@ avr_strtod (const char * nptr, char ** endptr)
for (pwr = 32; pwr; pwr >>= 1) { for (pwr = 32; pwr; pwr >>= 1) {
for (; exp >= pwr; exp -= pwr) { for (; exp >= pwr; exp -= pwr) {
union { union {
unsigned long u32; uint32_t u32;
float flt; float flt;
} y; } y;
y.u32 = (uint32_t) *((float *)nptr); y.u32 = (uint32_t) *((float *)nptr);
@ -213,7 +213,7 @@ avr_strtod (const char * nptr, char ** endptr)
nptr -= sizeof(float); nptr -= sizeof(float);
} }
if (!isfinite(x.flt) || x.flt == 0) if (!isfinite(x.flt) || x.flt == 0)
errno = ERANGE; avrlibc_errno = ERANGE;
} }
return x.flt; return x.flt;

@ -32,6 +32,7 @@
#include <limits.h> #include <limits.h>
#include <errno.h> #include <errno.h>
#include "avrlibc.h"
/* /*
* Convert a string to a long integer. * Convert a string to a long integer.
@ -39,14 +40,14 @@
* Ignores `locale' stuff. Assumes that the upper and lower case * Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous. * alphabets and digits are each contiguous.
*/ */
long int32_t
avr_strtol(const char *nptr, char **endptr, register int base) avr_strtol(const char *nptr, char **endptr, register int32_t base)
{ {
register unsigned long acc; register uint32_t acc;
register unsigned char c; register char c;
register unsigned long cutoff; register uint32_t cutoff;
register signed char any; register int8_t any;
unsigned char flag = 0; uint8_t flag = 0;
#define FL_NEG 0x01 /* number is negative */ #define FL_NEG 0x01 /* number is negative */
#define FL_0X 0x02 /* number has a 0x prefix */ #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 * Set any if any `digits' consumed; make it negative to indicate
* overflow. * overflow.
*/ */
#if LONG_MIN != -LONG_MAX - 1 #if INT32_MIN != -INT32_MAX - 1
# error "This implementation of strtol() does not work on this platform." # error "This implementation of strtol() does not work on this platform."
#endif #endif
switch (base) { switch (base) {
case 10: case 10:
cutoff = ((unsigned long)LONG_MAX + 1) / 10; cutoff = ((uint32_t)INT32_MAX + 1) / 10;
break; break;
case 16: case 16:
cutoff = ((unsigned long)LONG_MAX + 1) / 16; cutoff = ((uint32_t)INT32_MAX + 1) / 16;
break; break;
case 8: case 8:
cutoff = ((unsigned long)LONG_MAX + 1) / 8; cutoff = ((uint32_t)INT32_MAX + 1) / 8;
break; break;
case 2: case 2:
cutoff = ((unsigned long)LONG_MAX + 1) / 2; cutoff = ((uint32_t)INT32_MAX + 1) / 2;
break; break;
default: default:
cutoff = ((unsigned long)LONG_MAX + 1) / base; cutoff = ((uint32_t)INT32_MAX + 1) / base;
} }
for (acc = 0, any = 0;; c = *nptr++) { for (acc = 0, any = 0;; c = *nptr++) {
@ -143,7 +144,7 @@ avr_strtol(const char *nptr, char **endptr, register int base)
continue; continue;
} }
acc = acc * base + c; acc = acc * base + c;
if (acc > (unsigned long)LONG_MAX + 1) if (acc > (uint32_t)INT32_MAX + 1)
any = -1; any = -1;
else else
any = 1; any = 1;
@ -155,13 +156,13 @@ avr_strtol(const char *nptr, char **endptr, register int base)
*endptr = (char *)nptr - 2; *endptr = (char *)nptr - 2;
} }
if (any < 0) { if (any < 0) {
acc = (flag & FL_NEG) ? LONG_MIN : LONG_MAX; acc = (flag & FL_NEG) ? INT32_MIN : INT32_MAX;
errno = ERANGE; avrlibc_errno = ERANGE;
} else if (flag & FL_NEG) { } else if (flag & FL_NEG) {
acc = -acc; acc = -acc;
} else if ((signed long)acc < 0) { } else if ((signed long)acc < 0) {
acc = LONG_MAX; acc = INT32_MAX;
errno = ERANGE; avrlibc_errno = ERANGE;
} }
return (acc); return (acc);
} }

@ -35,18 +35,18 @@
#include "avrlibc.h" #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 * Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous. * alphabets and digits are each contiguous.
*/ */
unsigned long uint32_t
avr_strtoul(const char *nptr, char **endptr, register int base) avr_strtoul(const char *nptr, char **endptr, register int32_t base)
{ {
register unsigned long acc; register uint32_t acc;
register unsigned char c; register char c;
register unsigned long cutoff; register uint32_t cutoff;
register signed char any; register int8_t any;
unsigned char flag = 0; unsigned char flag = 0;
#define FL_NEG 0x01 /* number is negative */ #define FL_NEG 0x01 /* number is negative */
#define FL_0X 0x02 /* number has a 0x prefix */ #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) { switch (base) {
case 16: cutoff = ULONG_MAX / 16; break; case 16: cutoff = UINT32_MAX / 16; break;
case 10: cutoff = ULONG_MAX / 10; break; case 10: cutoff = UINT32_MAX / 10; break;
case 8: cutoff = ULONG_MAX / 8; break; case 8: cutoff = UINT32_MAX / 8; break;
default: cutoff = ULONG_MAX / base; default: cutoff = UINT32_MAX / base;
} }
for (acc = 0, any = 0;; c = *nptr++) { for (acc = 0, any = 0;; c = *nptr++) {
@ -126,7 +126,7 @@ avr_strtoul(const char *nptr, char **endptr, register int base)
continue; continue;
} }
acc = acc * base + c; acc = acc * base + c;
any = (c > acc) ? -1 : 1; any = (int8_t) ((c > acc) ? -1 : 1);
} }
if (endptr) { if (endptr) {
@ -138,8 +138,8 @@ avr_strtoul(const char *nptr, char **endptr, register int base)
if (flag & FL_NEG) if (flag & FL_NEG)
acc = -acc; acc = -acc;
if (any < 0) { if (any < 0) {
acc = ULONG_MAX; acc = UINT32_MAX;
errno = ERANGE; avrlibc_errno = ERANGE;
} }
return (acc); return (uint32_t) (acc);
} }

@ -0,0 +1,7 @@
//
// Created by MightyPork on 2018/02/23.
//
#include <stdint.h>
volatile int32_t avrlibc_errno = 0;

@ -8,21 +8,10 @@
#ifndef GEX_AVRLIBC_H_H #ifndef GEX_AVRLIBC_H_H
#define GEX_AVRLIBC_H_H #define GEX_AVRLIBC_H_H
/** #include <stdint.h>
* atoi() - parse decimal int from ASCII #include <stddef.h>
*
* @param p - string
* @return int, 0 on failure
*/
int avr_atoi(const char *p);
/** extern volatile int32_t avrlibc_errno;
* atol() - parse decimal long int from ASCII
*
* @param p - string
* @return int, 0 on failure
*/
long avr_atol(const char *p);
/** /**
* strtol() - parse integer number form string. * 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 * @param base - base 2, 10, 16.... 0 for auto
* @return the number * @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 nptr - string to parse
* @param endptr - NULL or pointer to string where the end will be stored (first bad char) * @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
*/ */
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 nptr - string to parse
* @param endptr - NULL or pointer to string where the end will be stored (first bad char) * @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 #endif //GEX_AVRLIBC_H_H

@ -190,7 +190,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
{ {
char ch; char ch;
LLONG value; LLONG value;
LDOUBLE fvalue; LDOUBLE fvalue = 0;
char *strvalue; char *strvalue;
int min; int min;
int max; int max;

@ -5,110 +5,3 @@
#include "str_utils.h" #include "str_utils.h"
#include "platform.h" #include "platform.h"
#include "avrlibc.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;
}

@ -103,55 +103,4 @@ last_char(const char *str)
return str[strlen(str) - 1]; 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 #endif

Loading…
Cancel
Save