[En-Nut-Discussion] Writting a new UART device -- I solved the problem , very weird

Harald Kipp harald.kipp at egnite.de
Sun Oct 20 13:12:57 CEST 2002


Avex,

I'm afraid I'm not able to track down the problem
with your code snippets. But I guess you ran out
of memory. You should check the result of NutHeapAlloc
and return an error, if it gives 0.

The reason for using 256 byte buffers in the UART
driver is, that the index counters will automatically
wrap, because they are unsigned character types.
Note that uartavr.c handles buffering inside interrupts.
Using additional code like

if(idx > limit) idx = 0;

within interrupt routines degrades system performance.
Things changed a bit for the ATmega128, which got an
additional buffer byte in the UART itself. The 16550
is even more advanced. But I do not have an idea right
now, how to use this to avoid generating interrupts
with each character received.

On the other hand the UART driver code was based on
the ATmega103 running at 3.6864 MHz only. I wrote
a sample UART driver using configurable buffer sizes.
Performance was OK, even with concurrently using
both ATmega128 UARTs. But final integration would
require some major changes in the Nut/OS driver
interface, to keep it usable for the ATmega103.

Harald

At 17:23 18.10.02 +0800, you wrote:
>Hi Harald,
>
>I solved the problem I mentioned before.
>I modified the file ifstream.h, however, I still dont know WHY ?
>
>The code I modified :
>
>struct _IFSTREAM {
>     int  (*if_input)(NUTDEVICE *);
>     int  (*if_output)(NUTDEVICE *);
>     int  (*if_flush)(NUTDEVICE *);
>     volatile u_char if_rx_idx;
>     u_char if_rd_idx;
>     volatile u_char if_tx_idx;
>     u_char if_wr_idx;
>     volatile u_char if_tx_act;
>     u_char if_last_eol;
>     u_char if_rx_buf[64];         <-- I changed the number from 256 to 64
>     u_char if_tx_buf[256];       <-- To change this digit made the same 
> problem
>};
>
>Would you kindly to tell me why ?  :  )
>
>Avex
>
> > Hi Harald Kipp ,
> >
> > I am writting a 4-port driver using st16c554 chip on ethernut
> > platform. I refer to uartavr.c & uarts.c and wrote a program
> > following the format like these 2 files.  However, I found, I
> > can't open 4 ports at the same time. To describe it clearly, I
> > couldn't open more than 2 ports concurrently. 2 ports is the
> > limitation which I can open at the same time.To open the
> > ports of uart one by one , the operation is correct. However,
> >  if I open it more than 2, it means opening 3 ports concurrently,
> > it went wrong.
> >
> > I trace it and I found the problem is at
> > NutHeapAllocClear(sizeof(IFSTREAM));  , shown as follow.
> >
> > int UartStInit(NUTDEVICE *dev)
> > {
> >     volatile IFSTREAM *ifs;
> >     volatile UARTSTDCB *dcb;
> >     volatile u_char lcr_byte  = 0;
> >      volatile u_char fifo_byte = 0;
> >      volatile u_char *base;    // reference: dev\eth0rtl.c
> >
> >     // Check for valid device.
> >     if (dev->dev_type != IFTYP_STREAM)
> >         return -1;
> >
> > //  #define COMA 0x8000 , int0
> > //  #define COMB 0x8008 , int1
> > //  #define COMC 0x8010 , int2
> > //  #define COMD 0x8018 , int3
> >     base = (u_char *)(dev->dev_base); // reference: dev\eth0rtl.c
> >
> >     // Initialize interface control block.
> >     if (dev->dev_icb == 0)
> >         // Problem : If  I alloc more then 2 times, the data which 
> ports send out will
> >         // not be correct
> >         dev->dev_icb = NutHeapAllocClear(sizeof(IFSTREAM));    <-- this 
> line, The Problems
> >
> >     ifs = dev->dev_icb;
> >     ifs->if_input  = UartStInput;
> >     ifs->if_output = UartStOutput;
> >     ifs->if_flush  = UartStFlush;
> >     // Initialize driver control block.
> > .................................................................
> >
> >     return 0;
> > }
>
>
>-----------------------------------------------------------------
>< ¨C¤Ñ³£ Yahoo!©_¼¯ >  www.yahoo.com.tw
>_______________________________________________
>En-Nut-Discussion mailing list
>En-Nut-Discussion at egnite.de
>http://www.egnite.de/mailman/listinfo/en-nut-discussion




More information about the En-Nut-Discussion mailing list