uart.c
191 lines
| 4.5 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" | |||
void uartputc(uartDev* dev,char c) { | ||||
while (!((dev->LineStat & (1<<5)))); | ||||
dev->RWreg = c; | ||||
} | ||||
char uartgetc(uartDev* dev) { | ||||
while (!((dev->LineStat & 1))); | ||||
return (char)dev->RWreg; | ||||
} | ||||
void uartputs(uartDev* dev,char *s) { | ||||
while (*s) uartputc(dev,*s++); | ||||
} | ||||
void uartgets(uartDev* dev,char *s) { | ||||
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; | ||||
} | ||||
} | ||||
void uartsetup(uartDev* dev,unsigned int baudRate,unsigned char WordLength,unsigned char StopBitCnt,unsigned char Parity) | ||||
{ | ||||
if(WordLength>9)WordLength=8; | ||||
if((StopBitCnt>2)||(StopBitCnt==0))StopBitCnt=1; | ||||
if(Parity>7)Parity=0; | ||||
dev->LineCtrl = (WordLength-5) + ((StopBitCnt-1)<<2) + (Parity<<3); | ||||
uartsetbaudrate(dev,baudRate); | ||||
} | ||||
unsigned char uartgetpclkfactor(uartDev* dev) | ||||
{ | ||||
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]; | ||||
} | ||||
void uartsetpclkfactor(uartDev* dev,unsigned char pclkfactor) | ||||
{ | ||||
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; | ||||
} | ||||
} | ||||
void uartsetbaudrate(uartDev* dev,unsigned int baudRate) | ||||
{ | ||||
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); | ||||
} | ||||
dev->LineCtrl |= 128; | ||||
dev->RWreg = pclk/(baudRate*16); | ||||
dev->LineCtrl &= ~(128); | ||||
} | ||||
r1 | ||||
uartDev* uartopen(int count){ | ||||
uartDev* dev; | ||||
switch(count) | ||||
{ | ||||
case 0: | ||||
dev = (uartDev*)((unsigned long)LPC_UART0_BASE); | ||||
break; | ||||
case 1: | ||||
dev = (uartDev*)((unsigned long)LPC_UART1_BASE); | ||||
break; | ||||
case 2: | ||||
dev = (uartDev*)((unsigned long)LPC_UART2_BASE); | ||||
break; | ||||
case 3: | ||||
dev = (uartDev*)((unsigned long)LPC_UART3_BASE); | ||||
break; | ||||
default: | ||||
dev = (uartDev*)0; | ||||
break; | ||||
} | ||||
return dev; | ||||
} | ||||