| /****************************************************************************** |
| |
| Copyright (c) 2006-2015 Lantiq Deutschland GmbH |
| Copyright (c) 2015 Lantiq Beteiligungs-GmbH & Co.KG |
| Copyright 2018, Intel Corporation. |
| |
| For licensing information, see the file 'LICENSE' in the root folder of |
| this software module. |
| |
| ******************************************************************************/ |
| |
| /** |
| \file dxs_gpio.c |
| Implementation of GPIO functions. |
| */ |
| |
| /* ========================================================================== */ |
| /* Includes */ |
| /* ========================================================================== */ |
| #include "dxs_config.h" |
| |
| #ifdef DXS_FEAT_GPIO |
| |
| #include "dxs.h" |
| #include "dxs_fw_cmd.h" |
| #include "dxs_errno.h" |
| #include "dxs_error.h" |
| |
| /* ========================================================================== */ |
| /* Macro definitions */ |
| /* ========================================================================== */ |
| |
| /* ========================================================================== */ |
| /* Type definitions */ |
| /* ========================================================================== */ |
| /** Data structure for GPIO configuration firmware command */ |
| typedef struct |
| { |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| CMD_HEAD_BE; |
| /** Reserved */ |
| uint32_t Res02 : 4; |
| /** Enable GPIO Pull-up Resistor */ |
| uint32_t GPIO_PULL_UP : 4; |
| /** Reserved */ |
| uint32_t Res03 : 4; |
| /** Direction of GPIO Bits */ |
| uint32_t GPIO_DIR : 4; |
| /** Reserved */ |
| uint32_t Res04 : 16; |
| #else |
| CMD_HEAD_LE; |
| /** Reserved */ |
| uint32_t Res04 : 16; |
| /** Direction of GPIO Bits */ |
| uint32_t GPIO_DIR : 4; |
| /** Reserved */ |
| uint32_t Res03 : 4; |
| /** Enable GPIO Pull-up Resistor */ |
| uint32_t GPIO_PULL_UP : 4; |
| /** Reserved */ |
| uint32_t Res02 : 4; |
| #endif |
| } __attribute__ ((packed)) DXS_FW_GPIO_Config_t; |
| #define DXS_FW_GPIO_Config_ECMD 2 |
| #define DXS_FW_GPIO_Config_LENGTH 4 |
| |
| /** Data structure for GPIO control firmware command */ |
| typedef struct |
| { |
| #if __BYTE_ORDER == __BIG_ENDIAN |
| CMD_HEAD_BE; |
| /** Reserved */ |
| uint32_t Res02 : 4; |
| /** Write Mask for GPIO */ |
| uint32_t GPIO_WR_MSK : 4; |
| /** Reserved */ |
| uint32_t Res03 : 4; |
| /** Value of GPIO Bits */ |
| uint32_t GPIO_VAL : 4; |
| /** Reserved */ |
| uint32_t Res04 : 16; |
| #else |
| CMD_HEAD_LE; |
| /** Reserved */ |
| uint32_t Res04 : 16; |
| /** Value of GPIO Bits */ |
| uint32_t GPIO_VAL : 4; |
| /** Reserved */ |
| uint32_t Res03 : 4; |
| /** Write Mask for GPIO */ |
| uint32_t GPIO_WR_MSK : 4; |
| /** Reserved */ |
| uint32_t Res02 : 4; |
| #endif |
| } __attribute__ ((packed)) DXS_FW_GPIO_Data_t; |
| #define DXS_FW_GPIO_Data_ECMD 3 |
| #define DXS_FW_GPIO_Data_LENGTH 4 |
| |
| /** GPIO device resource structure */ |
| typedef struct |
| { |
| /** status flag */ |
| uint32_t flag; |
| #define GPIO_DEV_INITIALIZED 0x00000001 |
| #define GPIO_CTRL_CONFIGURED 0x80000000 |
| /** DXS_FW_GPIO_Config command */ |
| DXS_FW_GPIO_Config_t cfg; |
| /** DXS_FW_GPIO_Data command */ |
| DXS_FW_GPIO_Data_t data; |
| } DXS_GPIO_Dev_Resource_t; |
| |
| /* ========================================================================== */ |
| /* Global variables */ |
| /* ========================================================================== */ |
| static DXS_GPIO_Dev_Resource_t gpio_devs[DXS_MAX_DEVICES] = {0}; |
| |
| /* ========================================================================== */ |
| /* Function prototypes */ |
| /* ========================================================================== */ |
| |
| /* ========================================================================== */ |
| /* Function implementation */ |
| /* ========================================================================== */ |
| /** |
| Function to initialize GPIO device resource |
| |
| \param devnum - device number |
| |
| */ |
| void *DXS_GPIO_DevInit(uint8_t devnum) |
| { |
| DXS_GPIO_Dev_Resource_t *p; |
| |
| if (devnum >= DXS_MAX_DEVICES) |
| return (void *)NULL; |
| |
| p = &gpio_devs[devnum]; |
| |
| p->flag = 0; |
| |
| p->cfg.CMD = CMD_EOP; |
| p->cfg.MOD = MOD_EOP_GPIO; |
| p->cfg.ECMD = DXS_FW_GPIO_Config_ECMD; |
| p->cfg.LENGTH = DXS_FW_GPIO_Config_LENGTH; |
| |
| p->data.CMD = CMD_EOP; |
| p->data.MOD = MOD_EOP_GPIO; |
| p->data.ECMD = DXS_FW_GPIO_Data_ECMD; |
| p->data.LENGTH = DXS_FW_GPIO_Data_LENGTH; |
| |
| p->flag |= GPIO_DEV_INITIALIZED; |
| |
| return (void *)p; |
| } |
| |
| /** |
| Function to configure GPIO |
| |
| \param pDev - pointer to DXS device structure |
| \param pGpioConf - pointer to GPIO config structure |
| |
| \return |
| - DXS_status_t |
| */ |
| int32_t DXS_GPIO_Config(DXS_DEVICE_t *pDev, DXS_GpioConfig_t *pGpioConf) |
| { |
| int32_t err = DXS_statusOk; |
| DXS_GPIO_Dev_Resource_t *p; |
| uint8_t new_gpio_PU, new_gpio_dir, param_check; |
| |
| if (pDev == NULL || pGpioConf == NULL) |
| { |
| DXS_RETURN(DXS_statusInvalidParam); |
| } |
| p = (DXS_GPIO_Dev_Resource_t *)pDev->gpio; |
| |
| if (!(p->flag & GPIO_DEV_INITIALIZED)) |
| { |
| DXS_RETURN(DXS_statusNotInitResource); |
| } |
| |
| param_check = (pGpioConf->gpio0_PU | pGpioConf->gpio1_PU | |
| pGpioConf->gpio2_PU | pGpioConf->gpio3_PU | |
| pGpioConf->gpio0_DIR | pGpioConf->gpio1_DIR | |
| pGpioConf->gpio2_DIR | pGpioConf->gpio3_DIR); |
| if (param_check > 1) |
| { |
| DXS_RETURN(DXS_statusParamsOutRange); |
| } |
| |
| if (!(p->flag & GPIO_CTRL_CONFIGURED)) |
| { |
| /* read configuration from the device */ |
| err = DXS_CmdRead(pDev, (uint32_t *)&p->cfg, (uint32_t *)&p->cfg); |
| if (err) |
| { |
| DXS_RETURN(err); |
| } |
| } |
| |
| /* Set the parameters */ |
| new_gpio_PU = 0xF & (pGpioConf->gpio0_PU | (pGpioConf->gpio1_PU << 1) | |
| (pGpioConf->gpio2_PU << 2) | (pGpioConf->gpio3_PU << 3)); |
| new_gpio_dir = 0xF & (pGpioConf->gpio0_DIR | (pGpioConf->gpio1_DIR << 1) | |
| (pGpioConf->gpio2_DIR << 2) | (pGpioConf->gpio3_DIR << 3)); |
| |
| if (new_gpio_PU != p->cfg.GPIO_PULL_UP || new_gpio_dir != p->cfg.GPIO_DIR) |
| { |
| /* write new values */ |
| p->cfg.GPIO_PULL_UP = new_gpio_PU; |
| p->cfg.GPIO_DIR = new_gpio_dir; |
| err = CmdWrite(pDev, (uint32_t *)&p->cfg); |
| if (err) |
| { |
| DXS_RETURN(err); |
| } |
| } |
| |
| p->flag |= GPIO_CTRL_CONFIGURED; |
| |
| DXS_RETURN(err); |
| } |
| |
| /** |
| Function DXS_GPIO_Write |
| |
| \param pDev - pointer to DXS device structure |
| \param pin - pin number |
| \param val - value |
| |
| \return |
| - DXS_status_t |
| */ |
| int32_t DXS_GPIO_Write(DXS_DEVICE_t *pDev, uint8_t pin, uint8_t val) |
| { |
| int32_t err = DXS_statusOk; |
| DXS_GPIO_Dev_Resource_t *p; |
| uint8_t pin_mask; |
| |
| if (pDev == NULL) |
| { |
| DXS_RETURN(DXS_statusInvalidParam); |
| } |
| p = (DXS_GPIO_Dev_Resource_t *)pDev->gpio; |
| |
| if (!(p->flag & GPIO_DEV_INITIALIZED)) |
| { |
| DXS_RETURN(DXS_statusNotInitResource); |
| } |
| |
| if (!(p->flag & GPIO_CTRL_CONFIGURED)) |
| { |
| /* GPIO port not configured yet */ |
| DXS_RETURN(DXS_statusGpioNotConfigured); |
| } |
| |
| pin_mask = 1 << pin; |
| /* If the specified pin is configured as input - return error */ |
| if (p->cfg.GPIO_DIR & pin_mask) |
| { |
| DXS_RETURN(DXS_statusGpioWriteAccessIgnored); |
| } |
| |
| /* Set the parameters */ |
| p->data.GPIO_WR_MSK = ~pin_mask; |
| if (val) |
| p->data.GPIO_VAL = 0xF; |
| else |
| p->data.GPIO_VAL = 0; |
| |
| /* write new values */ |
| err = CmdWrite(pDev, (uint32_t *)&p->data); |
| |
| DXS_RETURN(err); |
| } |
| |
| /** |
| Function DXS_GPIO_Read |
| |
| \param pDev - pointer to DXS device structure |
| \param pin - pin number |
| \param pVal - pointer to value |
| |
| \return |
| - DXS_status_t |
| */ |
| int32_t DXS_GPIO_Read(DXS_DEVICE_t *pDev, uint8_t pin, uint8_t *pVal) |
| { |
| int32_t err = DXS_statusOk; |
| DXS_GPIO_Dev_Resource_t *p; |
| |
| if (pDev == NULL) |
| { |
| DXS_RETURN(DXS_statusInvalidParam); |
| } |
| p = (DXS_GPIO_Dev_Resource_t *)pDev->gpio; |
| |
| if (!(p->flag & GPIO_DEV_INITIALIZED)) |
| { |
| DXS_RETURN(DXS_statusNotInitResource); |
| } |
| |
| if (!(p->flag & GPIO_CTRL_CONFIGURED)) |
| { |
| /* GPIO port not configured yet */ |
| DXS_RETURN(DXS_statusGpioNotConfigured); |
| } |
| |
| err = DXS_CmdRead(pDev, (uint32_t *)&p->data, (uint32_t *)&p->data); |
| if (err) |
| { |
| DXS_RETURN(err); |
| } |
| |
| /* Set the parameters */ |
| if (p->data.GPIO_VAL & (1 << pin)) |
| *pVal = 1; |
| else |
| *pVal = 0; |
| |
| DXS_RETURN(err); |
| } |
| #endif /* DXS_FEAT_GPIO */ |