/*------------------------------------------------------------------------------ -- 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@gmail.com -------------------------------------------------------------------------------*/ #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) int uartopen(int count ,uart_t* uart) { switch(count) { case 0: uart->_dev = (void*)USART1; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); ((USART_TypeDef *)(uart->_dev))->CR3 &= ~((1<<8) + (1<<9)); //uartenable(uart); break; case 1: uart->_dev = (void*)USART2; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); ((USART_TypeDef *)(uart->_dev))->CR3 &= ~((1<<8) + (1<<9)); //uartenable(uart); break; case 2: uart->_dev = (void*)USART3; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); ((USART_TypeDef *)(uart->_dev))->CR3 &= ~((1<<8) + (1<<9)); //uartenable(uart); break; case 3: uart->_dev = (void*)UART4; RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); ((USART_TypeDef *)(uart->_dev))->CR3 &= ~((1<<8) + (1<<9)); //uartenable(uart); break; case 4: uart->_dev = (void*)UART5; RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); break; case 5: uart->_dev = (void*)USART6; RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE); RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, DISABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); break; default: break; } return 1; } int uartopenandconfig(int count ,uart_t* uart,uint32_t cfg,uint32_t speed,uint32_t TXpin,uint32_t RXpin,uint32_t RTSpin,uint32_t CTSpin) { uartopen(count ,uart); uart->cfg = cfg; uart->speed = speed; uartsetconfig(uart); uartsetpins(uart,TXpin,RXpin,RTSpin,CTSpin); return 1; } int uartclose(uart_t* uart) { switch((int)uart->_dev) { case (int)(void*)USART1: uart->_dev = (void*)USART1; RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); break; case (int)(void*)USART2: uart->_dev = (void*)USART2; RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE); break; case (int)(void*)USART3: uart->_dev = (void*)USART3; RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE); break; case (int)(void*)UART4: uart->_dev = (void*)UART4; RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE); break; case (int)(void*)UART5: uart->_dev = (void*)UART5; RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE); break; case (int)(void*)USART6: uart->_dev = (void*)USART6; RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE); break; default: break; } return 1; } int uartsetpins(uart_t* uart,uint32_t TXpin,uint32_t RXpin,uint32_t RTSpin,uint32_t CTSpin) { 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((int)uart->_dev) { case (int)(void*)USART1: gpioAFuartx = GPIO_AF_USART1; break; case (int)(void*)USART2: gpioAFuartx = GPIO_AF_USART2; break; case (int)(void*)USART3: gpioAFuartx = GPIO_AF_USART3; break; case (int)(void*)UART4: gpioAFuartx = GPIO_AF_UART4; break; case (int)(void*)UART5: gpioAFuartx = GPIO_AF_UART5; break; case (int)(void*)USART6: gpioAFuartx = GPIO_AF_USART6; break; default: break; } GPIO_PinAFConfig(GPIOGETPORT(TX), (uint8_t)(TX & 0xF), gpioAFuartx); GPIO_PinAFConfig(GPIOGETPORT(TX), (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) { int res=1; uartdisable(uart); uartsetspeed(uart,uart->speed); uartsetparity(uart,uart->cfg & UARTPARITYMASK); uartsetdatabits(uart,uart->cfg & UARTBITSMASK); uartsetstopbits(uart,uart->cfg & UARTSTOPBITSMASK); uartenable(uart); return res; } int uartenable(uart_t* uart) { ((USART_TypeDef *)(uart->_dev))->CR1 |= (1<<13); ((USART_TypeDef *)(uart->_dev))->CR1 |= (1<<2) + (1<<3); ((USART_TypeDef *)(uart->_dev))->DR = ' '; return 1; } int uartdisable(uart_t* uart) { if((((USART_TypeDef *)(uart->_dev))->CR1 & ((1<<3) +(1<<13)))==((1<<3) +(1<<13))) { while((((USART_TypeDef *)(uart->_dev))->SR & (uint16_t)(1<<7))!=(uint16_t)(1<<7)); } ((USART_TypeDef *)(uart->_dev))->CR1 &= ~((1<<2) + (1<<3) +(1<<13)); return 1; } int uartsetspeed(uart_t* uart,int speed) { uart->speed = speed; uint32_t tmpreg = 0x00, apbclock = 0x00; uint32_t integerdivider = 0x00; uint32_t fractionaldivider = 0x00; RCC_ClocksTypeDef RCC_ClocksStatus; RCC_GetClocksFreq(&RCC_ClocksStatus); if (((USART_TypeDef *)(uart->_dev) == USART1) || (((USART_TypeDef *)(uart->_dev) == USART6))) { apbclock = RCC_ClocksStatus.PCLK2_Frequency; } else { apbclock = RCC_ClocksStatus.PCLK1_Frequency; } if (((((USART_TypeDef *)(uart->_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 ((((USART_TypeDef *)(uart->_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); } ((USART_TypeDef *)(uart->_dev))->BRR = (uint16_t)tmpreg; return 1; } int uartsetparity(uart_t* uart,uartparity_t parity) { uart->cfg &= ~(UARTPARITYMASK); uart->cfg |= parity; ((USART_TypeDef *)(uart->_dev))->CR1 &= ~(((1<<9)+(1<<10))); switch(parity) { case uartparityeven: ((USART_TypeDef *)(uart->_dev))->CR1 |= (1<<10); break; case uartparityodd: ((USART_TypeDef *)(uart->_dev))->CR1 |= (1<<10) + (1<<9); break; case uartparitynone: break; default : return 0; break; } return 1; } int uartsetdatabits(uart_t* uart,uartbits_t databits) { uart->cfg &= ~UARTBITSMASK; uart->cfg |= databits; ((USART_TypeDef *)(uart->_dev))->CR1 &= ~(((1<<12))); switch(databits) { case uart7bits: return 0; break; case uart8bits: break; case uart9bits: ((USART_TypeDef *)(uart->_dev))->CR1 |= (1<<12); break; default : return 0; break; } return 1; } int uartsetstopbits(uart_t* uart,uartstopbits_t stopbits) { uart->cfg &= ~UARTSTOPBITSMASK; uart->cfg |= stopbits; ((USART_TypeDef *)(uart->_dev))->CR2 &= ~(((1<<12)+(1<<13))); switch(stopbits) { case uarthalfstop: ((USART_TypeDef *)(uart->_dev))->CR2 |= (1<<12); break; case uartonestop: break; case uartonehalfstop: ((USART_TypeDef *)(uart->_dev))->CR2 |= (1<<12) + (1<<13); break; case uarttwostop: ((USART_TypeDef *)(uart->_dev))->CR2 |= (1<<13); break; default : return 0; break; } return 1; } int uartputc(uart_t* uart,char c) { while((((USART_TypeDef *)(uart->_dev))->SR & (uint16_t)(1<<7))!=(uint16_t)(1<<7)); ((USART_TypeDef *)(uart->_dev))->DR = c; return 1; } char uartgetc(uart_t* uart) { while(!(((USART_TypeDef *)(uart->_dev))->SR & (1<<5))); return (char)((USART_TypeDef *)(uart->_dev))->DR; } 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_dev))->SR & (1<<5))) return 0; else 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->streamPt = 0; return 1; }