uart.c
191 lines
| 4.6 KiB
| text/x-c
|
CLexer
r1 | /*------------------------------------------------------------------------------ | |||
-- 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 | ||||
-------------------------------------------------------------------------------*/ | ||||
r4 | #include "core.h" | |||
r1 | #include "uart.h" | |||
r12 | void uartputc(uartDev dev,char c) { | |||
while (!((((_uartDev)dev)->LineStat & (1<<5)))); | ||||
((_uartDev)dev)->RWreg = c; | ||||
r1 | } | |||
r12 | char uartgetc(uartDev dev) { | |||
while (!((((_uartDev)dev)->LineStat & 1))); | ||||
return (char)((_uartDev)dev)->RWreg; | ||||
r1 | } | |||
r12 | void uartputs(uartDev dev,char *s) { | |||
r1 | while (*s) uartputc(dev,*s++); | |||
} | ||||
r12 | void uartgets(uartDev dev,char *s) { | |||
r1 | while (*s && (*s!=0xd)) *s++ = uartgetc(dev); | |||
} | ||||
r4 | void uartoff(int count) | |||
{ | ||||
switch(count) | ||||
{ | ||||
case 0: | ||||
LPC_SC->PCONP &= ~( 1 << 3 ); | ||||
break; | ||||
case 1: | ||||
LPC_SC->PCONP &= ~( 1 << 4 ); | ||||
break; | ||||
case 2: | ||||
LPC_SC->PCONP &= ~( 1 << 24 ); | ||||
break; | ||||
case 3: | ||||
LPC_SC->PCONP &= ~( 1 << 25 ); | ||||
break; | ||||
default: | ||||
break; | ||||
} | ||||
} | ||||
void uarton(int count) | ||||
{ | ||||
switch(count) | ||||
{ | ||||
case 0: | ||||
LPC_SC->PCONP |= ( 1 << 3 ); | ||||
break; | ||||
case 1: | ||||
LPC_SC->PCONP |= ( 1 << 4 ); | ||||
break; | ||||
case 2: | ||||
LPC_SC->PCONP |= ( 1 << 24 ); | ||||
break; | ||||
case 3: | ||||
LPC_SC->PCONP |= ( 1 << 25 ); | ||||
break; | ||||
default: | ||||
break; | ||||
} | ||||
} | ||||
r12 | void uartsetup(uartDev dev,unsigned int baudRate,unsigned char WordLength,unsigned char StopBitCnt,unsigned char Parity) | |||
r4 | { | |||
if(WordLength>9)WordLength=8; | ||||
if((StopBitCnt>2)||(StopBitCnt==0))StopBitCnt=1; | ||||
if(Parity>7)Parity=0; | ||||
r12 | ((_uartDev)dev)->LineCtrl = (WordLength-5) + ((StopBitCnt-1)<<2) + (Parity<<3); | |||
r4 | uartsetbaudrate(dev,baudRate); | |||
} | ||||
r12 | unsigned char uartgetpclkfactor(uartDev dev) | |||
r4 | { | |||
unsigned int clksel=0; | ||||
const char clkselDec[]={4,1,2,8}; | ||||
switch((int)dev) | ||||
{ | ||||
case (int)LPC_UART0_BASE: | ||||
clksel = (LPC_SC->PCLKSEL0>>6) & 3; | ||||
break; | ||||
case (int)LPC_UART1_BASE: | ||||
clksel = (LPC_SC->PCLKSEL0>>8) & 3; | ||||
break; | ||||
case (int)LPC_UART2_BASE: | ||||
clksel = (LPC_SC->PCLKSEL1>>16) & 3; | ||||
break; | ||||
case (int)LPC_UART3_BASE: | ||||
clksel = (LPC_SC->PCLKSEL1>>18) & 3; | ||||
break; | ||||
default: | ||||
break; | ||||
} | ||||
return clkselDec[clksel]; | ||||
} | ||||
r12 | void uartsetpclkfactor(uartDev dev,unsigned char pclkfactor) | |||
r4 | { | |||
const char clkselDec[]={1,1,2,2,0,0,0,0,3}; | ||||
unsigned int clksel=0; | ||||
switch((int)dev) | ||||
{ | ||||
case (int)LPC_UART0_BASE: | ||||
LPC_SC->PCLKSEL0 |= clkselDec[pclkfactor]<<6; | ||||
LPC_SC->PCLKSEL0 &= clkselDec[pclkfactor]<<6; | ||||
break; | ||||
case (int)LPC_UART1_BASE: | ||||
LPC_SC->PCLKSEL0 |= clkselDec[pclkfactor]<<8; | ||||
LPC_SC->PCLKSEL0 &= clkselDec[pclkfactor]<<8; | ||||
break; | ||||
case (int)LPC_UART2_BASE: | ||||
LPC_SC->PCLKSEL1 |= clkselDec[pclkfactor]<<16; | ||||
LPC_SC->PCLKSEL1 &= clkselDec[pclkfactor]<<16; | ||||
break; | ||||
case (int)LPC_UART3_BASE: | ||||
LPC_SC->PCLKSEL1 |= clkselDec[pclkfactor]<<18; | ||||
LPC_SC->PCLKSEL1 &= clkselDec[pclkfactor]<<18; | ||||
break; | ||||
default: | ||||
break; | ||||
} | ||||
} | ||||
r12 | void uartsetbaudrate(uartDev dev,unsigned int baudRate) | |||
r4 | { | |||
unsigned int pclk = 0; | ||||
unsigned int clksel=0; | ||||
unsigned int cpuclk=0; | ||||
if(dev==0)return; | ||||
cpuclk = coregetCpuFreq(); | ||||
pclk = cpuclk / uartgetpclkfactor(dev); | ||||
while((baudRate*16)>pclk) | ||||
{ | ||||
unsigned char pclkfact= uartgetpclkfactor(dev); | ||||
if(pclkfact==1)return; | ||||
uartsetpclkfactor(dev,pclkfact/2); | ||||
pclk = cpuclk / uartgetpclkfactor(dev); | ||||
} | ||||
r12 | ((_uartDev)dev)->LineCtrl |= 128; | |||
((_uartDev)dev)->RWreg = pclk/(baudRate*16); | ||||
((_uartDev)dev)->LineCtrl &= ~(128); | ||||
r4 | } | |||
r1 | ||||
r12 | uartDev uartopen(int count){ | |||
uartDev dev; | ||||
r1 | switch(count) | |||
{ | ||||
case 0: | ||||
r12 | dev = (uartDev)((unsigned long)LPC_UART0_BASE); | |||
r1 | break; | |||
case 1: | ||||
r12 | dev = (uartDev)((unsigned long)LPC_UART1_BASE); | |||
r1 | break; | |||
case 2: | ||||
r12 | dev = (uartDev)((unsigned long)LPC_UART2_BASE); | |||
r1 | break; | |||
case 3: | ||||
r12 | dev = (uartDev)((unsigned long)LPC_UART3_BASE); | |||
r1 | break; | |||
default: | ||||
r12 | dev = (uartDev)0; | |||
r1 | break; | |||
} | ||||
return dev; | ||||
} | ||||