/*------------------------------------------------------------------------------ -- 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@member.fsf.org -------------------------------------------------------------------------------*/ #include #include #include #define GPIOGETPORT(gpio) ((GPIO_TypeDef*)(((((uint32_t)gpio) & (uint32_t)0x0000FF00)*(uint32_t)4) + (uint32_t)GPIOA)) #define GPIOPORTNUM(gpio) (((uint32_t)(gpio) & (uint32_t)0x0000FF00)>>(uint32_t)8) gpio_t gpioopen(uint32_t gpio) { gpiosetconfig(gpio,gpioindir,gpiolowspeed,gpiopulluptype,gpionopulltype); RCC_AHB1PeriphClockCmd(((uint32_t)0x00000001<direction, config->speed, config->outType, config->pullType); RCC_AHB1PeriphClockCmd(((uint32_t)0x00000001<direction, config->speed, config->outType, config->pullType); } extern void gpiosetspeed(gpio_t gpio,gpiospeed_t speed) { GPIO_TypeDef* GPIOx = GPIOGETPORT((gpio)); uint32_t speedMask = GPIO_Speed_2MHz; switch(speed) { case gpiolowspeed : speedMask = GPIO_Speed_2MHz; break; case gpiomediumspeed : speedMask = GPIO_Speed_25MHz; break; case gpiofastspeed : speedMask = GPIO_Speed_50MHz; break; case gpiohighspeed : speedMask = GPIO_Speed_100MHz; break; } if((gpio & 0xFF)==0xFF) { for(int i=0;i<16;i++) { GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (i * 2)); GPIOx->OSPEEDR |= ((speedMask) << (i * 2)); } } else { GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << ((gpio & 0xFF) * 2)); GPIOx->OSPEEDR |= ((speedMask) << ((gpio & 0xFF) * 2)); } } void gpiosetdir(gpio_t gpio, gpiodir_t dir) { GPIO_TypeDef* GPIOx = GPIOGETPORT((gpio)); uint32_t directionMask = GPIO_Mode_IN; switch(dir) { case gpiooutdir: directionMask = GPIO_Mode_OUT; break; case gpioaf: directionMask = GPIO_Mode_AF; break; case gpioan: directionMask = GPIO_Mode_AN; break; } if((gpio & 0xFF)==0xFF) { for(int i=0;i<16;i++) { GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (i * 2)); GPIOx->MODER |= (directionMask << (i * 2)); } } else { GPIOx->MODER &= ~(GPIO_MODER_MODER0 << ((gpio & 0xFF) * 2)); GPIOx->MODER |= (directionMask << ((gpio & 0xFF) * 2)); } } void gpiosetouttype(gpio_t gpio, gpioouttype_t outtype) { GPIO_TypeDef* GPIOx = GPIOGETPORT((gpio)); uint16_t outTypeMask = GPIO_OType_PP; if(outtype == gpioopendraintype) outTypeMask = GPIO_OType_OD; else outTypeMask = GPIO_OType_PP; if((gpio & 0xFF)==0xFF) { for(int i=0;i<16;i++) { GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)i)); GPIOx->OTYPER |= (uint16_t)(outTypeMask<<((uint16_t)i)); } } else { GPIOx->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)(gpio & 0xFF))); GPIOx->OTYPER |= (uint16_t)(outTypeMask<<((uint16_t)(gpio & 0xFF))); } } void gpiosetpulltype(gpio_t gpio,gpiopulltype_t pulltype) { GPIO_TypeDef* GPIOx = GPIOGETPORT(gpio); uint32_t pullTypeMask=GPIO_PuPd_NOPULL; switch(pulltype) { case gpiopulluptype: pullTypeMask=GPIO_PuPd_UP; break; case gpiopulldowntype: pullTypeMask=GPIO_PuPd_DOWN; break; default : pullTypeMask=GPIO_PuPd_NOPULL; break; } if((gpio & 0xFF)==0xFF) { for(int i=0;i<16;i++) { GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)i * 2)); GPIOx->PUPDR |= (pullTypeMask << (i * 2)); } } else { GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)(gpio & 0xFF) * 2)); GPIOx->PUPDR |= (pullTypeMask << ((gpio & 0xFF) * 2)); } } 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 { if(val) GPIOx->BSRRL = 1<<(gpio & 0xFF); else GPIOx->BSRRH = 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); } }