/*------------------------------------------------------------------------------ -- This file is a part of the libuc, microcontroler library -- Copyright (C) 2012, Alexis Jeandet -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------- -- Author : Alexis Jeandet -- Mail : alexis.jeandet@gmail.com -------------------------------------------------------------------------------*/ #include //#include #include typedef struct { __IO uint32_t FIODIR; /**< FIO direction register */ uint32_t RESERVED0[3]; /**< Reserved */ __IO uint32_t FIOMASK; /**< FIO mask register */ __IO uint32_t FIOPIN; /**< FIO pin register */ __IO uint32_t FIOSET; /**< FIO set register */ __O uint32_t FIOCLR; /**< FIO clear register */ } GPIO_TypeDef; #define GPIOGETPORT(gpio) ((GPIO_TypeDef*)(((((uint32_t)gpio) & (uint32_t)0x0000FF00)*(uint32_t)2) + (uint32_t)LPC_GPIO_BASE)) #define GPIOPORTNUM(gpio) (((uint32_t)(gpio) & (uint32_t)0x0000FF00)>>(uint32_t)8) #define GPIOGETPINMODE(gpio) ((GPIOPORTNUM(gpio)*8) + (LPC_PINCON_BASE+0x40)) #define GPIOGETPINMODE_OD(gpio) ((GPIOPORTNUM(gpio)*4) + (LPC_PINCON_BASE+0x68)) gpio_t gpioopen(uint32_t gpio) { gpio &= -1^GPIOSPEEDMASK; gpio |= gpiolowspeed; gpio &= -1^GPIODIRMASK; gpio |= gpioindir; gpio &= -1^GPIOOUTTYPEMASK; gpio |= gpiopushpulltype; gpio &= -1^GPIOPULLTYPEMASK; gpio |= gpionopulltype; gpiosetconfig(&gpio); return gpio; } void gpioclose(gpio_t gpio) { } void gpiosetconfig(gpio_t* gpio) { gpiosetdir(gpio, (*gpio & GPIODIRMASK)); gpiosetspeed(gpio, (*gpio & GPIOSPEEDMASK)); gpiosetouttype(gpio, (*gpio & GPIOOUTTYPEMASK)); gpiosetpulltype(gpio, (*gpio & GPIOPULLTYPEMASK)); } extern void gpiosetspeed(gpio_t* gpio,gpiospeed_t speed) { /*no speed option on lpc17xx*/ } void gpiosetdir(gpio_t* gpio,gpiodir_t dir) { GPIO_TypeDef* GPIOx = GPIOGETPORT((*gpio)); switch(dir) { case gpiooutdir: if((*gpio & 0xFF)==0xFF) { GPIOx->FIODIR = -1; } else { GPIOx->FIODIR |= 1<<(*gpio & 0xFF); } *gpio &= ~GPIODIRMASK; *gpio |= gpiooutdir; break; case gpioaf: /*No af mode on lpc17xx*/ //*gpio &= ~GPIODIRMASK; //*gpio |= gpioaf; break; case gpioan: /*No an mode on lpc17xx*/ /**gpio &= ~GPIODIRMASK; *gpio |= gpioan;*/ break; default : if((*gpio & 0xFF)==0xFF) { GPIOx->FIODIR = 0; } else { GPIOx->FIODIR &= ~(1<<(*gpio & 0xFF)); } *gpio &= ~GPIODIRMASK; *gpio |= gpioindir; break; } } void gpiosetouttype(gpio_t* gpio, gpioouttype_t outtype) { GPIO_TypeDef* GPIOx = GPIOGETPORT((*gpio)); if(outtype == gpioopendraintype) { if((*gpio & 0xFF)==0xFF) { GPIOGETPINMODE_OD(gpio) =-1; for(int i=0;i<16;i++) { *GPIOGETPINMODE(*gpio) &= ~(3<<((*gpio & 0xFF)*2)); *(GPIOGETPINMODE(*gpio)+4) &= ~(3<<((*gpio & 0xFF)*2)); } } else { //GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)(*gpio & 0xFF))); //GPIOx->OTYPER |= (uint16_t)(GPIO_OType_OD<<((uint16_t)(*gpio & 0xFF))); } *gpio &= ~GPIOOUTTYPEMASK; *gpio |= gpioopendraintype; } else { if((*gpio & 0xFF)==0xFF) { for(int i=0;i<16;i++) { //GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)i)); //GPIOx->OTYPER |= (uint16_t)(GPIO_OType_PP<<((uint16_t)i)); } } else { //GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)(*gpio & 0xFF))); //GPIOx->OTYPER |= (uint16_t)(GPIO_OType_PP<<((uint16_t)(*gpio & 0xFF))); } *gpio &= ~GPIOOUTTYPEMASK; *gpio |= gpiopushpulltype; } } void gpiosetpulltype(gpio_t* gpio,gpiopulltype_t pulltype) { //GPIO_TypeDef* GPIOx = GPIOGETPORT(*gpio); switch(pulltype) { case gpiopulluptype: if((*gpio & 0xFF)==0xFF) { for(int i=0;i<16;i++) { //GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)i * 2)); //GPIOx->PUPDR |= (GPIO_PuPd_UP << (i * 2)); } } else { //GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)(*gpio & 0xFF) * 2)); //GPIOx->PUPDR |= (GPIO_PuPd_UP << ((*gpio & 0xFF) * 2)); } *gpio &= ~GPIOPULLTYPEMASK; *gpio |= gpiopulluptype; break; case gpiopulldowntype: if((*gpio & 0xFF)==0xFF) { for(int i=0;i<16;i++) { //GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)i * 2)); //GPIOx->PUPDR |= (GPIO_PuPd_DOWN << (i * 2)); } } else { //GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)(*gpio & 0xFF) * 2)); //GPIOx->PUPDR |= (GPIO_PuPd_DOWN << ((*gpio & 0xFF) * 2)); } *gpio &= ~GPIOPULLTYPEMASK; *gpio |= gpiopulldowntype; break; default : if((*gpio & 0xFF)==0xFF) { for(int i=0;i<16;i++) { //GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)i * 2)); //GPIOx->PUPDR |= (GPIO_PuPd_NOPULL << (i * 2)); } } else { //GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)(*gpio & 0xFF) * 2)); //GPIOx->PUPDR |= (GPIO_PuPd_NOPULL << ((*gpio & 0xFF) * 2)); } *gpio &= ~GPIOPULLTYPEMASK; *gpio |= gpionopulltype; break; } } void gpioset(gpio_t gpio) { //GPIO_TypeDef* GPIOx = GPIOGETPORT(gpio); if((gpio & 0xFF)==0xFF) { //GPIOx->BSRRL = -1; } else { //GPIOx->BSRRL = 1<<(gpio & 0xFF); } } void gpioclr(gpio_t gpio) { //GPIO_TypeDef* GPIOx = GPIOGETPORT(gpio); if((gpio & 0xFF)==0xFF) { //GPIOx->BSRRH = -1; } else { //GPIOx->BSRRH = 1<<(gpio & 0xFF); } } void gpiosetval(gpio_t gpio,int val) { //GPIO_TypeDef* GPIOx = GPIOGETPORT(gpio); if((gpio & 0xFF)==0xFF) { //GPIOx->ODR = val; } else { //GPIOx->ODR = (val & 1)<<(gpio & 0xFF); } } int gpiogetval(gpio_t gpio) { //GPIO_TypeDef* GPIOx = GPIOGETPORT(gpio); if((gpio & 0xFF)==0xFF) { //return GPIOx->IDR; } else { //return ((GPIOx->IDR>>(gpio & 0xFF)) & 1); } }