Content originally posted in LPCWare by tbelo on Sun Apr 28 23:25:31 MST 2013
Hi,
Finally it worked!
Key notes:
* Big delay after the AT command.
* Enable tx irq only during expected transmision time
* and some more as shown to the code...
#define UART_BUFF_MASK (UART_BUFF_SIZE - 1)
static uint8_t buf[128];
static volatile struct {
uint16_t ri, wi, ct, act;
uint8_t buff[UART_BUFF_SIZE];
} TxBuff, RxBuff;
#define RS485_ENABLED0
#define TX_INTERRUPT0/* 0 if TX uses polling, 1 interrupt driven. */
#define MODEM_TEST0
#define IER_RBR0x01
#define IER_THRE0x02
#define IER_RLS0x04
#define IIR_PEND0x01
#define IIR_RLS0x03
#define IIR_RDA0x02
#define IIR_CTI0x06
#define IIR_THRE0x01
#define LSR_RDR0x01
#define LSR_OE0x02
#define LSR_PE0x04
#define LSR_FE0x08
#define LSR_BI0x10
#define LSR_THRE0x20
#define LSR_TEMT0x40
#define LSR_RXFE0x80
void UART_IRQHandler (void)
{
uint8_t iir, d;
int i, cnt;
for (;;) {
iir = LPC_UART->IIR; /* Get interrupt ID */
if (iir & 1) break; /* Exit if there is no interrupt */
switch (iir & 7) {
case 4: /* Rx FIFO is filled to trigger level or timeout occured */
i = RxBuff.wi;
cnt = RxBuff.ct;
while (LPC_UART->LSR & 0x01) { /* Get all data in the Rx FIFO | (LPC_UART->LSR & 0x02))*/
d = LPC_UART->RBR;
if (cnt < UART_BUFF_SIZE) { /* Store data if Rx buffer is not full */
RxBuff.buff = d;
i++;
i &= UART_BUFF_MASK;
cnt++;
}
}
RxBuff.wi = i;
RxBuff.ct = cnt;
break;
case 2: /* Tx FIFO gets empty */
cnt = TxBuff.ct;
if (cnt) { /* There is one or more byte to send */
i = TxBuff.ri;
for (d = 16; d && cnt; d--, cnt--) { /* Fill Tx FIFO */
LPC_UART->THR = TxBuff.buff[i++];
i &= UART_BUFF_MASK;
}
TxBuff.ri = i;
TxBuff.ct = cnt;
} else {
TxBuff.act = 0; /* When no data to send, next putc() must trigger Tx sequense */
}
//__disable_irq();
LPC_UART->IER = 0x5 ;
break;
default: /* Data error or break detected */
LPC_UART->LSR;
LPC_UART->RBR;
break;
}
}
}
void uart_init (uint32_t baudrate)
{
uint32_t Fdiv;
uint32_t regVal;
NVIC_DisableIRQ(UART_IRQn);
LPC_IOCON->PIO1_6 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_6 |= 0x01; /* UART RXD */
LPC_IOCON->PIO1_7 &= ~0x07;
LPC_IOCON->PIO1_7 |= 0x01; /* UART TXD */
/* Enable UART clock */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */
LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
regVal = LPC_SYSCON->UARTCLKDIV;
Fdiv = (((SystemCoreClock*LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/baudrate ;/*baud rate */
LPC_UART->DLM = Fdiv / 256;
LPC_UART->DLL = Fdiv % 256;
LPC_UART->LCR = 0x03;/* DLAB = 0 */
LPC_UART->FCR = 0x07;/* Enable and reset TX and RX FIFO. */
/* Read to clear the line status. */
regVal = LPC_UART->LSR;
/* Clear Tx/Rx buffers */
TxBuff.ri = 0; TxBuff.wi = 0; TxBuff.ct = 0; TxBuff.act = 0;
RxBuff.ri = 0; RxBuff.wi = 0; RxBuff.ct = 0;
/* Ensure a clean start, no data in either TX or RX FIFO. */
// CodeRed - added parentheses around comparison in operand of &
while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );
while ( LPC_UART->LSR & LSR_RDR )
{
regVal = LPC_UART->RBR;/* Dump data from RX FIFO */
}
/* Enable Tx/Rx/Error interrupts */
NVIC_EnableIRQ(UART_IRQn);
LPC_UART->IER = IER_RBR | IER_RLS;/* Enable UART interrupt */
return;
}
void setspeed (baudrate)
{
/* Enable UART clock */
uint32_t Fdiv;
uint32_t regVal;
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */
regVal = LPC_SYSCON->UARTCLKDIV;
Fdiv = (((SystemCoreClock*LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/baudrate ;/*baud rate */
LPC_UART->FDR = 0;
LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
LPC_UART->DLL = Fdiv; // Baud Rate depending on PCLK
LPC_UART->DLM = (Fdiv >> 8); // High divisor latch
}
uint32_t uart_test (void)
{
return RxBuff.ct;
}
uint8_t uart_getc (void)
{
uint8_t data;
int i;
/* Wait while Rx buffer is empty */
while (!RxBuff.ct);
i = RxBuff.ri; /* Get a byte from Rx buffer */
data = RxBuff.buff[i++];
RxBuff.ri = i & UART_BUFF_MASK;
RxBuff.ct--;
return data;
}
void uart_putc (uint8_t d) /* Data byte to be sent */
{
int i;
/* Wait for Tx buffer ready */
while (TxBuff.ct >= UART_BUFF_SIZE) ;
if (TxBuff.act) {
i = TxBuff.wi; /* Put a byte into Tx buffer */
TxBuff.buff[i++] = d;
TxBuff.wi = i & UART_BUFF_MASK;
TxBuff.ct++;
} else {
TxBuff.act = 1; /* Trigger Tx sequense */
LPC_UART->THR = d;
}
LPC_UART->IER = 0x7 ;
}
void uart_puts(char *s)// Put String to UART, Require uart_putc()
{
while(*s!='\0'){uart_putc(*s);s++;}
}
void uart_gets(uint8_t *buf) {
int i,j;
i= uart_test();
for (j = 0; j < i; j++) {
buf[j] = uart_getc();
}
}
void wait(uint32_t time){
while(time--){
__NOP();
}
}
void clr_buf (void){
int i;
for (i = 0; i <= 128; i++) {
buf='\0';
}
}
int start (void)
{
uart_init(UART_BAUD);
wait(1000000);
uart_puts ("AT+IFC=0,0\r\n");
wait(1000000);
uart_gets (buf);
clr_buf();
.................................