/*------------------------------------------------------------------------------ -- This file is a part of the libuc, microcontroler library -- Copyright (C) 2011, 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 #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) USART_TypeDef* _uart_dev_table[6]={USART1,USART2,USART3,UART4,UART5,USART6}; int _uartstrsetpos(streamdevice* device,int pos); int _uartstrread(streamdevice* device,void* data,int size, int n); int _uartstrwrite(streamdevice* device,void* data,int size, int n); streamdevice_ops UART_OPS= { .write = &_uartstrwrite, .read = &_uartstrread, .setpos= &_uartstrsetpos, .close = NULL }; uart_t uartopen(int count) { switch(count) { case uart1: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART1->CR3 &= ~((1<<8) + (1<<9)); return uart1; break; case uart2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); USART2->CR3 &= ~((1<<8) + (1<<9)); return uart2; break; case uart3: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); USART3->CR3 &= ~((1<<8) + (1<<9)); return uart3; break; case uart4: RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); UART4->CR3 &= ~((1<<8) + (1<<9)); return uart4; break; case uart5: RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); return uart5; break; case uart6: RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, DISABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); return uart6; break; default: break; } return -1; } uart_t uartopenandconfig(int count, uint32_t cfg, uint32_t speed, uint32_t TXpin, uint32_t RXpin, uint32_t RTSpin, uint32_t CTSpin) { uart_t dev= uartopen(count); uartsetconfig(dev,cfg,speed); uartsetpins(dev,TXpin,RXpin,RTSpin,CTSpin); return dev; } int uartclose(uart_t uart) { switch(uart) { case uart1: RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); break; case uart2: RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); break; case uart3: RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); break; case uart4: RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); break; case uart5: RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); break; case uart6: RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE); break; default: return -1; break; } return 1; } int uartsetpins(uart_t uart,uint32_t TXpin,uint32_t RXpin,uint32_t RTSpin,uint32_t CTSpin) { if(uart >5)return -1; if(uart <0)return -1; gpio_t TX,RX,CTS,RTS; TX = gpioopen(TXpin); RX = gpioopen(RXpin); TX |= gpiolowspeed | gpioaf | gpiopushpulltype | gpionopulltype; RX |= gpiolowspeed | gpioaf | gpiopushpulltype | gpionopulltype; gpiosetconfig(&TX); gpiosetconfig(&RX); uint8_t gpioAFuartx = GPIO_AF_USART1; switch(uart) { case uart1: gpioAFuartx = GPIO_AF_USART1; break; case uart2: gpioAFuartx = GPIO_AF_USART2; break; case uart3: gpioAFuartx = GPIO_AF_USART3; break; case uart4: gpioAFuartx = GPIO_AF_UART4; break; case uart5: gpioAFuartx = GPIO_AF_UART5; break; case uart6: gpioAFuartx = GPIO_AF_USART6; break; default: return -1; break; } GPIO_PinAFConfig(GPIOGETPORT(TX), (uint8_t)(TX & 0xF), gpioAFuartx); GPIO_PinAFConfig(GPIOGETPORT(RX), (uint8_t)(RX & 0xF), gpioAFuartx); if((gpioAFuartx!=GPIO_AF_UART5) && (gpioAFuartx!=GPIO_AF_UART4)) { if(CTSpin!=-1) { CTS = gpioopen(CTSpin); CTS |= gpiolowspeed | gpioaf | gpiopushpulltype | gpionopulltype; gpiosetconfig(&CTS); GPIO_PinAFConfig(GPIOGETPORT(CTS), (uint8_t)(CTS & 0xF), gpioAFuartx); } if(RTSpin!=-1) { RTS = gpioopen(RTSpin); RTS |= gpiolowspeed | gpioaf | gpiopushpulltype | gpionopulltype; gpiosetconfig(&RTS); GPIO_PinAFConfig(GPIOGETPORT(RTS), (uint8_t)(RTS & 0xF), gpioAFuartx); } } return 1; } int uartsetconfig(uart_t uart, uint32_t cfg, uint32_t speed) { int res=1; uartdisable(uart); uartsetspeed(uart,speed); uartsetparity(uart,cfg & UARTPARITYMASK); uartsetdatabits(uart,cfg & UARTBITSMASK); uartsetstopbits(uart,cfg & UARTSTOPBITSMASK); uartenable(uart); return res; } int uartenable(uart_t uart) { if((uart<6)&&(uart>=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; _dev_->CR1 |= (1<<13); _dev_->CR1 |= (1<<2) + (1<<3); _dev_->DR = ' '; return 1; } return -1; } int uartdisable(uart_t uart) { if((uart<6)&&(uart>=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; if((_dev_->CR1 & ((1<<3) +(1<<13)))==((1<<3) +(1<<13))) { while((_dev_->SR & (uint16_t)(1<<7))!=(uint16_t)(1<<7)); } _dev_->CR1 &= ~((1<<2) + (1<<3) +(1<<13)); return 1; } return -1; } int uartsetspeed(uart_t uart,uint32_t speed) { if((uart<6)&&(uart>=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; uint32_t tmpreg = 0x00, apbclock = 0x00; uint32_t integerdivider = 0x00; uint32_t fractionaldivider = 0x00; RCC_ClocksTypeDef RCC_ClocksStatus; RCC_GetClocksFreq(&RCC_ClocksStatus); if ((_dev_ == USART1) || ((_dev_ == USART6))) { apbclock = RCC_ClocksStatus.PCLK2_Frequency; } else { apbclock = RCC_ClocksStatus.PCLK1_Frequency; } if (((_dev_->CR1) & USART_CR1_OVER8) != (uint16_t)0) { integerdivider = ((25 * apbclock) / (2 * (speed))); } else { integerdivider = ((25 * apbclock) / (4 * (speed))); } tmpreg = (integerdivider / 100) << 4; fractionaldivider = integerdivider - (100 * (tmpreg >> 4)); if ((_dev_->CR1 & USART_CR1_OVER8) != (uint16_t)0) { tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07); } else { tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F); } _dev_->BRR = (uint16_t)tmpreg; return 1; } return -1; } int uartsetparity(uart_t uart,uartparity_t parity) { if((uart<6)&&(uart>=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; _dev_->CR1 &= ~(((1<<9)+(1<<10))); switch(parity) { case uartparityeven: _dev_->CR1 |= (1<<10); break; case uartparityodd: _dev_->CR1 |= (1<<10) + (1<<9); break; case uartparitynone: break; default : return 0; break; } return 1; } return -1; } int uartsetdatabits(uart_t uart,uartbits_t databits) { if((uart<6)&&(uart>=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; _dev_->CR1 &= ~(((1<<12))); switch(databits) { case uart7bits: return 0; break; case uart8bits: break; case uart9bits: _dev_->CR1 |= (1<<12); break; default : return 0; break; } return 1; } return -1; } int uartsetstopbits(uart_t uart,uartstopbits_t stopbits) { if((uart<6)&&(uart>=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; _dev_->CR2 &= ~(((1<<12)+(1<<13))); switch(stopbits) { case uarthalfstop: _dev_->CR2 |= (1<<12); break; case uartonestop: break; case uartonehalfstop: _dev_->CR2 |= (1<<12) + (1<<13); break; case uarttwostop: _dev_->CR2 |= (1<<13); break; default : return 0; break; } return 1; } return -1; } int uartputc(uart_t uart,char c) { if((uart<6)&&(uart>=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; while((_dev_->SR & (uint16_t)(1<<7))!=(uint16_t)(1<<7)); _dev_->DR = c; return 1; } return -1; } char uartgetc(uart_t uart) { if((uart<6)&&(uart>=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; while(!(_dev_->SR & (1<<5))); return (char)_dev_->DR; } return -1; } int uartputs(uart_t uart,char* s) { while (*s) uartputc(uart,*s++); return 1; } int uartgets(uart_t uart,char* s) { do { (*s) = uartgetc(uart); } while(*s++); return 1; } int uartputnc(uart_t uart,char* c,int n) { int l=0; while(l=0)) { USART_TypeDef* _dev_ = _uart_dev_table[(int)uart]; if(!(_dev_->SR & (1<<5))) return 0; else return 1; } return -1; } int _uartstrwrite(streamdevice* device,void* data,int size, int n) { return uartputnc((uart_t) device->_stream,(char*) data,size*n); } int _uartstrread(streamdevice* device,void* data,int size, int n) { return uartgetnc((uart_t) device->_stream,(char*) data,size*n); } int _uartstrsetpos(streamdevice* device,int pos) { return 1; } int uartmkstreamdev(uart_t uart,streamdevice* strdev) { strdev->_stream = (UHANDLE)uart;/* strdev->write = (write_t)&_uartstrwrite; strdev->read = (read_t)&_uartstrread; strdev->setpos = (setpos_t)&_uartstrsetpos;*/ strdev->ops = &UART_OPS; strdev->streamPt = 0; return 1; }