Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a888366af
|
||
|
|
a60b736834
|
||
|
|
8dcdaf9236
|
@@ -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)))) + \
|
||||
(((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))
|
||||
|
||||
@@ -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__ )
|
||||
+1
-1
@@ -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
|
||||
|
||||
+34
-19
@@ -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;
|
||||
@@ -21,10 +22,8 @@ const char *const rsc_names[] = {
|
||||
#undef X
|
||||
};
|
||||
|
||||
// Check that EXTI have higher values than GPIOs in the enum
|
||||
// (determines the logic in the name generation code below)
|
||||
COMPILER_ASSERT(R_EXTI0 > R_PA0);
|
||||
|
||||
COMPILER_ASSERT(R_PF15 < R_EXTI0);
|
||||
COMPILER_ASSERT(R_PA0 == 0);
|
||||
|
||||
const char * rsc_get_name(Resource rsc)
|
||||
{
|
||||
@@ -34,23 +33,45 @@ const char * rsc_get_name(Resource rsc)
|
||||
// we assume the returned value is not stored anywhere
|
||||
// and is directly used in a sprintf call, hence a static buffer is OK to use
|
||||
|
||||
if (rsc >= R_EXTI0) {
|
||||
if (rsc >= R_EXTI0 && rsc <= R_EXTI15) {
|
||||
uint8_t index = rsc - R_EXTI0;
|
||||
SNPRINTF(gpionamebuf, 8, "EXTI%d", index);
|
||||
return gpionamebuf;
|
||||
}
|
||||
|
||||
if (rsc >= R_PA0) {
|
||||
// R_PA0 is 0
|
||||
if (rsc <= R_PF15) {
|
||||
// we assume the returned value is not stored anywhere
|
||||
// and is directly used in a sprintf call.
|
||||
uint8_t index = rsc - R_PA0;
|
||||
uint8_t index = rsc;
|
||||
SNPRINTF(gpionamebuf, 8, "P%c%d", 'A'+(index/16), index%16);
|
||||
return gpionamebuf;
|
||||
}
|
||||
|
||||
return rsc_names[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)
|
||||
{
|
||||
@@ -121,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;
|
||||
@@ -141,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;
|
||||
@@ -222,7 +237,7 @@ void rsc_print_all_available(IniWriter *iw)
|
||||
|
||||
uint32_t count0 = (iw->count + iw->skip);
|
||||
bool first = true;
|
||||
for (uint32_t rsc = 0; rsc < R_PA0; rsc++) {
|
||||
for (uint32_t rsc = R_EXTI15+1; rsc < R_NONE; rsc++) {
|
||||
if (RSC_IS_HELD(scratchmap, (Resource)rsc)) continue;
|
||||
if (!first) iw_string(iw, ", ");
|
||||
|
||||
@@ -242,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;
|
||||
}
|
||||
|
||||
@@ -257,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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -59,9 +59,9 @@ typedef enum hw_resource Resource;
|
||||
/** Enum of all resources */
|
||||
enum hw_resource {
|
||||
#define X(res_name) R_##res_name,
|
||||
XX_RESOURCES
|
||||
XX_RESOURCES_GPIO
|
||||
XX_RESOURCES_EXTI
|
||||
XX_RESOURCES
|
||||
#undef X
|
||||
R_NONE,
|
||||
RESOURCE_COUNT = R_NONE,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
+11
-216
@@ -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,19 @@ 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)
|
||||
/** Convert a pin resource to it's LL lib values */
|
||||
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);
|
||||
if (rsc > R_PF15) 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 port name */
|
||||
bool parse_port_name(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 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 optimize ("O2")
|
||||
/** spread a packed pinfield using a mask */
|
||||
@@ -285,25 +93,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<<i)) {
|
||||
if (i == index) return (uint8_t) cnt;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
/** Configure unit pins as analog (part of unit teardown) */
|
||||
void hw_deinit_unit_pins(Unit *unit)
|
||||
{
|
||||
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));
|
||||
GPIO_TypeDef *port = GPIO_PERIPHS[(rsc-R_PA0) / 16];
|
||||
uint32_t ll_pin = LL_GPIO_PINS[(rsc-R_PA0)%16];
|
||||
@@ -360,7 +156,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 */
|
||||
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)
|
||||
{
|
||||
if (required_freq == 0) return false;
|
||||
@@ -394,7 +190,6 @@ bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void hw_periph_clock_enable(void *periph)
|
||||
{
|
||||
// GPIOs are enabled by default on start-up
|
||||
|
||||
+7
-65
@@ -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
|
||||
*
|
||||
@@ -41,55 +31,14 @@ 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
|
||||
* Convert a pin resource to it's LL lib values
|
||||
*
|
||||
* @param str - source string
|
||||
* @param targetName - output: port name (one character)
|
||||
* @param targetNumber - output: pin number 0-15
|
||||
* @param[in] rsc - resource to process
|
||||
* @param[out] port - output port
|
||||
* @param[out] llpin - output LL pin mask
|
||||
* @return success
|
||||
*/
|
||||
bool parse_pin(const char *str, char *targetName, uint8_t *targetNumber);
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -121,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.
|
||||
@@ -192,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 { \
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include "usbd_msc.h"
|
||||
#include "task_main.h"
|
||||
|
||||
extern void plat_init(void);
|
||||
|
||||
/* TaskUsbEvent function */
|
||||
void TaskMain(void const * argument)
|
||||
{
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
@@ -18,17 +18,15 @@ void OW_loadBinary(Unit *unit, PayloadParser *pp)
|
||||
|
||||
priv->port_name = pp_char(pp);
|
||||
priv->pin_number = pp_u8(pp);
|
||||
if (version >= 1) {
|
||||
priv->parasitic = pp_bool(pp);
|
||||
}
|
||||
}
|
||||
|
||||
/** Write to a binary buffer for storing in Flash */
|
||||
void OW_writeBinary(Unit *unit, PayloadBuilder *pb)
|
||||
{
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
pb_u8(pb, 1); // version
|
||||
pb_u8(pb, 0); // version
|
||||
|
||||
pb_char(pb, priv->port_name);
|
||||
pb_u8(pb, priv->pin_number);
|
||||
@@ -44,10 +42,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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)");
|
||||
|
||||
@@ -20,23 +20,18 @@ void DIn_loadBinary(Unit *unit, PayloadParser *pp)
|
||||
priv->pins = pp_u16(pp);
|
||||
priv->pulldown = pp_u16(pp);
|
||||
priv->pullup = pp_u16(pp);
|
||||
|
||||
if (version >= 1) {
|
||||
priv->trig_rise = pp_u16(pp);
|
||||
priv->trig_fall = pp_u16(pp);
|
||||
priv->trig_holdoff = pp_u16(pp);
|
||||
}
|
||||
if (version >= 2) {
|
||||
priv->def_auto = pp_u16(pp);
|
||||
}
|
||||
}
|
||||
|
||||
/** Write to a binary buffer for storing in Flash */
|
||||
void DIn_writeBinary(Unit *unit, PayloadBuilder *pb)
|
||||
{
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
pb_u8(pb, 2); // version
|
||||
pb_u8(pb, 0); // version
|
||||
|
||||
pb_char(pb, priv->port_name);
|
||||
pb_u16(pb, priv->pins);
|
||||
@@ -57,28 +52,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 +92,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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -18,27 +18,22 @@ void UFCAP_loadBinary(Unit *unit, PayloadParser *pp)
|
||||
|
||||
priv->conf.signal_pname = pp_char(pp);
|
||||
priv->conf.signal_pnum = pp_u8(pp);
|
||||
|
||||
if (version >= 1) {
|
||||
priv->conf.active_level = pp_bool(pp);
|
||||
priv->conf.dfilter = pp_u8(pp);
|
||||
priv->conf.direct_presc = pp_u8(pp);
|
||||
priv->conf.direct_msec = pp_u16(pp);
|
||||
priv->conf.startmode = (enum fcap_opmode) pp_u8(pp);
|
||||
}
|
||||
}
|
||||
|
||||
/** Write to a binary buffer for storing in Flash */
|
||||
void UFCAP_writeBinary(Unit *unit, PayloadBuilder *pb)
|
||||
{
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
pb_u8(pb, 1); // version
|
||||
pb_u8(pb, 0); // version
|
||||
|
||||
pb_char(pb, priv->conf.signal_pname);
|
||||
pb_u8(pb, priv->conf.signal_pnum);
|
||||
|
||||
// V1
|
||||
pb_bool(pb, priv->conf.active_level);
|
||||
pb_u8(pb, priv->conf.dfilter);
|
||||
pb_u8(pb, priv->conf.direct_presc);
|
||||
@@ -55,22 +50,22 @@ 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,
|
||||
priv->conf.startmode = (enum fcap_opmode) cfg_enum4_parse(value,
|
||||
"N", OPMODE_IDLE,
|
||||
"I", OPMODE_INDIRECT_CONT,
|
||||
"D", OPMODE_DIRECT_CONT,
|
||||
@@ -110,7 +105,7 @@ 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,
|
||||
iw_entry(iw, "initial-mode", cfg_enum4_encode(priv->conf.startmode,
|
||||
OPMODE_IDLE, "N",
|
||||
OPMODE_INDIRECT_CONT, "I",
|
||||
OPMODE_DIRECT_CONT, "D",
|
||||
|
||||
@@ -20,18 +20,15 @@ void UI2C_loadBinary(Unit *unit, PayloadParser *pp)
|
||||
priv->anf = pp_bool(pp);
|
||||
priv->dnf = pp_u8(pp);
|
||||
priv->speed = pp_u8(pp);
|
||||
|
||||
if (version >= 1) {
|
||||
priv->remap = pp_u8(pp);
|
||||
}
|
||||
}
|
||||
|
||||
/** Write to a binary buffer for storing in Flash */
|
||||
void UI2C_writeBinary(Unit *unit, PayloadBuilder *pb)
|
||||
{
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
pb_u8(pb, 1); // version
|
||||
pb_u8(pb, 0); // version
|
||||
|
||||
pb_u8(pb, priv->periph_num);
|
||||
pb_bool(pb, priv->anf);
|
||||
@@ -49,19 +46,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 +96,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);
|
||||
|
||||
@@ -16,7 +16,7 @@ error_t UU_Npx_Clear(Unit *unit)
|
||||
CHECK_TYPE(unit, &UNIT_NEOPIXEL);
|
||||
|
||||
struct priv *priv = unit->data;
|
||||
ws2812_clear(priv->port, priv->ll_pin, priv->pixels);
|
||||
ws2812_clear(priv->port, priv->ll_pin, priv->cfg.pixels);
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ error_t UU_Npx_Load(Unit *unit, const uint8_t *packed_rgb, uint32_t nbytes)
|
||||
CHECK_TYPE(unit, &UNIT_NEOPIXEL);
|
||||
|
||||
struct priv *priv = unit->data;
|
||||
if (nbytes != 3*priv->pixels) return E_BAD_COUNT;
|
||||
ws2812_load_raw(priv->port, priv->ll_pin, packed_rgb, priv->pixels);
|
||||
if (nbytes != 3*priv->cfg.pixels) return E_BAD_COUNT;
|
||||
ws2812_load_raw(priv->port, priv->ll_pin, packed_rgb, priv->cfg.pixels);
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ static error_t load_u32(Unit *unit, const uint8_t *bytes, uint32_t nbytes, bool
|
||||
CHECK_TYPE(unit, &UNIT_NEOPIXEL);
|
||||
|
||||
struct priv *priv = unit->data;
|
||||
if (nbytes != 4*priv->pixels) return E_BAD_COUNT;
|
||||
ws2812_load_sparse(priv->port, priv->ll_pin, bytes, priv->pixels, bige);
|
||||
if (nbytes != 4*priv->cfg.pixels) return E_BAD_COUNT;
|
||||
ws2812_load_sparse(priv->port, priv->ll_pin, bytes, priv->cfg.pixels, bige);
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,6 @@ error_t UU_Npx_GetCount(Unit *unit, uint16_t *count)
|
||||
CHECK_TYPE(unit, &UNIT_NEOPIXEL);
|
||||
|
||||
struct priv *priv = unit->data;
|
||||
*count = priv->pixels;
|
||||
*count = priv->cfg.pixels;
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,8 @@ error_t Npx_preInit(Unit *unit)
|
||||
if (priv == NULL) return E_OUT_OF_MEM;
|
||||
|
||||
// some defaults
|
||||
priv->pin_number = 0;
|
||||
priv->port_name = 'A';
|
||||
priv->pixels = 1;
|
||||
priv->cfg.pin = R_PA0;
|
||||
priv->cfg.pixels = 1;
|
||||
|
||||
return E_SUCCESS;
|
||||
}
|
||||
@@ -30,13 +29,9 @@ error_t Npx_init(Unit *unit)
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
// --- 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);
|
||||
suc = hw_pinrsc2ll(priv->cfg.pin, &priv->port, &priv->ll_pin);
|
||||
if (!suc) return E_BAD_CONFIG;
|
||||
|
||||
// --- Claim resources ---
|
||||
TRY(rsc_claim(unit, rsc));
|
||||
TRY(rsc_claim(unit, priv->cfg.pin));
|
||||
|
||||
// --- Init hardware ---
|
||||
LL_GPIO_SetPinMode(priv->port, priv->ll_pin, LL_GPIO_MODE_OUTPUT);
|
||||
@@ -45,7 +40,7 @@ error_t Npx_init(Unit *unit)
|
||||
|
||||
// clear strip
|
||||
|
||||
ws2812_clear(priv->port, priv->ll_pin, priv->pixels);
|
||||
ws2812_clear(priv->port, priv->ll_pin, priv->cfg.pixels);
|
||||
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
|
||||
/** Private data structure */
|
||||
struct priv {
|
||||
char port_name;
|
||||
uint8_t pin_number;
|
||||
struct {
|
||||
Resource pin;
|
||||
uint16_t pixels;
|
||||
} cfg;
|
||||
|
||||
uint32_t ll_pin;
|
||||
GPIO_TypeDef *port;
|
||||
|
||||
@@ -13,9 +13,8 @@ void Npx_loadBinary(Unit *unit, PayloadParser *pp)
|
||||
{
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
priv->port_name = pp_char(pp);
|
||||
priv->pin_number = pp_u8(pp);
|
||||
priv->pixels = pp_u16(pp);
|
||||
priv->cfg.pin = (Resource) pp_u8(pp);
|
||||
priv->cfg.pixels = pp_u16(pp);
|
||||
}
|
||||
|
||||
/** Write to a binary buffer for storing in Flash */
|
||||
@@ -23,9 +22,8 @@ void Npx_writeBinary(Unit *unit, PayloadBuilder *pb)
|
||||
{
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
pb_char(pb, priv->port_name);
|
||||
pb_u8(pb, priv->pin_number);
|
||||
pb_u16(pb, priv->pixels);
|
||||
pb_u8(pb, priv->cfg.pin);
|
||||
pb_u16(pb, priv->cfg.pixels);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -37,10 +35,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);
|
||||
priv->cfg.pin = cfg_pinrsc_parse(value, &suc);
|
||||
}
|
||||
else if (streq(key, "pixels")) {
|
||||
priv->pixels = (uint16_t) avr_atoi(value);
|
||||
priv->cfg.pixels = cfg_u16_parse(value, &suc);
|
||||
}
|
||||
else {
|
||||
return E_BAD_KEY;
|
||||
@@ -56,8 +54,8 @@ void Npx_writeIni(Unit *unit, IniWriter *iw)
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
iw_comment(iw, "Data pin");
|
||||
iw_entry(iw, "pin", "%c%d", priv->port_name, priv->pin_number);
|
||||
iw_entry(iw, "pin", cfg_pinrsc_encode(priv->cfg.pin));
|
||||
|
||||
iw_comment(iw, "Number of pixels");
|
||||
iw_entry(iw, "pixels", "%d", priv->pixels);
|
||||
iw_entry(iw, "pixels", "%d", priv->cfg.pixels);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ error_t UU_SIPO_Write(Unit *unit, const uint8_t *buffer, uint16_t buflen, uint16
|
||||
// buffer contains data for the individual data pins, back to back as AAA BBB CCC (whole bytes)
|
||||
const uint8_t data_width = priv->data_width;
|
||||
const uint16_t bytelen = buflen / data_width;
|
||||
const uint16_t mask = priv->data_pins;
|
||||
const uint16_t mask = priv->cfg.data_pins;
|
||||
|
||||
uint8_t offsets[16];
|
||||
for (int i=0; i<16; i++) offsets[i] = (uint8_t) (bytelen * i);
|
||||
@@ -61,7 +61,7 @@ error_t UU_SIPO_Write(Unit *unit, const uint8_t *buffer, uint16_t buflen, uint16
|
||||
priv->data_port->BSRR = spread | (((~spread) & mask) << 16);
|
||||
|
||||
// Shift clock pulse
|
||||
send_pulse(priv->shift_pol, priv->shift_port, priv->shift_ll);
|
||||
send_pulse(priv->cfg.shift_pol, priv->shift_port, priv->shift_ll);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ error_t UU_SIPO_Write(Unit *unit, const uint8_t *buffer, uint16_t buflen, uint16
|
||||
uint16_t spread = pinmask_spread(terminal_data, mask);
|
||||
priv->data_port->BSRR = spread | (((~spread) & mask) << 16);
|
||||
|
||||
send_pulse(priv->store_pol, priv->store_port, priv->store_ll);
|
||||
send_pulse(priv->cfg.store_pol, priv->store_port, priv->store_ll);
|
||||
return E_SUCCESS;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
@@ -80,8 +80,8 @@ error_t UU_SIPO_DirectData(Unit *unit, uint16_t data_packed)
|
||||
CHECK_TYPE(unit, &UNIT_SIPO);
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
uint16_t spread = pinmask_spread(data_packed, priv->data_pins);
|
||||
priv->data_port->BSRR = spread | (((~spread) & priv->data_pins) << 16);
|
||||
uint16_t spread = pinmask_spread(data_packed, priv->cfg.data_pins);
|
||||
priv->data_port->BSRR = spread | (((~spread) & priv->cfg.data_pins) << 16);
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ error_t UU_SIPO_DirectClear(Unit *unit)
|
||||
{
|
||||
CHECK_TYPE(unit, &UNIT_SIPO);
|
||||
struct priv *priv = unit->data;
|
||||
send_pulse(priv->clear_pol, priv->clear_port, priv->clear_ll);
|
||||
send_pulse(priv->cfg.clear_pol, priv->clear_port, priv->clear_ll);
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ error_t UU_SIPO_DirectShift(Unit *unit)
|
||||
{
|
||||
CHECK_TYPE(unit, &UNIT_SIPO);
|
||||
struct priv *priv = unit->data;
|
||||
send_pulse(priv->shift_pol, priv->shift_port, priv->shift_ll);
|
||||
send_pulse(priv->cfg.shift_pol, priv->shift_port, priv->shift_ll);
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -105,6 +105,6 @@ error_t UU_SIPO_DirectStore(Unit *unit)
|
||||
{
|
||||
CHECK_TYPE(unit, &UNIT_SIPO);
|
||||
struct priv *priv = unit->data;
|
||||
send_pulse(priv->store_pol, priv->store_port, priv->store_ll);
|
||||
send_pulse(priv->cfg.store_pol, priv->store_port, priv->store_ll);
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
+21
-34
@@ -14,20 +14,17 @@ error_t USIPO_preInit(Unit *unit)
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv));
|
||||
if (priv == NULL) return E_OUT_OF_MEM;
|
||||
|
||||
priv->store_pname = 'A';
|
||||
priv->store_pnum = 0;
|
||||
priv->store_pol = true;
|
||||
priv->cfg.pin_store = R_PA0;
|
||||
priv->cfg.store_pol = true;
|
||||
|
||||
priv->shift_pname = 'A';
|
||||
priv->shift_pnum = 1;
|
||||
priv->shift_pol = true;
|
||||
priv->cfg.pin_shift = R_PA1;
|
||||
priv->cfg.shift_pol = true;
|
||||
|
||||
priv->clear_pname = 'A';
|
||||
priv->clear_pnum = 2;
|
||||
priv->clear_pol = false;
|
||||
priv->cfg.pin_clear = R_PA2;
|
||||
priv->cfg.clear_pol = false;
|
||||
|
||||
priv->data_pname = 'A';
|
||||
priv->data_pins = (1<<3);
|
||||
priv->cfg.data_pname = 'A';
|
||||
priv->cfg.data_pins = (1<<3);
|
||||
|
||||
return E_SUCCESS;
|
||||
}
|
||||
@@ -39,33 +36,23 @@ error_t USIPO_init(Unit *unit)
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
// --- 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);
|
||||
suc &= hw_pinrsc2ll(priv->cfg.pin_store, &priv->store_port, &priv->store_ll);
|
||||
suc &= hw_pinrsc2ll(priv->cfg.pin_shift, &priv->shift_port, &priv->shift_ll);
|
||||
suc &= hw_pinrsc2ll(priv->cfg.pin_clear, &priv->clear_port, &priv->clear_ll);
|
||||
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);
|
||||
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);
|
||||
if (!suc) return E_BAD_CONFIG;
|
||||
TRY(rsc_claim(unit, clear_rsc));
|
||||
TRY(rsc_claim(unit, priv->cfg.pin_store));
|
||||
TRY(rsc_claim(unit, priv->cfg.pin_shift));
|
||||
TRY(rsc_claim(unit, priv->cfg.pin_clear));
|
||||
|
||||
// Claim all needed pins
|
||||
TRY(rsc_claim_gpios(unit, priv->data_pname, priv->data_pins));
|
||||
priv->data_port = hw_port2periph(priv->data_pname, &suc);
|
||||
TRY(rsc_claim_gpios(unit, priv->cfg.data_pname, priv->cfg.data_pins));
|
||||
priv->data_port = hw_port2periph(priv->cfg.data_pname, &suc);
|
||||
|
||||
// --- Init hardware ---
|
||||
|
||||
priv->data_width = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (priv->data_pins & (1 << i)) {
|
||||
if (priv->cfg.data_pins & (1 << i)) {
|
||||
uint32_t ll_pin = hw_pin2ll((uint8_t) i, &suc);
|
||||
LL_GPIO_SetPinMode(priv->data_port, ll_pin, LL_GPIO_MODE_OUTPUT);
|
||||
LL_GPIO_SetPinOutputType(priv->data_port, ll_pin, LL_GPIO_OUTPUT_PUSHPULL);
|
||||
@@ -75,7 +62,7 @@ error_t USIPO_init(Unit *unit)
|
||||
}
|
||||
|
||||
// Set the initial state - zeros
|
||||
priv->data_port->ODR &= ~priv->data_pins;
|
||||
priv->data_port->ODR &= ~priv->cfg.data_pins;
|
||||
|
||||
|
||||
// STORE
|
||||
@@ -83,7 +70,7 @@ error_t USIPO_init(Unit *unit)
|
||||
LL_GPIO_SetPinOutputType(priv->store_port, priv->store_ll, LL_GPIO_OUTPUT_PUSHPULL);
|
||||
LL_GPIO_SetPinSpeed(priv->store_port, priv->store_ll, LL_GPIO_SPEED_FREQ_HIGH);
|
||||
|
||||
if (priv->store_pol)
|
||||
if (priv->cfg.store_pol)
|
||||
LL_GPIO_ResetOutputPin(priv->store_port, priv->store_ll);
|
||||
else
|
||||
LL_GPIO_SetOutputPin(priv->store_port, priv->store_ll);
|
||||
@@ -93,7 +80,7 @@ error_t USIPO_init(Unit *unit)
|
||||
LL_GPIO_SetPinOutputType(priv->shift_port, priv->shift_ll, LL_GPIO_OUTPUT_PUSHPULL);
|
||||
LL_GPIO_SetPinSpeed(priv->shift_port, priv->shift_ll, LL_GPIO_SPEED_FREQ_HIGH);
|
||||
|
||||
if (priv->shift_pol)
|
||||
if (priv->cfg.shift_pol)
|
||||
LL_GPIO_ResetOutputPin(priv->shift_port, priv->shift_ll);
|
||||
else
|
||||
LL_GPIO_SetOutputPin(priv->shift_port, priv->shift_ll);
|
||||
@@ -103,7 +90,7 @@ error_t USIPO_init(Unit *unit)
|
||||
LL_GPIO_SetPinOutputType(priv->clear_port, priv->clear_ll, LL_GPIO_OUTPUT_PUSHPULL);
|
||||
LL_GPIO_SetPinSpeed(priv->clear_port, priv->clear_ll, LL_GPIO_SPEED_FREQ_HIGH);
|
||||
|
||||
if (priv->clear_pol)
|
||||
if (priv->cfg.clear_pol)
|
||||
LL_GPIO_ResetOutputPin(priv->clear_port, priv->clear_ll);
|
||||
else
|
||||
LL_GPIO_SetOutputPin(priv->clear_port, priv->clear_ll);
|
||||
|
||||
@@ -13,21 +13,20 @@
|
||||
|
||||
/** Private data structure */
|
||||
struct priv {
|
||||
struct {
|
||||
// settings
|
||||
char store_pname;
|
||||
uint8_t store_pnum;
|
||||
Resource pin_store;
|
||||
bool store_pol; //!< Store pulse active edge
|
||||
|
||||
char shift_pname;
|
||||
uint8_t shift_pnum;
|
||||
Resource pin_shift;
|
||||
bool shift_pol; //!< Shift clock active edge
|
||||
|
||||
char clear_pname;
|
||||
uint8_t clear_pnum;
|
||||
Resource pin_clear;
|
||||
bool clear_pol; //!< Clear signal active level
|
||||
|
||||
char data_pname;
|
||||
uint16_t data_pins;
|
||||
} cfg;
|
||||
|
||||
// live fields
|
||||
uint32_t store_ll;
|
||||
|
||||
+32
-38
@@ -16,20 +16,17 @@ void USIPO_loadBinary(Unit *unit, PayloadParser *pp)
|
||||
uint8_t version = pp_u8(pp);
|
||||
(void)version;
|
||||
|
||||
priv->store_pname = pp_char(pp);
|
||||
priv->store_pnum = pp_u8(pp);
|
||||
priv->store_pol = pp_bool(pp);
|
||||
priv->cfg.pin_store = (Resource) pp_u8(pp);
|
||||
priv->cfg.store_pol = pp_bool(pp);
|
||||
|
||||
priv->shift_pname = pp_char(pp);
|
||||
priv->shift_pnum = pp_u8(pp);
|
||||
priv->shift_pol = pp_bool(pp);
|
||||
priv->cfg.pin_shift = (Resource) pp_u8(pp);
|
||||
priv->cfg.shift_pol = pp_bool(pp);
|
||||
|
||||
priv->clear_pname = pp_char(pp);
|
||||
priv->clear_pnum = pp_u8(pp);
|
||||
priv->clear_pol = pp_bool(pp);
|
||||
priv->cfg.pin_clear = (Resource) pp_u8(pp);
|
||||
priv->cfg.clear_pol = pp_bool(pp);
|
||||
|
||||
priv->data_pname = pp_char(pp);
|
||||
priv->data_pins = pp_u16(pp);
|
||||
priv->cfg.data_pname = pp_char(pp);
|
||||
priv->cfg.data_pins = pp_u16(pp);
|
||||
}
|
||||
|
||||
/** Write to a binary buffer for storing in Flash */
|
||||
@@ -39,20 +36,17 @@ void USIPO_writeBinary(Unit *unit, PayloadBuilder *pb)
|
||||
|
||||
pb_u8(pb, 0); // version
|
||||
|
||||
pb_char(pb, priv->store_pname);
|
||||
pb_u8(pb, priv->store_pnum);
|
||||
pb_bool(pb, priv->store_pol);
|
||||
pb_u8(pb, priv->cfg.pin_store);
|
||||
pb_bool(pb, priv->cfg.store_pol);
|
||||
|
||||
pb_char(pb, priv->shift_pname);
|
||||
pb_u8(pb, priv->shift_pnum);
|
||||
pb_bool(pb, priv->shift_pol);
|
||||
pb_u8(pb, priv->cfg.pin_shift);
|
||||
pb_bool(pb, priv->cfg.shift_pol);
|
||||
|
||||
pb_char(pb, priv->clear_pname);
|
||||
pb_u8(pb, priv->clear_pnum);
|
||||
pb_bool(pb, priv->clear_pol);
|
||||
pb_u8(pb, priv->cfg.pin_clear);
|
||||
pb_bool(pb, priv->cfg.clear_pol);
|
||||
|
||||
pb_char(pb, priv->data_pname);
|
||||
pb_u16(pb, priv->data_pins);
|
||||
pb_char(pb, priv->cfg.data_pname);
|
||||
pb_u16(pb, priv->cfg.data_pins);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -64,30 +58,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);
|
||||
priv->cfg.pin_store = cfg_pinrsc_parse(value, &suc);
|
||||
}
|
||||
else if (streq(key, "shift-pin")) {
|
||||
suc = parse_pin(value, &priv->shift_pname, &priv->shift_pnum);
|
||||
priv->cfg.pin_shift = cfg_pinrsc_parse(value, &suc);
|
||||
}
|
||||
else if (streq(key, "clear-pin")) {
|
||||
suc = parse_pin(value, &priv->clear_pname, &priv->clear_pnum);
|
||||
priv->cfg.pin_clear = cfg_pinrsc_parse(value, &suc);
|
||||
}
|
||||
|
||||
else if (streq(key, "store-pol")) {
|
||||
priv->store_pol = (bool) avr_atoi(value);
|
||||
priv->cfg.store_pol = cfg_bool_parse(value, &suc);
|
||||
}
|
||||
else if (streq(key, "shift-pol")) {
|
||||
priv->shift_pol = (bool) avr_atoi(value);
|
||||
priv->cfg.shift_pol = cfg_bool_parse(value, &suc);
|
||||
}
|
||||
else if (streq(key, "clear-pol")) {
|
||||
priv->clear_pol = (bool) avr_atoi(value);
|
||||
priv->cfg.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->cfg.data_pname);
|
||||
}
|
||||
else if (streq(key, "data-pins")) {
|
||||
priv->data_pins = (uint16_t) parse_pinmask(value, &suc);
|
||||
priv->cfg.data_pins = cfg_pinmask_parse(value, &suc);
|
||||
}
|
||||
|
||||
else {
|
||||
@@ -104,19 +98,19 @@ void USIPO_writeIni(Unit *unit, IniWriter *iw)
|
||||
struct priv *priv = unit->data;
|
||||
|
||||
iw_comment(iw, "Shift pin & its active edge (1-rising,0-falling)");
|
||||
iw_entry(iw, "shift-pin", "%c%d", priv->shift_pname, priv->shift_pnum);
|
||||
iw_entry(iw, "shift-pol", "%d", priv->shift_pol);
|
||||
iw_entry(iw, "shift-pin", cfg_pinrsc_encode(priv->cfg.pin_shift));
|
||||
iw_entry(iw, "shift-pol", "%d", priv->cfg.shift_pol);
|
||||
|
||||
iw_comment(iw, "Store pin & its active edge");
|
||||
iw_entry(iw, "store-pin", "%c%d", priv->store_pname, priv->store_pnum);
|
||||
iw_entry(iw, "store-pol", "%d", priv->store_pol);
|
||||
iw_entry(iw, "store-pin", cfg_pinrsc_encode(priv->cfg.pin_store));
|
||||
iw_entry(iw, "store-pol", "%d", priv->cfg.store_pol);
|
||||
|
||||
iw_comment(iw, "Clear pin & its active level");
|
||||
iw_entry(iw, "clear-pin", "%c%d", priv->clear_pname, priv->clear_pnum);
|
||||
iw_entry(iw, "clear-pol", "%d", priv->clear_pol);
|
||||
iw_entry(iw, "clear-pin", cfg_pinrsc_encode(priv->cfg.pin_clear));
|
||||
iw_entry(iw, "clear-pol", "%d", priv->cfg.clear_pol);
|
||||
|
||||
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-port", "%c", priv->cfg.data_pname);
|
||||
iw_entry(iw, "data-pins", cfg_pinmask_encode(priv->cfg.data_pins, unit_tmp512, true));
|
||||
}
|
||||
|
||||
|
||||
+11
-13
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,20 +180,20 @@ 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,
|
||||
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,
|
||||
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,
|
||||
iw_entry(iw, "first-bit", cfg_enum2_encode((uint32_t) priv->lsb_first,
|
||||
0, "MSB",
|
||||
1, "LSB"));
|
||||
|
||||
@@ -201,13 +201,13 @@ void UUSART_writeIni(Unit *unit, IniWriter *iw)
|
||||
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,
|
||||
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,
|
||||
iw_entry(iw, "hw-flow-control", cfg_enum4_encode(priv->hw_flow_control,
|
||||
0, "NONE",
|
||||
1, "RTS",
|
||||
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);
|
||||
}
|
||||
+10
-10
@@ -37,10 +37,10 @@
|
||||
#include <stdint.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
|
||||
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;
|
||||
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;
|
||||
|
||||
+19
-18
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
+15
-15
@@ -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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
//
|
||||
// Created by MightyPork on 2018/02/23.
|
||||
//
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
volatile int32_t avrlibc_errno = 0;
|
||||
+36
-25
@@ -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 <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* 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,7 +24,39 @@ 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);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @param base - base 2, 10, 16.... 0 for auto
|
||||
* @return the number
|
||||
*/
|
||||
uint32_t avr_strtoul(const char *nptr, char **endptr, register int32_t base);
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -46,14 +67,4 @@ long avr_strtol(const char *nptr, char **endptr, register int base);
|
||||
*/
|
||||
double avr_strtod (const char * nptr, char ** endptr);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @param base - base 2, 10, 16.... 0 for auto
|
||||
* @return the number
|
||||
*/
|
||||
unsigned long avr_strtoul(const char *nptr, char **endptr, register int base);
|
||||
|
||||
#endif //GEX_AVRLIBC_H_H
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user