EmbeddedRelated.com
Forums

problem communication UART LPC2129 to LM400 bluetooth

Started by zied130187 December 13, 2010
hello , my friends

i have a problem to communicate with LM400 module bluetooth.

i have a development kit olimex with MCU LPC2129.
i want to send command "AT\r" to test the communication with LM400.

i use UART interface to communicate with the module bluetooth.
baud rate 19200, 1 bit stop , no parity

frequency clock : 14,7456 Mhz
CCLK = 58,P824 Mhz
PCLK = 14,7456 Mhz

divisor baud rate = 14745600/(16*19200) = 48

my problem is when i execute the code and i send "AT\r" with UART
i must to receive \r\nOK\r\n after send AT\r
but i receive 0xFF after send A and 0xFF after send T ,
and i don't receive any data after send the command.

my code work with any problem if i connect U1RX to U1TX.
i send AT\r and i receive AT\r.
i don't see where is the problem,

help me please,

this is my code :

i debug this code with IAR workbench

***********************************************************
* CPUinit()
*
***********************************************************
void CPUinit(void)
{
PLLCFG_bit.MSEL=3; //See PLL calculations in #define section at top of this file
PLLCFG_bit.PSEL=1; //See PLL calculations in #define section at top of this file
PLLFEED=0xAA;
PLLFEED=0x55;
PLLCON_bit.PLLE=1; // Enable the PLL
PLLFEED=0xAA;
PLLFEED=0x55;
while(!(PLLSTAT & PLOCK)); // Wait for PLL to lock

//Init MAM & Flash memory fetch
MAMCR_bit.MODECTRL=2;
MAMTIM_bit.CYCLES=4;
VPBDIV_bit.VPBDIV=0; //See PLL calculations in #define section at top of this file

//GPIO init
// A_PULL_UP;

//IODIR in binary 0000 0000 0000 0000 0011 0001 0000 0001 ...P0.12, P0.13 are output(LEDs) also TXD0,TXD1,TD2
IO0DIR=0x00003101;

//PINSEL0 in binary 0000 0000 0000 0101 0000 0000 0000 0101
PINSEL0 = 0x00050005; // P0 lower 16 bits : TXD1,RXD1,TXD0,RXD0,others GPIO
PINSEL1=0; //P0 upper 16 bits all GPIO

A_LED1_OFF;
A_LED2_OFF;
VICProtection = 0;
}

************************************************************
* INTERRUPTSinit()
*
************************************************************
void INTERRUPTSinit(void)
{
#ifdef SRAM_VIA_JLINK
MEMMAP = 2;
#endif

VICVectAddr0 = (U32)UART0Interrupt;
VICVectCntl0 = (1<<5)|6; // Enable vector interrupt for UART0.

VICVectAddr1 = (U32)UART1Interrupt;
VICVectCntl1 = (1<<5)|7; // Enable vector interrupt for UART1.

VICIntSelect = 0;
VICIntEnable = (1<<6)|(1<<7); // Enable UART1 et UART0 interrupt. (1<<7) et (1<<6)

}

**************************************************************
* irq_handler()
*
**************************************************************
#pragma vector=0x18
__irq __arm void irq_handler(void)
{
void (*interrupt_function)();
U16 vector;

vector = VICVectAddr; // GET VECTOR ADDRESS FROM VIC CONTROLLER
interrupt_function = (void(*)())vector;

(*interrupt_function)(); // Call vectored interrupt function.

VICVectAddr=0xFF;
//A_LED1_OFF; // Clear interrupt in VIC.
}
****************************************************************
* UART1Interrupt()
*
****************************************************************
void UART1Interrupt(void)
{
switch(U1IIR_bit.IID)
{
case 0x01: //THRE interrupt
U1IER &= ~0x02; //disable the tx interrupt
break;

case 0x02: //Receive data available

A_LED2_ON; //received byte handling code
while (!(U1LSR & 0x01));

//data1 = U1RBR;
printf("U1RBR = %d\n",U1RBR);
buf[ind]= U1RBR; //data1;
ind++;
if(ind=P) ind=0;
break;

case 0x00: break; //Modem interrupt
case 0x03: break; //Receive line status interrupt (RDA)
case 0x06: break; //Character time out indicator interrupt (CTI)

default:
break;
}

}

***********************************************************
* getprocessorClockFreq()
*
***********************************************************

U16 getprocessorClockFreq(void)
{
return OSCILLATOR_CLOCK_FREQUENCY * (PLLCON & 1 ? (PLLCFG & 0xF) + 1 : 1);
}

************************************************************
* getperipheralClockFreq()
*
************************************************************

U16 getperipheralClockFreq(void)
{
U16 divider;
switch (VPBDIV_bit.VPBDIV)
{
case 0:
divider = 4;
break;
case 1:
divider = 1;
break;
case 2:
divider = 2;
break;
}
// printf ("CCLK = %d\n",getprocessorClockFreq());
// printf ("PCLK = %d\n",getprocessorClockFreq() / divider);
return getprocessorClockFreq() / divider;
}

