Reply by dr_danish_ali November 21, 20052005-11-21
Thanks to those who have replied.
To Richard, AFAIK the example on the Keil website
>http://www.keil.com/download/docs/288.asp
does not make use of the hardware TX buffer. To do that you'd need
code along the lines of (*warning untested code*):
void uart0_isr(void) __irq { /* not for public use */
unsigned char source = U0IIR & 0x06; /* only interested in interrupt
bits */
int index;
switch (source) {
case 0x02: /* transmit holding register empty */
uart0.TX_internal_buffer_space = uart_TX_internal_buffer_size;
while ((uart0.TX_internal_buffer_space > 0)
&& (uart0.TX_Extract_Index != uart0.TX_Insert_Index)) {
U0THR = uart0_TX_Buffer[uart0.TX_Extract_Index++];
if (uart0.TX_Extract_Index == uart0TX_BufferSize)
uart0.TX_Extract_Index = 0;
--uart0.TX_internal_buffer_space;
}
break;
case 0x04: /* receiver buffer register occupied */
...
break;
case 0x06: /* RX Line status change or error */
source = U0LSR;
break;
default: /* should not have interrupted */
break;
}
VICVectAddr = 0; /* satisfy the Vector Interrupt Controller */
}

and a "put into buffer" routine like:

void uart0_putch(char c) { /* this will HANG while buffer is full */
int newIndex;
if (uart0.TX_internal_buffer_space > 0) {
U0THR = c;
--uart0.TX_internal_buffer_space;
} else {
newIndex = uart0.TX_Insert_Index + 1;
if (uart0TX_BufferSize == newIndex)
newIndex = 0;
while (newIndex == uart0.TX_Extract_Index)
; /* hang while buffer is full */
uart0_TX_Buffer[uart0.TX_Insert_Index] = c;
uart0.TX_Insert_Index = newIndex;
if ((uart0.TX_internal_buffer_space > 0)
&& (uart0.TX_Insert_Index != uart0.TX_Extract_Index)) {
/* just missed empty interrupt! */
c = uart0_TX_Buffer[uart0.TX_Extract_Index];
newIndex = uart0.TX_Extract_Index + 1;
if (uart0TX_BufferSize == newIndex)
newIndex = 0;
uart0.TX_Extract_Index = newIndex;
U0THR = c; /* this might cause interrupt */
}
}
}

And to Sten, I don't see any mention on your website that your code
makes use of the TX FIFO. Should one just assume that
professional-quality code like yours does every possible optimisation?
Or should I browse through the code to see if it has the facilities I
might desire?
>
>if you have a 16byte-hardware-FIFO why you should not use it?!?
>I have written an interrupt-driven driver which is using configurable
>software TX and RX FIFOs between ISR and task. The task is feeding the
>TX FIFO with data and the ISR in background is feeding UART's hardware
>FIFO with 16 bytes/call (if available) from TX FIFO. It's a maximum
>efficiency with a minimum overhead.
> http://nanortos.net-attack.de/

I suppose part of the question is whether an arm with modern
peripherals is too large to be worth learning in its entirety. And
another part is that people should be able to make money by selling
their libraries and/or tools.

Regards,
Danish



An Engineer's Guide to the LPC2100 Series

Reply by Sten November 20, 20052005-11-20
Another solution... But obviously it can only handle one UART connection.

Richard wrote:
> http://www.keil.com/download/docs/288.asp
>
> --- In lpc2000@lpc2..., Sten <list@n...> wrote:
>
>>
>>Hi,
>>
>>if you have a 16byte-hardware-FIFO why you should not use it?!?
>>I have written an interrupt-driven driver which is using configurable
>>software TX and RX FIFOs between ISR and task. The task is feeding the
>>TX FIFO with data and the ISR in background is feeding UART's hardware
>>FIFO with 16 bytes/call (if available) from TX FIFO. It's a maximum
>>efficiency with a minimum overhead.
>>
>>(void) uart_write(uartNr, "Unable to encrypt! -- ", 20, 200 MSEC);
>>
>>If a task wants to transmit large data, an uart_write() call is writing
>>and sleeping to the TX FIFO until all data has been transmitted (20
>>bytes) or a timeout has been occured (200 msec).
>>
>> Sten
>>

--
/************************************************
Do you need a tiny and efficient real time
operating system (RTOS) with a preemtive
multitasking for LPC2000 or AT91SAM7?

http://nanortos.net-attack.de/

Or some open-source tools and code for LPC2000?

http://www.net-attack.de/

************************************************/



Reply by Don Lewis November 19, 20052005-11-19
You can do two power supplies if you use optical isolators.

