3 Commits
49 changed files with 843 additions and 1415 deletions
@@ -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
View File
@@ -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
View File
@@ -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);
+10
View File
@@ -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.
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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);
+3 -2
View File
@@ -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;
}
+1
View File
@@ -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"
+1 -1
View File
@@ -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
+299
View File
@@ -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;
}
+153
View File
@@ -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
+12 -217
View File
@@ -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,8 +156,8 @@ error_t hw_configure_sparse_pins(char port_name, uint16_t mask, GPIO_TypeDef **p
}
/** Solve a timer/counter's count and prescaller value */
bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit,
uint16_t *presc, uint32_t *count, float *real_freq)
bool hw_solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit,
uint16_t *presc, uint32_t *count, float *real_freq)
{
if (required_freq == 0) return false;
@@ -394,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
View File
@@ -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 { \
+3 -8
View File
@@ -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);
+1 -7
View File
@@ -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 */
-2
View File
@@ -12,8 +12,6 @@
#include "usbd_msc.h"
#include "task_main.h"
extern void plat_init(void);
/* TaskUsbEvent function */
void TaskMain(void const * argument)
{
+1 -1
View File
@@ -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 ---
+4 -6
View File
@@ -18,9 +18,7 @@ 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);
}
priv->parasitic = pp_bool(pp);
}
/** Write to a binary buffer for storing in Flash */
@@ -28,7 +26,7 @@ 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;
+1 -1
View File
@@ -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;
}
+6 -6
View File
@@ -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)");
+19 -24
View File
@@ -20,15 +20,10 @@ 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);
}
priv->trig_rise = pp_u16(pp);
priv->trig_fall = pp_u16(pp);
priv->trig_holdoff = pp_u16(pp);
priv->def_auto = pp_u16(pp);
}
/** Write to a binary buffer for storing in Flash */
@@ -36,7 +31,7 @@ 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);
+7 -7
View File
@@ -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));
}
+22 -27
View File
@@ -18,14 +18,11 @@ 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);
}
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 */
@@ -33,12 +30,10 @@ 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,27 +50,27 @@ error_t UFCAP_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data;
if (streq(key, "pin")) {
suc = parse_pin(value, &priv->conf.signal_pname, &priv->conf.signal_pnum);
suc = cfg_portpin_parse(value, &priv->conf.signal_pname, &priv->conf.signal_pnum);
}
else if (streq(key, "active-level")) {
priv->conf.active_level = (bool) avr_atoi(value);
priv->conf.active_level = cfg_bool_parse(value, &suc);
}
else if (streq(key, "input-filter")) {
priv->conf.dfilter = (uint8_t) avr_atoi(value);
priv->conf.dfilter = cfg_u8_parse(value, &suc);
}
else if (streq(key, "direct-presc")) {
priv->conf.direct_presc = (uint8_t) avr_atoi(value);
priv->conf.direct_presc = cfg_u8_parse(value, &suc);
}
else if (streq(key, "direct-time")) {
priv->conf.direct_msec = (uint16_t) avr_atoi(value);
priv->conf.direct_msec = cfg_u16_parse(value, &suc);
}
else if (streq(key, "initial-mode")) {
priv->conf.startmode = (enum fcap_opmode) str_parse_4(value,
"N", OPMODE_IDLE,
"I", OPMODE_INDIRECT_CONT,
"D", OPMODE_DIRECT_CONT,
"F", OPMODE_FREE_COUNTER,
&suc);
priv->conf.startmode = (enum fcap_opmode) cfg_enum4_parse(value,
"N", OPMODE_IDLE,
"I", OPMODE_INDIRECT_CONT,
"D", OPMODE_DIRECT_CONT,
"F", OPMODE_FREE_COUNTER,
&suc);
}
else{
return E_BAD_KEY;
@@ -110,10 +105,10 @@ void UFCAP_writeIni(Unit *unit, IniWriter *iw)
iw_cmt_newline(iw);
iw_comment(iw, "Mode on startup: N-none, I-indirect, D-direct, F-free count");
iw_entry(iw, "initial-mode", "%s", str_4(priv->conf.startmode,
OPMODE_IDLE, "N",
OPMODE_INDIRECT_CONT, "I",
OPMODE_DIRECT_CONT, "D",
OPMODE_FREE_COUNTER, "F"));
iw_entry(iw, "initial-mode", cfg_enum4_encode(priv->conf.startmode,
OPMODE_IDLE, "N",
OPMODE_INDIRECT_CONT, "I",
OPMODE_DIRECT_CONT, "D",
OPMODE_FREE_COUNTER, "F"));
}
+8 -11
View File
@@ -20,10 +20,7 @@ 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);
}
priv->remap = pp_u8(pp);
}
/** Write to a binary buffer for storing in Flash */
@@ -31,7 +28,7 @@ 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);
+6 -6
View File
@@ -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;
}
+5 -10
View File
@@ -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;
}
+4 -3
View File
@@ -13,9 +13,10 @@
/** Private data structure */
struct priv {
char port_name;
uint8_t pin_number;
uint16_t pixels;
struct {
Resource pin;
uint16_t pixels;
} cfg;
uint32_t ll_pin;
GPIO_TypeDef *port;
+8 -10
View File
@@ -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);
}
+8 -8
View File
@@ -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
View File
@@ -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);
+11 -12
View File
@@ -13,21 +13,20 @@
/** Private data structure */
struct priv {
// settings
char store_pname;
uint8_t store_pnum;
bool store_pol; //!< Store pulse active edge
struct {
// settings
Resource pin_store;
bool store_pol; //!< Store pulse active edge
char shift_pname;
uint8_t shift_pnum;
bool shift_pol; //!< Shift clock active edge
Resource pin_shift;
bool shift_pol; //!< Shift clock active edge
char clear_pname;
uint8_t clear_pnum;
bool clear_pol; //!< Clear signal active level
Resource pin_clear;
bool clear_pol; //!< Clear signal active level
char data_pname;
uint16_t data_pins;
char data_pname;
uint16_t data_pins;
} cfg;
// live fields
uint32_t store_ll;
+32 -38
View File
@@ -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
View File
@@ -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));
}
+51 -51
View File
@@ -81,66 +81,66 @@ error_t UUSART_loadIni(Unit *unit, const char *key, const char *value)
struct priv *priv = unit->data;
if (streq(key, "device")) {
priv->periph_num = (uint8_t) avr_atoi(value);
priv->periph_num = cfg_u8_parse(value, &suc);
}
else if (streq(key, "remap")) {
priv->remap = (uint8_t) avr_atoi(value);
priv->remap = cfg_u8_parse(value, &suc);
}
else if (streq(key, "baud-rate")) {
priv->baudrate = (uint32_t ) avr_atoi(value);
priv->baudrate = cfg_u32_parse(value, &suc);
}
else if (streq(key, "parity")) {
priv->parity = (uint8_t) str_parse_3(value,
"NONE", 0,
"ODD", 1,
"EVEN", 2, &suc);
priv->parity = (uint8_t) cfg_enum3_parse(value,
"NONE", 0,
"ODD", 1,
"EVEN", 2, &suc);
}
else if (streq(key, "stop-bits")) {
priv->stopbits = (uint8_t) str_parse_4(value,
"0.5", 0,
"1", 1,
"1.5", 2,
"2", 3, &suc);
priv->stopbits = (uint8_t) cfg_enum4_parse(value,
"0.5", 0,
"1", 1,
"1.5", 2,
"2", 3, &suc);
}
else if (streq(key, "direction")) {
priv->direction = (uint8_t) str_parse_3(value,
"RX", UUSART_DIRECTION_RX,
"TX", UUSART_DIRECTION_TX,
"RXTX", UUSART_DIRECTION_RXTX, &suc);
priv->direction = (uint8_t) cfg_enum3_parse(value,
"RX", UUSART_DIRECTION_RX,
"TX", UUSART_DIRECTION_TX,
"RXTX", UUSART_DIRECTION_RXTX, &suc);
}
else if (streq(key, "hw-flow-control")) {
priv->hw_flow_control = (uint8_t) str_parse_4(value,
"NONE", 0,
"RTS", 1,
"CTS", 2,
"FULL", 3, &suc);
priv->hw_flow_control = (uint8_t) cfg_enum4_parse(value,
"NONE", 0,
"RTS", 1,
"CTS", 2,
"FULL", 3, &suc);
}
else if (streq(key, "word-width")) {
priv->width = (uint8_t ) avr_atoi(value);
priv->width = cfg_u8_parse(value, &suc);
}
else if (streq(key, "first-bit")) {
priv->lsb_first = (bool)str_parse_2(value, "MSB", 0, "LSB", 1, &suc);
priv->lsb_first = (bool) cfg_enum2_parse(value, "MSB", 0, "LSB", 1, &suc);
}
else if (streq(key, "clock-output")) {
priv->clock_output = str_parse_yn(value, &suc);
priv->clock_output = cfg_bool_parse(value, &suc);
}
else if (streq(key, "cpol")) {
priv->cpol = (bool) avr_atoi(value);
priv->cpol = cfg_bool_parse(value, &suc);
}
else if (streq(key, "cpha")) {
priv->cpha = (bool) avr_atoi(value);
priv->cpha = cfg_bool_parse(value, &suc);
}
else if (streq(key, "de-output")) {
priv->de_output = str_parse_yn(value, &suc);
priv->de_output = cfg_bool_parse(value, &suc);
}
else if (streq(key, "de-polarity")) {
priv->de_polarity = (bool) avr_atoi(value);
priv->de_polarity = cfg_bool_parse(value, &suc);
}
else if (streq(key, "de-assert-time")) {
priv->de_assert_time = (uint8_t) avr_atoi(value);
priv->de_assert_time = cfg_u8_parse(value, &suc);
}
else if (streq(key, "de-clear-time")) {
priv->de_clear_time = (uint8_t) avr_atoi(value);
priv->de_clear_time = cfg_u8_parse(value, &suc);
}
else {
return E_BAD_KEY;
@@ -180,38 +180,38 @@ void UUSART_writeIni(Unit *unit, IniWriter *iw)
iw_entry(iw, "baud-rate", "%d", (int)priv->baudrate);
iw_comment(iw, "Parity type (NONE, ODD, EVEN)");
iw_entry(iw, "parity", "%s", str_3(priv->parity,
0, "NONE",
1, "ODD",
2, "EVEN"));
iw_entry(iw, "parity", cfg_enum3_encode(priv->parity,
0, "NONE",
1, "ODD",
2, "EVEN"));
iw_comment(iw, "Number of stop bits (0.5, 1, 1.5, 2)");
iw_entry(iw, "stop-bits", "%s", str_4(priv->stopbits,
0, "0.5",
1, "1",
2, "1.5",
3, "2"));
iw_entry(iw, "stop-bits", cfg_enum4_encode(priv->stopbits,
0, "0.5",
1, "1",
2, "1.5",
3, "2"));
iw_comment(iw, "Bit order (LSB or MSB first)");
iw_entry(iw, "first-bit", str_2((uint32_t)priv->lsb_first,
0, "MSB",
1, "LSB"));
iw_entry(iw, "first-bit", cfg_enum2_encode((uint32_t) priv->lsb_first,
0, "MSB",
1, "LSB"));
iw_comment(iw, "Word width (7,8,9) - including parity bit if used");
iw_entry(iw, "word-width", "%d", (int)priv->width);
iw_comment(iw, "Enabled lines (RX,TX,RXTX)");
iw_entry(iw, "direction", str_3(priv->direction,
1, "RX",
2, "TX",
3, "RXTX"));
iw_entry(iw, "direction", cfg_enum3_encode(priv->direction,
1, "RX",
2, "TX",
3, "RXTX"));
iw_comment(iw, "Hardware flow control (NONE, RTS, CTS, FULL)");
iw_entry(iw, "hw-flow-control", "%s", str_4(priv->hw_flow_control,
0, "NONE",
1, "RTS",
2, "CTS",
3, "FULL"));
iw_entry(iw, "hw-flow-control", cfg_enum4_encode(priv->hw_flow_control,
0, "NONE",
1, "RTS",
2, "CTS",
3, "FULL"));
iw_cmt_newline(iw);
iw_comment(iw, "Generate serial clock (Y,N)");
-35
View File
@@ -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);
}
-36
View File
@@ -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);
}
+11 -11
View File
@@ -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;
float flt;
uint32_t u32;
float flt;
} x;
unsigned char c;
int exp;
char c;
int32_t exp;
unsigned char flag;
uint8_t flag;
#define FL_MINUS 0x01 /* number is negative */
#define FL_ANY 0x02 /* any digit was readed */
#define FL_OVFL 0x04 /* overflow was */
@@ -178,7 +178,7 @@ avr_strtod (const char * nptr, char ** endptr)
do {
if (i < 3200)
i = (((i << 2) + i) << 1) + c; /* i = 10*i + c */
c = *nptr++ - '0';
c = (char) (*nptr++ - '0');
} while (c <= 9);
if (flag & FL_MEXP)
i = -i;
@@ -189,7 +189,7 @@ avr_strtod (const char * nptr, char ** endptr)
if ((flag & FL_ANY) && endptr)
*endptr = (char *)nptr - 1;
x.flt = __floatunsisf (x.u32); /* manually */
x.flt = (float) __floatunsisf (x.u32); /* manually */
if ((flag & FL_MINUS) && (flag & FL_ANY))
x.flt = -x.flt;
@@ -204,7 +204,7 @@ avr_strtod (const char * nptr, char ** endptr)
for (pwr = 32; pwr; pwr >>= 1) {
for (; exp >= pwr; exp -= pwr) {
union {
unsigned long u32;
uint32_t u32;
float flt;
} y;
y.u32 = (uint32_t) *((float *)nptr);
@@ -213,7 +213,7 @@ avr_strtod (const char * nptr, char ** endptr)
nptr -= sizeof(float);
}
if (!isfinite(x.flt) || x.flt == 0)
errno = ERANGE;
avrlibc_errno = ERANGE;
}
return x.flt;
+19 -18
View File
@@ -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
View File
@@ -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);
}
+7
View File
@@ -0,0 +1,7 @@
//
// Created by MightyPork on 2018/02/23.
//
#include <stdint.h>
volatile int32_t avrlibc_errno = 0;
+36 -25
View File
@@ -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
View File
@@ -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;
-107
View File
@@ -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;
}
-51
View File
@@ -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