************************************************************
* UART1Init()
*
************************************************************

void UART1Init(U16 baud)
{
// PINSEL0_bit.P0_8=1;
// PINSEL0_bit.P0_9=1;
U16 divisor = getperipheralClockFreq() / (16 * baud);
printf("div = %d\n",divisor);
U1LCR = 0x83; // 8 bits, no Parity, 1 Stop bit
U1DLL = LSB(divisor);
// printf("U1DLL = %d\n",U1DLL);
U1DLM = MSB(divisor);
// printf("U1DLM = %d\n",U1DLM);
/* U1FCR: UART1 FIFO Control Register
0x07: Clear Tx and Rx FIFO and FIFO Enable */
U1FCR=0x07 ;
U1LCR &=~0x80 ; //Disable DLAB

}

***********************************************************
* UART1_SendByte()
*
************************************************************

void UART1_SendByte (char dat)
{
printf("data1 %c\n",dat);
U1IER |= 0x02; // enable tx interrupt
U1THR = dat;
// A_LED2_OFF;
if(dat!= '\r') delay_ms(1000);
while ((U1LSR & 0x40) == 0);
}

**********************************************************
* UART1_SendStr()
*
**********************************************************
void UART1_SendStr (char *str)
{
while (1)
{
if (*str == '\0') break;
UART1_SendByte(*str++);
}
}

**********************************************************
* main.c
*
**********************************************************

#include //Needed by Macros only usually (but in this case 'SFR peek/poking' in main too)
#include "hardware.h" //Supplies Hardware specific macros (e.g. Action A_LED1_ON)
#include
#include
#include

extern char data1;
extern char data0;
extern char buf[];
extern int ind;
int j,k;
U16 toto;
/*-------------------*/

void main(void)
{

__disable_interrupt();
CPUinit();

UART1Init(19200);

INTERRUPTSinit();

U1IER = 0x03;
__enable_interrupt();

UART1_SendStr("AT\r");

while(1)
{
printf("ind = %d\n",ind);
for(j=0;j printf("receive = %c\n",buf[j]);
}
}

*******************************************************************
*******************************************************************

the connection LM400 with UART is :

LM400 LPC2129
PIN2(TX) to P0.9(U1RX)
PIN3(RX) to P0.8(U1TX)
PIN4(RTS)<=> PIN5(CTS) No Flow Control (3 wire operation)
PIN6(VDD) to 3.3V
PIN12(GND) to GND

thank you to help me.

An Engineer's Guide to the LPC2100 Series

Hello,

one problem could be the following (inside ISR):

printf("U1RBR = %d\n",U1RBR);
buf[ind]= U1RBR; //data1;

printf is already reading one byte...
(do you see the correct character in output of printf ?)

Try the following change:

buf[ind]= U1RBR; //data1;
printf("U1RBR = %d\n",buf[ind]);

Best regards,

Martin

--- In l..., "capiman26061973" wrote:
>
> Hello,
>
> one problem could be the following (inside ISR):
>
> printf("U1RBR = %d\n",U1RBR);
> buf[ind]= U1RBR; //data1;
>
> printf is already reading one byte...
> (do you see the correct character in output of printf ?)
>
> Try the following change:
>
> buf[ind]= U1RBR; //data1;
> printf("U1RBR = %d\n",buf[ind]);
>
> Best regards,
>
> Martin
>

hello Martin, thank you for your response
yes i see the correct character in output of printf
when i use :
printf("U1RBR = %d\n",U1RBR);
buf[ind]= U1RBR; //data1;

i have change this 2 instructions with :
> buf[ind]= U1RBR; //data1;
> printf("U1RBR = %d\n",buf[ind]);

but i have always the same problem

i receive 0xFF after send a caracter.
and i don't receive any response from LM400.

Hello,

when you see the correct received characters via printf,
then you know the communication between LPC2129 and BT module works !

Then have a look at the handling of buf.
1) Your ind variable is accessed via main routine and via interrupt
routine. Change

extern int ind;

to

extern volatile int ind;

and also were the variable is created (i have not found this code in your post)

int ind;

to

volatile int ind;

2) Interrupt routine has a ring buffer, 50 elements, filling one
after the other.
Main routine always prints characters from 0 to ind. So no ring buffer...
There seems to be a mixture of different forms of implementiation.
I would prefer the ring buffer. But then you need a read index and a write index.
Use and increment write index (like in existing interrupt routine).
In main routine check if read index is different to write index,
if yes, print one character and increment read index by 1.

PS: Use volatile for both index (read and write index). Too much volatile does not really matter...

Best regards,

Martin

Doing a printf inside an interrupt can lead to a few timing issues as the printf takes a while to perform (especially over a debug link!). It may also cause other interrupt to fire if it uses another UART to get that string out.

That's one observation, the other is that you need to loop in the interrupt until the U1LSR_RDR is clear, as you may have more than 1 byte in the FIFO (that generated the interrupt) and your only reading one of them! so you could be missing a few bytes.