I use a heavy current 10Amp 12 - 15 volt DC power for motors and a lowly
1Amp 9 - 12Vdc for controller. I can optionally drive it all with the
heavy power supply.

Don Lewis --- In basicx@basi..., "tieutaydoc" <tieutaydoc@y...> wrote:
>
> My problem was that I didn\'t use the bx-24 ground but a seperate power
> supply. That\'s why I couldn\'t get it to reverse with the chip. Thanks
> Tony for your help.
>




Reply by Sten November 19, 20052005-11-19
dr_danish_ali wrote:
> Hi Folks,
> I am very new to the lpc2xxx family (although I am competent at PICs) so I am looking
> at what other people do with the peripherals. My current line of investigation is the UARTs,
> which are described as "550-compatible".
> Of course I want everything i.e. interrupt-driven and externally-buffered serial input and
> output, but I don't seem to be having much success at finding example source code that
> makes good use of the hardware uart transmit buffer. Can people suggest where to look /
> what terms to google with?
>
> I have seen (for example) the drivers posted by sashi_ono but (as I understand it) they
> don't use the hardware transmit buffer. Perhaps this is related to my PIC background,
> where I previously had to scrape every last cycle of performance out of the hardware but
> that's unnecessary in the luxurious arm environment.
>
> What's the problem with that code? I'm in no position to criticise - I assume this is solid,
> working code (more than anything I've produced) but I reckon it doesn't use the 16-level
> FIFO on transmit. This is a low-level hardware issue because the THREEmpty interrupt
> occurs when the FIFO is _empty_ - not when there's space to put more characters into it.
> So you could - assuming there are that many characters in the external transmit buffer -
> pump 16 characters into U0THR in response to a THREEmpty interrupt, and thereby save
> up to 15/16 ISR call overheads.
>
> Is this worth the extra effort for an arm? It was often done in the days of the PC. The ISR
> call overhead is not very great in terms of cycles, and it might only be noticed at high baud
> rates.
>
> What do people think? I invite comments on this point.
>
> Regards,
> Danish
>

Hi,

if you have a 16byte-hardware-FIFO why you should not use it?!?
I have written an interrupt-driven driver which is using configurable
software TX and RX FIFOs between ISR and task. The task is feeding the
TX FIFO with data and the ISR in background is feeding UART's hardware
FIFO with 16 bytes/call (if available) from TX FIFO. It's a maximum
efficiency with a minimum overhead.

(void) uart_write(uartNr, "Unable to encrypt! -- ", 20, 200 MSEC);

If a task wants to transmit large data, an uart_write() call is writing
and sleeping to the TX FIFO until all data has been transmitted (20
bytes) or a timeout has been occured (200 msec).

Sten

--
/************************************************
Do you need a tiny and efficient real time
operating system (RTOS) with a preemtive
multitasking for LPC2000 or AT91SAM7?

http://nanortos.net-attack.de/

Or some open-source tools and code for LPC2000?

http://www.net-attack.de/

************************************************/



Reply by rtstofer November 19, 20052005-11-19
I haven't written a driver either but I would would start with a
rather large circular buffer. The character IO routines would write
to the circular buffer and the transmit buffer empty interrupt routine
would transfer as many chars as possible from the buffer to the FIFO.

There is always the issue of kick starting the USART if the FIFO runs
empty.



Reply by dr_danish_ali November 19, 20052005-11-19
Hi Folks,
I am very new to the lpc2xxx family (although I am competent at PICs) so I am looking
at what other people do with the peripherals. My current line of investigation is the UARTs,
which are described as "550-compatible".
Of course I want everything i.e. interrupt-driven and externally-buffered serial input and
output, but I don't seem to be having much success at finding example source code that
makes good use of the hardware uart transmit buffer. Can people suggest where to look /
what terms to google with?

I have seen (for example) the drivers posted by sashi_ono but (as I understand it) they
don't use the hardware transmit buffer. Perhaps this is related to my PIC background,
where I previously had to scrape every last cycle of performance out of the hardware but
that's unnecessary in the luxurious arm environment.

What's the problem with that code? I'm in no position to criticise - I assume this is solid,
working code (more than anything I've produced) but I reckon it doesn't use the 16-level
FIFO on transmit. This is a low-level hardware issue because the THREEmpty interrupt
occurs when the FIFO is _empty_ - not when there's space to put more characters into it.
So you could - assuming there are that many characters in the external transmit buffer -
pump 16 characters into U0THR in response to a THREEmpty interrupt, and thereby save
up to 15/16 ISR call overheads.

Is this worth the extra effort for an arm? It was often done in the days of the PC. The ISR
call overhead is not very great in terms of cycles, and it might only be noticed at high baud
rates.

What do people think? I invite comments on this point.

Regards,
Danish