| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- /*
- * Copyright (c) 2022 OpenLuat & AirM2M
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- #include "user.h"
- typedef struct
- {
- volatile GPIO_TypeDef *RegBase;
- const int32_t IrqLine;
- uint16_t ODBitMap;
- }GPIO_ResourceStruct;
- typedef struct
- {
- CBFuncEx_t CB;
- void *pParam;
- }EXTI_CBStruct;
- typedef struct
- {
- EXTI_CBStruct ExtiCB[GPIO_MAX];
- }GPIO_CtrlStruct;
- static GPIO_CtrlStruct prvGPIO;
- static GPIO_ResourceStruct prvGPIO_Resource[6] =
- {
- {
- GPIOA,
- EXTI0_IRQn,
- 0,
- },
- {
- GPIOB,
- EXTI1_IRQn,
- 0,
- },
- {
- GPIOC,
- EXTI2_IRQn,
- 0,
- },
- {
- GPIOD,
- EXTI3_IRQn,
- 0,
- },
- {
- GPIOE,
- EXTI4_IRQn,
- 0,
- },
- {
- GPIOF,
- EXTI5_IRQn,
- 0,
- },
- };
- static int32_t GPIO_IrqDummyCB(void *pData, void *pParam)
- {
- // DBG("%d", pData);
- return 0;
- }
- static void __FUNC_IN_RAM__ GPIO_IrqHandle(int32_t IrqLine, void *pData)
- {
- volatile uint32_t Port = (uint32_t)pData;
- volatile uint32_t Sn, i, Pin;
- CBFuncEx_t CB;
- if (GPIO->INTP_TYPE_STA[Port].INTP_STA)
- {
- Sn = GPIO->INTP_TYPE_STA[Port].INTP_STA;
- GPIO->INTP_TYPE_STA[Port].INTP_STA = 0xffff;
- Port = (Port << 4);
- for(i = 0; i < 16; i++)
- {
- if (Sn & (1 << i))
- {
- Pin = Port+i;
- //DBG("%d,%x,%x", Pin, prvGPIO.ExtiCB[Pin].CB, prvGPIO.ExtiCB[Pin].pParam);
- prvGPIO.ExtiCB[Pin].CB((void *)Pin, prvGPIO.ExtiCB[Pin].pParam);
- }
- }
- }
- ISR_Clear(IrqLine);
- }
- void GPIO_GlobalInit(CBFuncEx_t Fun)
- {
- uint32_t i;
- if (Fun)
- {
- for(i = 0; i < GPIO_MAX; i++)
- {
- prvGPIO.ExtiCB[i].CB = Fun;
- }
- }
- else
- {
- for(i = 0; i < GPIO_MAX; i++)
- {
- prvGPIO.ExtiCB[i].CB = GPIO_IrqDummyCB;
- }
- }
- for(i = 0; i < 6; i++)
- {
- GPIO->INTP_TYPE_STA[i].INTP_TYPE = 0;
- GPIO->INTP_TYPE_STA[i].INTP_STA = 0xffff;
- #ifdef __BUILD_OS__
- ISR_SetPriority(prvGPIO_Resource[i].IrqLine, IRQ_MAX_PRIORITY + 1);
- #else
- ISR_SetPriority(prvGPIO_Resource[i].IrqLine, 3);
- #endif
- ISR_SetHandler(prvGPIO_Resource[i].IrqLine, GPIO_IrqHandle, (void *)i);
- ISR_OnOff(prvGPIO_Resource[i].IrqLine, 1);
- }
- }
- void __FUNC_IN_RAM__ GPIO_Config(uint32_t Pin, uint8_t IsInput, uint8_t InitValue)
- {
- uint8_t Port = (Pin >> 4);
- uint8_t orgPin = Pin;
- Pin = 1 << (Pin & 0x0000000f);
- GPIO_Iomux(orgPin, 1);
- if (IsInput)
- {
- prvGPIO_Resource[Port].RegBase->OEN |= Pin;
- }
- else
- {
- prvGPIO_Resource[Port].RegBase->BSRR |= InitValue?Pin:(Pin << 16);
- prvGPIO_Resource[Port].RegBase->OEN &= ~Pin;
- }
- prvGPIO_Resource[Port].ODBitMap &= ~Pin;
- }
- void __FUNC_IN_RAM__ GPIO_ODConfig(uint32_t Pin, uint8_t InitValue)
- {
- uint8_t Port = (Pin >> 4);
- uint8_t orgPin = Pin;
- Pin = 1 << (Pin & 0x0000000f);
- GPIO_Iomux(orgPin, 1);
- if (InitValue)
- {
- prvGPIO_Resource[Port].RegBase->OEN |= Pin;
- }
- else
- {
- prvGPIO_Resource[Port].RegBase->BSRR |= (Pin << 16);
- prvGPIO_Resource[Port].RegBase->OEN &= ~Pin;
- }
- prvGPIO_Resource[Port].ODBitMap |= Pin;
- }
- void __FUNC_IN_RAM__ GPIO_PullConfig(uint32_t Pin, uint8_t IsPull, uint8_t IsUp)
- {
- uint8_t Port = (Pin >> 4);
- Pin = 1 << (Pin & 0x0000000f);
- if (IsPull && IsUp)
- {
- prvGPIO_Resource[Port].RegBase->PUE |= Pin;
- }
- else
- {
- prvGPIO_Resource[Port].RegBase->PUE &= ~Pin;
- }
- }
- void GPIO_ExtiConfig(uint32_t Pin, uint8_t IsLevel, uint8_t IsRiseHigh, uint8_t IsFallLow)
- {
- uint8_t Port = (Pin >> 4);
- uint32_t Type = 0;
- uint32_t Mask = ~(0x03 << ((Pin & 0x0000000f) * 2));
- if (!IsLevel)
- {
- if (IsRiseHigh && IsFallLow)
- {
- Type = 0x03 << ((Pin & 0x0000000f) * 2);
- }
- else if (IsFallLow)
- {
- Type = 0x02 << ((Pin & 0x0000000f) * 2);
- }
- else if (IsRiseHigh)
- {
- Type = 0x01 << ((Pin & 0x0000000f) * 2);
- }
- }
- GPIO->INTP_TYPE_STA[Port].INTP_TYPE = (GPIO->INTP_TYPE_STA[Port].INTP_TYPE & Mask) | Type;
- uint32_t Sn = Pin / 32;
- uint32_t Pos = 1 << (Pin % 32);
- if (!IsLevel)
- {
- switch(Sn)
- {
- case 0:
- GPIO->WAKE_P0_EN |= Pos;
- break;
- case 1:
- GPIO->WAKE_P1_EN |= Pos;
- break;
- case 2:
- GPIO->WAKE_P2_EN |= Pos;
- break;
- }
- }
- else
- {
- switch(Sn)
- {
- case 0:
- GPIO->WAKE_P0_EN &= ~Pos;
- break;
- case 1:
- GPIO->WAKE_P1_EN &= ~Pos;
- break;
- case 2:
- GPIO->WAKE_P2_EN &= ~Pos;
- break;
- }
- }
- }
- void GPIO_ExtiSetCB(uint32_t Pin, CBFuncEx_t CB, void *pParam)
- {
- if (CB)
- {
- prvGPIO.ExtiCB[Pin].CB = CB;
- }
- else
- {
- prvGPIO.ExtiCB[Pin].CB = GPIO_IrqDummyCB;
- }
- prvGPIO.ExtiCB[Pin].pParam = pParam;
- }
- void __FUNC_IN_RAM__ GPIO_Iomux(uint32_t Pin, uint32_t Function)
- {
- uint8_t Port = (Pin >> 4);
- uint32_t Mask = ~(0x03 << ((Pin & 0x0000000f) * 2));
- Function = Function << ((Pin & 0x0000000f) * 2);
- GPIO->ALT[Port] = (GPIO->ALT[Port] & Mask) | Function;
- }
- void __FUNC_IN_RAM__ GPIO_Output(uint32_t Pin, uint8_t Level)
- {
- uint8_t Port = (Pin >> 4);
- Pin = 1 << (Pin & 0x0000000f);
- if (prvGPIO_Resource[Port].ODBitMap & Pin)
- {
- if (Level)
- {
- prvGPIO_Resource[Port].RegBase->OEN |= Pin;
- }
- else
- {
- prvGPIO_Resource[Port].RegBase->BSRR |= (Pin << 16);
- prvGPIO_Resource[Port].RegBase->OEN &= ~Pin;
- }
- }
- else
- {
- prvGPIO_Resource[Port].RegBase->BSRR |= Level?Pin:(Pin << 16);
- }
- // DBG("%d, %x, %x, %x",Port, Pin, prvGPIO_Resource[Port].RegBase, prvGPIO_Resource[Port].RegBase->IODR);
- }
- uint8_t __FUNC_IN_RAM__ GPIO_Input(uint32_t Pin)
- {
- uint8_t Port = (Pin >> 4);
- Pin = 1 << (Pin & 0x0000000f);
- return (prvGPIO_Resource[Port].RegBase->IODR & (Pin << 16))?1:0;
- }
- void __FUNC_IN_RAM__ GPIO_OutputMulti(uint32_t Port, uint32_t Pins, uint32_t Level)
- {
- prvGPIO_Resource[Port].RegBase->BSRR |= Level?Pins:(Pins << 16);
- }
- uint32_t __FUNC_IN_RAM__ GPIO_InputMulti(uint32_t Port)
- {
- return (prvGPIO_Resource[Port].RegBase->IODR >> 16);
- }
|