123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618 |
- /**
- * @file gpio.c
- * @author chipsea
- * @brief Contains all functions support for gpio and iomux driver
- * @version 0.1
- * @date 2020-11-30
- * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
- * @note
- */
- #include "sdk_config.h"
- #include "log.h"
- #include "mcu.h"
- #include "gpio.h"
- #include "types.h"
- #include "clock.h"
- #include "error.h"
- #include "string.h"
- #include "pwrmgr.h"
- #include "jump_function.h"
- extern uint32_t s_gpio_wakeup_src_group1, s_gpio_wakeup_src_group2;
- enum {
- GPIO_PIN_ASSI_NONE = 0,
- GPIO_PIN_ASSI_OUT,
- GPIO_PIN_ASSI_IN,
- };
- typedef struct {
- bool enable;
- uint8_t pin_state;
- gpioin_Hdl_t posedgeHdl;
- gpioin_Hdl_t negedgeHdl;
-
- }gpioin_Ctx_t;
- typedef struct {
- bool state;
- uint8_t pin_assignments[NUMBER_OF_PINS];
- gpioin_Ctx_t irq_ctx[NUMBER_OF_PINS];
-
- }gpio_Ctx_t;
- typedef struct{
- uint8_t reg_i;
- uint8_t bit_h;
- uint8_t bit_l;
-
- }PULL_TypeDef;
- static gpio_Ctx_t m_gpioCtx = {
- .state = FALSE,
- .pin_assignments = {0,},
- };
- const uint8_t c_gpio_index[GPIO_NUM] = {0,1,2,3,7,9,10,11,14,15,16,17,18,20,23,24,25,26,27,31,32,33,34};
- const PULL_TypeDef c_gpio_pull[GPIO_NUM]=
- {
- {0,2,1}, //p0
- {0,5,4}, //p1
- {0,8,7}, //p2
- {0,11,10},//p3
- {0,23,22},//p7
- {0,29,28},//p9
- {1,2,1}, //p10
- {1,5,4}, //p11
- {1,14,13},//p14
- {1,17,16},//p15
- {1,20,19},//p16
- {1,23,22},//p17
- {1,26,25},//p18
- {2,2,1}, //p20
- {2,11,10},//p23
- {2,14,13},//p24
- {2,17,16},//p25
- {2,20,19},//p26
- {2,23,22},//p27
- {3,5,4}, //p31
- {3,8,7}, //p32
- {3,11,10},//p33
- {3,14,13},//p34
- };
- const signed char retention_reg[GPIO_NUM][2]={
- {0,13},//p0
- {0,14},//p1
- {0,16},//p2
- {0,17},//p3
- {0,19},//p7
- {0,20},//p9
- {1,7},//p10
- {1,8},//p11
- {1,10},//p14
- {1,11},//p15
- {1,28},//p16
- {1,29},//p17
- {2,4},//p18
- {2,5},//p20
- {2,7},//p23
- {2,8},//p24
- {2,25},//p25
- {2,26},//p26
- {2,28},//p27
- {2,29},//p31
- {3,1},//p32
- {3,2},//p33
- {3,23},//p34
- };
- static int hal_gpio_interrupt_disable(GpioPin_t pin)
- {
- subWriteReg(&(AP_GPIO->intmask),pin,pin,1);
- subWriteReg(&(AP_GPIO->inten),pin,pin,0);
- return ERR_NONE;
- }
- static void hal_gpio_wakeup_control(GpioPin_t pin, bit_action_e value)
- {
- if(pin < P32)
- {
- if (value)
- AP_AON->REG_S9 |= BIT(c_gpio_index[pin]);
- else
- AP_AON->REG_S9 &= ~BIT(c_gpio_index[pin]);
- }
- else
- {
- if (value)
- AP_AON->REG_S10 |= BIT(c_gpio_index[pin] - 32);
- else
- AP_AON->REG_S10 &= ~BIT(c_gpio_index[pin] - 32);
- }
- }
- void HalGpioDsControl(GpioPin_t pin, bit_action_e value)
- {
- if(value)
- AP_IOMUX->pad_ps0 |= BIT(pin);
- else
- AP_IOMUX->pad_ps0 &= ~BIT(pin);
- }
- ErrCode_t HalGpioAnalogConfig(GpioPin_t pin, bit_action_e value)
- {
- if((pin < P11) || (pin > P25))
- return ERR_INVALID_PARAM;
- if(value > Bit_ENABLE)
- {
- return ERR_INVALID_DATA;
- }
- if(value)
- {
- HalGpioPupdConfig(pin,GPIO_FLOATING);
- AP_IOMUX->Analog_IO_en |= BIT(pin - P11);
- }
- else
- {
- AP_IOMUX->Analog_IO_en &= ~BIT(pin - P11);
- }
- return ERR_NONE;
- }
- void HalGpioPin2Pin3Control(GpioPin_t pin, uint8_t en)//0:sw,1:other func
- {
- if(en)
- AP_IOMUX->gpio_pad_en |= BIT(pin-2);
- else
- AP_IOMUX->gpio_pad_en &= ~BIT(pin-2);
- }
- static void hal_gpio_retention_enable(GpioPin_t pin,uint8_t en)
- {
- if(en)
- {
- if((pin == P32)||(pin == P33)||(pin == P34))
- {
- AP_AON->PMCTL0 |= BIT(retention_reg[pin][1]);
- }
- else
- {
- AP_AON->IOCTL[retention_reg[pin][0]] |= BIT(retention_reg[pin][1]);
- }
- }
- else
- {
- if((pin == P32)||(pin == P33)||(pin == P34))
- {
- AP_AON->PMCTL0 &= ~BIT(retention_reg[pin][1]);
- }
- else
- {
- AP_AON->IOCTL[retention_reg[pin][0]] &= ~BIT(retention_reg[pin][1]);
- }
- }
- }
- int hal_gpioin_disable(GpioPin_t pin)
- {
- gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
- if (pin > (NUMBER_OF_PINS - 1))
- return ERR_NOT_SUPPORTED;
- p_irq_ctx[pin].enable = FALSE;
- m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_NONE;
- HalGpioPinInit(pin, GPIO_INPUT);
- return hal_gpio_interrupt_disable(pin);
- }
- __ATTR_SECTION_SRAM__ static int hal_gpio_interrupt_enable(GpioPin_t pin, gpio_polarity_e type)
- {
- uint32_t gpio_tmp;
- if (pin >= NUMBER_OF_PINS)
- return ERR_NOT_SUPPORTED;
- gpio_tmp = AP_GPIO->inttype_level;
- gpio_tmp |= (1 << pin); //edge sensitive
- AP_GPIO->inttype_level = gpio_tmp;
- gpio_tmp = AP_GPIO->intmask;
- gpio_tmp &= ~(1 << pin); //unmask interrupt
- AP_GPIO->intmask = gpio_tmp;
- gpio_tmp = AP_GPIO->int_polarity;
- if (type == POL_RISING )
- gpio_tmp |= (1 << pin);
- else
- gpio_tmp &= ~(1 << pin);
- AP_GPIO->int_polarity = gpio_tmp;
- gpio_tmp = AP_GPIO->inten;
- gpio_tmp |= (1 << pin); //enable interrupt
- AP_GPIO->inten = gpio_tmp;
- return ERR_NONE;
- }
- __ATTR_SECTION_SRAM__ static void hal_gpioin_event_pin(GpioPin_t pin, gpio_polarity_e type)
- {
- gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
- if (p_irq_ctx[pin].posedgeHdl && (type == POL_RISING ))
- {
- p_irq_ctx[pin].posedgeHdl(pin,POL_RISING );//LOG("POS\n");
- }
- else if (p_irq_ctx[pin].negedgeHdl && (type == POL_FALLING))
- {
- p_irq_ctx[pin].negedgeHdl(pin,POL_FALLING);//LOG("NEG\n");
- }
- }
- static void hal_gpioin_wakeup_trigger(GpioPin_t pin)
- {
- uint8_t pin_state = (uint8_t)HalGpioGet(pin);
- gpio_polarity_e type = pin_state ? POL_RISING : POL_FALLING;
- if (m_gpioCtx.irq_ctx[pin].pin_state != pin_state)
- hal_gpioin_event_pin(pin, type);
- }
- __ATTR_SECTION_SRAM__ static void hal_gpioin_event(uint32 int_status, uint32 polarity)
- {
- int i;
- gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
- // LOG("GI:%x,%x\n",int_status,polarity);
- for (i = 0; i < NUMBER_OF_PINS; i++)
- {
- if (int_status & (1ul << i))
- {
- gpio_polarity_e type = (polarity & BIT(i)) ? POL_RISING : POL_FALLING;
- hal_gpioin_event_pin((GpioPin_t)i, type);
- //reconfig interrupt
- if (p_irq_ctx[i].posedgeHdl && p_irq_ctx[i].negedgeHdl) //both raise and fall
- {
- type = (type == POL_RISING) ? POL_FALLING : POL_RISING ;
- hal_gpio_interrupt_enable((GpioPin_t)i, type);
- }
- else if (p_irq_ctx[i].posedgeHdl) //raise
- {
- hal_gpio_interrupt_enable((GpioPin_t)i, POL_RISING );
- }
- else if (p_irq_ctx[i].negedgeHdl) //fall
- {
- hal_gpio_interrupt_enable((GpioPin_t)i, POL_FALLING);
- }
- }
- }
- }
- ErrCode_t hal_gpioin_enable(GpioPin_t pin)
- {
- gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
- gpio_polarity_e type = POL_FALLING;
- uint32 pinVal = 0;
- if (p_irq_ctx[pin].posedgeHdl == NULL && p_irq_ctx[pin].negedgeHdl == NULL)
- return ERR_NOT_REGISTED;
- m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_IN;
- p_irq_ctx[pin].enable = TRUE;
- HalGpioPinInit(pin, GPIO_INPUT);
- //HalGpioPupdConfig(pin, PULL_DOWN); //??need disccuss
- if (p_irq_ctx[pin].posedgeHdl && p_irq_ctx[pin].negedgeHdl) //both raise and fall
- {
- pinVal = HalGpioGet(pin);
- type = pinVal ? POL_FALLING : POL_RISING ;
- }
- else if (p_irq_ctx[pin].posedgeHdl) //raise
- {
- type = POL_RISING ;
- }
- else if (p_irq_ctx[pin].negedgeHdl) //fall
- {
- type = POL_FALLING;
- }
- hal_gpio_interrupt_enable(pin, type);
- return ERR_NONE;
- }
- void GpioSleepHandler(void)
- {
- int i;
- gpio_polarity_e pol;
- uint8_t ic_ver = get_ic_version();
-
- for (i = 0; i < NUMBER_OF_PINS; i++)
- {
- //config wakeup
- if (m_gpioCtx.pin_assignments[i] == GPIO_PIN_ASSI_OUT)
- {
- hal_gpio_retention_enable((GpioPin_t)i,Bit_ENABLE);
- }
- if (m_gpioCtx.pin_assignments[i] == GPIO_PIN_ASSI_IN)
- {
-
- if(ic_ver != VERSION_0100 && ((i==P16)||(i==P17)))
- {
- HalGpioAnalogConfig((GpioPin_t)i,Bit_DISABLE);
- subWriteReg(&(AP_AON->PMCTL2_0),6,6,0x01);
- WaitUs(50);
- pol = HalGpioGet((GpioPin_t)i) ? POL_FALLING : POL_RISING ;
- subWriteReg(&(AP_AON->PMCTL2_0),6,6,0x00);
- }
- else
- {
- pol = HalGpioGet((GpioPin_t)i) ? POL_FALLING : POL_RISING ;
- }
-
- HalGpioWkupConfig((GpioPin_t)i, pol);
- m_gpioCtx.irq_ctx[i].pin_state = HalGpioGet((GpioPin_t)i);
- }
- }
- }
- void GpioWakeupHandler(void)
- {
- int i;
- uint8_t ic_ver = get_ic_version();
-
- NVIC_SetPriority(GPIO_IRQn, IRQ_PRIO_HAL);
- NVIC_EnableIRQ(GPIO_IRQn);
- for (i = 0; i < NUMBER_OF_PINS; i++)
- {
- if( ((i == GPIO_P02) || (i == GPIO_P03)) && (m_gpioCtx.pin_assignments[i] != GPIO_PIN_ASSI_NONE) )
- {
- HalGpioPin2Pin3Control((GpioPin_t)i,1);
- }
- if(ic_ver != VERSION_0100 && ((i==P16)||(i==P17)))
- {
- HalGpioAnalogConfig((GpioPin_t)i,Bit_DISABLE);
- }
- if (m_gpioCtx.pin_assignments[i] == GPIO_PIN_ASSI_OUT)
- {
- bool pol = HalGpioGet((GpioPin_t)i);
- HalGpioSet((GpioPin_t)i, (bit_action_e)pol);
- HalGpioPinInit((GpioPin_t)i, GPIO_OUTPUT);
- hal_gpio_retention_enable((GpioPin_t)i, Bit_DISABLE);
- }
- }
- for (i = 0; i < NUMBER_OF_PINS; i++)
- {
- if (m_gpioCtx.irq_ctx[i].enable)
- {
- hal_gpioin_enable((GpioPin_t)i); //resume gpio irq
- hal_gpioin_wakeup_trigger((GpioPin_t)i);//trigger gpio irq manually
- }
- }
- }
- __ATTR_SECTION_SRAM__ void HalGpioIRQHandler(void)
- {
- uint32 polarity = AP_GPIO->int_polarity;
- uint32 st = AP_GPIO->int_status;
- AP_GPIO->porta_eoi = st;//clear interrupt
- hal_gpioin_event(st, polarity);
- }
- bool HalBootPinStatusGet(void)
- {
- bool status;
- uint32_t config;
- config = *(volatile unsigned int *)0x4000f058;
- status = (config & 0x40)>> 6;
- return status;
- }
- void HalGpioSet(GpioPin_t pin, bit_action_e bitVal)
- {
- if(bitVal)
- AP_GPIO->swporta_dr |= BIT(pin);
- else
- AP_GPIO->swporta_dr &= ~BIT(pin);
- }
- bool HalGpioGet(GpioPin_t pin)
- {
- uint32_t r;
- if(pin >= GPIO_NUM )
- {
- return ERR_NOT_SUPPORTED;
- }
- if(AP_GPIO->swporta_ddr & BIT(pin))
- {
- r = AP_GPIO->swporta_dr;
- }
- else
- {
- r = AP_GPIO->ext_porta;
- }
- return (int)((r>> pin) &1);
- }
- ErrCode_t HalGpioPupdConfig(GpioPin_t pin, gpio_pupd_e type)
- {
- if(pin >= GPIO_NUM || type > GPIO_PULL_DOWN)
- {
- return ERR_NOT_SUPPORTED;
- }
- uint8_t i = c_gpio_pull[pin].reg_i;
- uint8_t h = c_gpio_pull[pin].bit_h;
- uint8_t l = c_gpio_pull[pin].bit_l;
- if(pin < P31)
- subWriteReg(&(AP_AON->IOCTL[i]),h,l,type);
- else
- subWriteReg(&(AP_AON->PMCTL0),h,l,type);
- return ERR_NONE;
- }
- ErrCode_t HalGpioFmuxEnable(GpioPin_t pin, bit_action_e value)
- {
- if(pin >= GPIO_NUM || value > Bit_ENABLE)
- {
- return ERR_NOT_SUPPORTED;
- }
- if(value)
- {
- AP_IOMUX->full_mux0_en |= BIT(pin);
- }
- else
- {
- AP_IOMUX->full_mux0_en &= ~BIT(pin);
- }
- return ERR_NONE;
- }
- ErrCode_t HalGpioFmuxConfig(GpioPin_t pin, gpio_fmux_e type)
- {
- uint8_t h = 0, l = 0;
- uint32_t reg_index;
- uint32_t bit_index;
- if( (pin >= GPIO_NUM) || (type > FMUX_ANT_SEL_2) )
- {
- return ERR_NOT_SUPPORTED;
- }
- reg_index = pin / 4;
- bit_index = pin % 4;
- l = 8 * bit_index;
- h = l + 5;
- subWriteReg(&(AP_IOMUX->gpio_sel[reg_index]),h,l,type);
- HalGpioFmuxEnable(pin, Bit_ENABLE);
- return ERR_NONE;
- }
- ErrCode_t HalGpioWkupConfig(GpioPin_t pin, gpio_polarity_e type)
- {
- if(pin >= GPIO_NUM || type > POL_RISING)
- {
- return ERR_NOT_SUPPORTED;
- }
- uint8_t i = c_gpio_pull[pin].reg_i;
- uint8_t p = c_gpio_pull[pin].bit_l-1;
- if (m_gpioCtx.pin_assignments[pin] != GPIO_PIN_ASSI_IN)
- return ERR_INVALID_STATE;
-
- AP_GPIO->inttype_level |= BIT(pin);//edge sensitive
- if(pin < P31)
- {
- if(POL_FALLING == type)
- AP_AON->IOCTL[i] |= BIT(p);
- else
- AP_AON->IOCTL[i] &= ~BIT(p);
- }
- else
- {
- if(POL_FALLING == type)
- AP_AON->PMCTL0 |= BIT(p);
- else
- AP_AON->PMCTL0 &= ~BIT(p);
- }
- hal_gpio_wakeup_control(pin,Bit_ENABLE);//enable wakeup function
- return ERR_NONE;
- }
- ErrCode_t HalGpioRegister(GpioPin_t pin, gpioin_Hdl_t posedgeHdl, gpioin_Hdl_t negedgeHdl)
- {
- ErrCode_t ret;
- gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
- if(pin >= GPIO_NUM )
- {
- return ERR_NOT_SUPPORTED;
- }
- hal_gpioin_disable(pin);
- p_irq_ctx[pin].posedgeHdl = posedgeHdl;
- p_irq_ctx[pin].negedgeHdl = negedgeHdl;
- ret = hal_gpioin_enable(pin);
- JUMP_FUNCTION(V16_IRQ_HANDLER) = (uint32_t)&HalGpioIRQHandler;
-
- if (ret != ERR_NONE)
- hal_gpioin_disable(pin);
- return ret;
- }
- ErrCode_t HalGpioUnregister(GpioPin_t pin)
- {
- gpioin_Ctx_t* p_irq_ctx = &(m_gpioCtx.irq_ctx[0]);
- if (pin >= GPIO_NUM)
- return ERR_NOT_SUPPORTED;
- hal_gpioin_disable(pin);
- p_irq_ctx[pin].negedgeHdl = NULL;
- p_irq_ctx[pin].posedgeHdl = NULL;
- return ERR_NONE;
- }
- ErrCode_t HalGpioInit(void)
- {
- if (m_gpioCtx.state)
- return ERR_INVALID_STATE;
- memset(&m_gpioCtx, 0, sizeof(m_gpioCtx));
- m_gpioCtx.state = TRUE;
- //disable all channel irq,unmask all channel
- AP_GPIO->inten = 0;
- AP_GPIO->intmask = 0;
- //disable all wakeup pin
- AP_WAKEUP->io_wu_mask_31_0 = 0;
- AP_WAKEUP->io_wu_mask_34_32 = 0;
- NVIC_SetPriority(GPIO_IRQn, IRQ_PRIO_HAL);
- NVIC_EnableIRQ(GPIO_IRQn);
- hal_pwrmgr_register(MOD_GPIO, GpioSleepHandler, GpioWakeupHandler);
- return ERR_NONE;
- }
- ErrCode_t HalGpioPinInit(GpioPin_t pin, gpio_dir_t type)
- {
- if(pin >= GPIO_NUM || type > GPIO_OUTPUT)
- {
- return ERR_NOT_SUPPORTED;
- }
- HalGpioFmuxEnable(pin,Bit_DISABLE);
- if((pin == P2) || (pin == P3))
- HalGpioPin2Pin3Control(pin,1);
- HalGpioAnalogConfig(pin,Bit_DISABLE);
- if(type == GPIO_OUTPUT)
- {
- AP_GPIO->swporta_ddr |= BIT(pin);
- m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_OUT;
- }
- else
- {
- AP_GPIO->swporta_ddr &= ~BIT(pin);
- m_gpioCtx.pin_assignments[pin] = GPIO_PIN_ASSI_IN;
- }
- return ERR_NONE;
- }
|