// get all available bytes from FIFO
while (U1LSR & U1LSR_RDR)
{
buf[ind]= U1RBR; // get available byte and put in buffer;
printf("U1RBR = %d\n",buf[ind]); // NOT a good idea in an ISR !!!
ind++;
};

Simon.

--- In l..., "zied130187" wrote:
>
> --- In l..., "capiman26061973" wrote:
> >
> >
> >
> > Hello,
> >
> > one problem could be the following (inside ISR):
> >
> > printf("U1RBR = %d\n",U1RBR);
> > buf[ind]= U1RBR; //data1;
> >
> > printf is already reading one byte...
> > (do you see the correct character in output of printf ?)
> >
> > Try the following change:
> >
> > buf[ind]= U1RBR; //data1;
> > printf("U1RBR = %d\n",buf[ind]);
> >
> > Best regards,
> >
> > Martin
> > hello Martin, thank you for your response
> yes i see the correct character in output of printf
> when i use :
> printf("U1RBR = %d\n",U1RBR);
> buf[ind]= U1RBR; //data1;
>
> i have change this 2 instructions with :
> > buf[ind]= U1RBR; //data1;
> > printf("U1RBR = %d\n",buf[ind]);
>
> but i have always the same problem
>
> i receive 0xFF after send a caracter.
> and i don't receive any response from LM400.
>

> I would prefer the ring buffer.

my problem at present is not to read after 50 caracters.

yes i must to change the loop in main, but now

i have the problem to read one caracter from LM400

when i send AT\r , i must receive \r\nOK\r\n (6 caracters)

in this case , i don't have the problem to create ring buffer
but i must change this after correct my code to receive the response
of AT\r command.

so, i must to send AT\r char by char with 80-100 msec guard time between two characters.

i use this function delay but i don't sure , if this function give me a delay for X ms.

i don't know , who calculate the limit of j.

********************************************************************
* delay_ms()
*
********************************************************************
void delay_ms(long int ms)
{
long int i,j;
for(i=0;i for(j=0;j<6666;j++); //6653
}

my freq clock : CCLK = 58,9824 MHz
can you help me to correct this function

best regards,

zied

As I said last week ....

6666 is the number of iterations that the nested for-loop needs to do in 1mS. Caution: The number of iterations is dependant upon a) the processor clock (cycle time) and b) the compiler optimisation settings and the resultant instruction code.

It can be determine by trial and error for your particular set-up by setting up an I/O pin as an output and toggling it whilst monitoring it on an oscilloscope. e.g.


SET_PIN_AS_OUTPUT;
for (;;) // indefinite loop
{
SET_PIN_HIGH;
delay_ms(100);
SET_PIN_LOW;
delay_ms(100);
}


...using this you can 'tweek' the value until the 100mS high/low time is
seen/measured on the scope.

In practice, a for loop isn't the best way to do timings like this. A routine that sets an internal timer and waits for the interrupt ('done') flag is the way to go. This method is only dependant upon the processor clock and that value you know! The compiler can now do what it likes and it won't affect the delay (well by the odd micro second at worst!).

Above is how you can adjust the j value to give you a 1mS delay. It involves using an I/O pin and a scope. You can't easily calculate it just based on clock timing alone as you don't know what instructions the compiler will generate!

Simon.

--- In l..., "zied130187" wrote:
> > I would prefer the ring buffer.
>
> my problem at present is not to read after 50 caracters.
>
> yes i must to change the loop in main, but now
>
> i have the problem to read one caracter from LM400
>
> when i send AT\r , i must receive \r\nOK\r\n (6 caracters)
>
> in this case , i don't have the problem to create ring buffer
> but i must change this after correct my code to receive the response
> of AT\r command.
>
> so, i must to send AT\r char by char with 80-100 msec guard time between two characters.
>
> i use this function delay but i don't sure , if this function give me a delay for X ms.
>
> i don't know , who calculate the limit of j.
>
> ********************************************************************
> * delay_ms()
> *
> ********************************************************************
> void delay_ms(long int ms)
> {
> long int i,j;
> for(i=0;i > for(j=0;j<6666;j++); //6653
> }
>
> my freq clock : CCLK = 58,9824 MHz
> can you help me to correct this function
>
> best regards,
>
> zied
>

thank you for all response,

any others idea to resolve the problem of communication
LPC2129 with LM400 bluetooth module.

it isn't work up to now !!!

----Original Message----
From: l...
[mailto:l...] On Behalf Of zied130187
Sent: 13 December 2010 13:27 To: l...
Subject: [lpc2000] Re: problem communication UART LPC2129
to LM400 bluetooth

> thank you for all response,
>
> any others idea to resolve the problem of communication
> LPC2129 with LM400 bluetooth module.
>
> it isn't work up to now !!!

Have you checked that your baud rate is actually what you think it is?

--
Tim Mitchell

--- In l..., "zied130187" wrote:
>
> thank you for all response,
>
> any others idea to resolve the problem of communication
> LPC2129 with LM400 bluetooth module.
>
> it isn't work up to now !!!
>

Scope RxD / TxD. Are they really working with 19200?

Is the bluetooth module really transmitting 0xFF or is the uart
misreading something else?