ts-7000
[Top] [All Lists]

RE: [ts-7000] Re: ts 7300 LCD drÃÂver problem for HD44780

To: ts 700 <>
Subject: RE: [ts-7000] Re: ts 7300 LCD drÃÂver problem for HD44780
From: alper kalkan <>
Date: Mon, 11 Oct 2010 13:34:51 +0000


I am posting to solutıon that I get from support of embedded arm.



Alper,

There is actually a small bug in the linuxrc file, it puts one pin on the LCD header in to the wrong mode, you need to either modify your linuxrc file to have the following:

peekpoke 32 0x809300c0 0xAA #unlock software lock
peekpoke 32 0x80930080 0x88140d00 #disable DMA/enable GPIO pins

Or simply issue those commands in your application.

The 0x80930080 register currently gets set to 0x80140d00 which causes one pin of the LCD header to not function properly. If you can use our `lcdmesg` application to talk to the LCD screen, then the hardware works correctly.




Dear Kris Bahnsen,
 

 

 We are developing project in which we used TS 7260 and LCD named HD44780. Also we are using LCDproc for handling LCD.

 

I think we already bought 150 TS 7260. We decided to replace our TS 7260 with TS 7300 because of the customer new needs.

 

Our driver for LCD (HD44780) is working without problems on the TS 7260. However, when we even modify the driver for TS 7300, it does not working at all.

 

When we say modify, we simply mean that adding PORT C control for LCD_7 bit.

 

Could you help us about how to make it work ?

 

I am sending original driver for TS 7260 and modified driver for TS 7300.

 

Thanks in advance.

 

Best Regards






To:
From:
Date: Sun, 10 Oct 2010 15:27:11 +0000
Subject: RE: [ts-7000] Re: ts 7300 LCD drıver problem for HD44780

 
Thank you all guys.

I am gonna paste software here. I actually read the manual. 

And also  I am using LCDproc.

in my original code part A just was used for LCD manipulation.

I simply modify them for LCD_7 for PORT_C . 

it was like this 


////////////////////////////////////////////////////////////
/ Set port A all outputs to write data
   *paddr = 0xFF;
   
   // Put value to write on port A
   *padr = ch;

//////////////////////////////////////////////
 
now it looks like this

////////////////////////////////////////////////////////////
*paddr = *paddr | PAMASK; //set port A to outputs
   *pcddr = *pcddr | PCMASK; //set port C to outputs
   
   
    *padr = *padr & ~PAMASK;
*pcdr = *pcdr & ~PCMASK;
*padr = *padr | (ch & PAMASK);
*pcdr = *pcdr | ((ch >> 7) & PCMASK);
/////////////////////////////////////////////////////////////////




Orginal Driver for TS7260 

/////////////////////////////////////////////////////////////////////////////////////////////

/*
 * Driver module for Hitachi HD44780 based LCD displays.
 * The LCD is operated in it's 8 bit-mode to be connected to the ts7200 LCD Port
 *
 * Copyright (c)  1999, 1995 Benjamin Tse <>
 *                2001 Joris Robijn <>
 *
 * Created modular driver Dec 1999, Benjamin Tse <>
 *
 * Modified for Technologix Systems TS-72xx ARM CPU series by Kym B Newbery
 *
 * Based on the code in the lcdtime package which uses the LCD
 * controller in its 8-bit mode.
 *
 * This file is released under the GNU General Public License. Refer to the
 * COPYING file distributed with this package.
 */

#include "hd44780-ts7200.h"
#include "hd44780-low.h"
#include "report.h"

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <termios.h>

#define GPIOBASE 0x80840000
#define PADR     0
#define PADDR   (0x10 / sizeof(unsigned int))
#define PAMASK   0x7F  
#define PHDR    (0x40 / sizeof(unsigned int))
#define PHDDR   (0x44 / sizeof(unsigned int))

#define LCD_EN   0x08  
#define LCD_RS   0x10
#define LCD_WR   0x20

volatile unsigned int *gpio;
volatile unsigned int *phdr;
volatile unsigned int *phddr;
volatile unsigned int *padr;
volatile unsigned int *paddr;

#define DEFAULT_KEYPAD_DEVICE "/dev/ttyTS2"

// Generally, any function that accesses the LCD control lines needs to be
// implemented separately for each HW design. This is typically (but not
// restricted to):
// HD44780_senddata
// HD44780_readkeypad

void ts7200_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch);
void ts7200_HD44780_backlight (PrivateData *p, unsigned char state);
unsigned char ts7200_HD44780_scankeypad (PrivateData *p);

// initialise the driver
int hd_init_ts7200 (Driver *drvthis)
{
   int memfd;   
   PrivateData *p = (PrivateData*) drvthis->private_data;
   
   struct termios portset;
   char keypad_device[256] = DEFAULT_KEYPAD_DEVICE;
   
   HD44780_functions *hd44780_functions = p->hd44780_functions;

   // Read config file
   
   /****************************************************************/
   
   strncpy(keypad_device, 
  drvthis->config_get_string(drvthis->name, "Keypad_Device", 0, DEFAULT_KEYPAD_DEVICE), 
  sizeof(keypad_device));
   keypad_device[sizeof(keypad_device)-1] = '\0';
   report(RPT_INFO, "HD44780: TS7200 KEYPAD : using device %s", keypad_device);
   
   // setup port and open it
   p->fd = open(keypad_device, O_RDWR | O_NOCTTY);
   if (p->fd == -1)
     {
report(RPT_ERR, "HD44780 : TS7200 : Could not open device %s (%s)", 
      keypad_device, strerror(errno));
return -1;
     }
   
   tcgetattr(p->fd, &portset);
   
   portset.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
   portset.c_iflag &= ~OPOST;
   portset.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN );
   portset.c_cflag &= ~(CSIZE | PARENB | CRTSCTS);
   portset.c_cflag |= (CS8 | CREAD | CLOCAL);
   portset.c_cc[VMIN] = 1;
   portset.c_cc[VTIME] = 3;
   
   // input port speed 9600
   cfsetispeed(&portset, B9600);
   
   // Force settings now
   tcsetattr(p->fd, TCSANOW, &portset);
 
   /**************************************************************/
   
   report(RPT_INFO, "HD44780: TS7200 LCD : initialising lcd port");

   // Get I/O Access
   memfd = open("/dev/mem", O_RDWR | O_SYNC);
   gpio = (unsigned int *)mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, memfd, GPIOBASE);
   
   phdr  = &gpio[PHDR];
   phddr = &gpio[PHDDR]; 
   padr  = &gpio[PADR];
   paddr = &gpio[PADDR];
      
   // Port H - Bit 3 = LCD_EN, output
   //          Bit 4 = LCD_RS, output
   //          Bit 5 = LCD_WR, output
   *phddr |= (LCD_EN | LCD_RS | LCD_WR);
   
   // de-assert EN, deassert RS
   *phdr  &= ~(LCD_EN | LCD_RS);
   
   // Set port A (databus) to inputs
   *paddr = 0x00;
   
   report(RPT_INFO, "HD44780: TS7200 LCD : Done Initialising..");
   
   hd44780_functions->senddata = ts7200_HD44780_senddata;
   hd44780_functions->backlight = ts7200_HD44780_backlight;
   hd44780_functions->scankeypad = ts7200_HD44780_scankeypad;
   
   // setup the lcd in 8 bit mode
   hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT);
   hd44780_functions->uPause (p, 4100);
   hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT);
   hd44780_functions->uPause (p, 100);
   hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT | TWOLINE | SMALLCHAR);
   hd44780_functions->uPause (p, 40);

   common_init (p, IF_8BIT);

   if (p->have_keypad) {
      // Remember which input lines are stuck
      p->stuckinputs = ts7200_HD44780_scankeypad (p);
   }

   return 0;
}

// ts7200_HD44780_senddata
void ts7200_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
{
   //
   // NOTE : May want to optimise the timing in this section
   // 
   
   // set LCD_RS
   if (flags == RS_INSTR)
     *phdr &= ~(LCD_RS);   // RS = low for control registers
   else if (flags == RS_DATA)
     *phdr |= LCD_RS;      // RS = high for data ram
     
   // set LCD_RW low for write cycle
   *phdr &= ~(LCD_WR);
   
   // Set port A all outputs to write data
   *paddr = 0xFF;
   
   // Put value to write on port A
   *padr = ch;
   
   // pause for min 100ns
   p->hd44780_functions->uPause(p, 1);
   
   // Set LCD_EN
   *phdr |= LCD_EN;
   
   // Pause for min 500ns
   p->hd44780_functions->uPause(p, 1);
   
   // clear LCD_EN. Data latched on falling edge
   *phdr &= ~(LCD_EN);
   
   // pause for minimum
   // p->hd44780_functions->uPause(p, 1);
}

void ts7200_HD44780_backlight (PrivateData *p, unsigned char state)
{
   /* No Backlight Control - Yet */
}

unsigned char ts7200_HD44780_scankeypad (PrivateData *p)
{
   char in = 0;
   unsigned char keycode = 0;
   struct pollfd fds[1];
   
   fds[0].fd = p->fd;
   fds[0].events = POLLIN;
   fds[0].revents = 0;
   poll(fds,1,0);
   if (fds[0].revents == 0)
     return (unsigned char)NULL;
   
   read(p->fd, &in, 1); 
   
   if (in == '\0')
     return (unsigned char)NULL;
   else   
     {
switch(in)
 {     
    // Mapping for RT Nollett serial 4 x 4 keypad
    // row 1
  case '1' : keycode = 0x11; break;
  case '2' : keycode = 0x12; break;
  case '3' : keycode = 0x13; break;
  case 'A' : keycode = 0x14; break;
    // row 2
  case '4' : keycode = 0x21; break;
  case '5' : keycode = 0x22; break;
  case '6' : keycode = 0x23; break;
  case 'B' : keycode = 0x24; break;
    // row 3
  case '7' : keycode = 0x31; break;
  case '8' : keycode = 0x32; break;
  case '9' : keycode = 0x33; break;
  case 'C' : keycode = 0x34; break;
    // row 4
  case 0x08 : keycode = 0x41; break;
  case '0'  : keycode = 0x42; break;
  case 0x0D : keycode = 0x43; break;
  case 'D'  : keycode = 0x44; break;
  default  : keycode = 0; break;
 }
return keycode;
     }
   
   return NULL;
}
 
/////////////////////////////////////////////////////////////////////////////////////////////

modified code for TS7300

/*
 * Driver module for Hitachi HD44780 based LCD displays.
 * The LCD is operated in it's 8 bit-mode to be connected to the ts7200 LCD Port
 *
 * Copyright (c)  1999, 1995 Benjamin Tse <>
 *                2001 Joris Robijn <>
 *
 * Created modular driver Dec 1999, Benjamin Tse <>
 *
 * Modified for Technologix Systems TS-72xx ARM CPU series by Kym B Newbery
 *
 * Based on the code in the lcdtime package which uses the LCD
 * controller in its 8-bit mode.
 *
 * This file is released under the GNU General Public License. Refer to the
 * COPYING file distributed with this package.
 */

#include "hd44780-ts7200.h"
#include "hd44780-low.h"
#include "report.h"


#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <termios.h>

#define GPIOBASE 0x80840000
#define PADR     0
#define PADDR   (0x10 / sizeof(unsigned int))
#define PAMASK   0x7F  
#define PHDR    (0x40 / sizeof(unsigned int))
#define PHDDR   (0x44 / sizeof(unsigned int))

//Port C 
#define PCDR    (0x08 / sizeof(unsigned int))
#define PCDDR   (0x18 / sizeof(unsigned int))
#define PCMASK  0x01 

#define LCD_EN   0x08  
#define LCD_RS   0x10
#define LCD_WR   0x20

//GPIO KEYPAD
// Use 0 for busy-wait
#define POLL_FREQ       30

// Use 0 for busy-wait
#define DEBOUNCE_POLL_FREQ      256

#define DEBOUNCE_STABLE_MS      10
#define REPEAT_FREQ     30
#define REPEAT_DELAY_MS 500

// struct timeval utility macros
#define TV_ADD_US(x, y) { \
        (x).tv_usec += (y); \
        (x).tv_sec += (x).tv_usec / 1000000; \
        (x).tv_usec = (x).tv_usec % 1000000; \
}


#define TV_GTE(x, y) ((x).tv_sec > (y).tv_sec || ((x).tv_sec == (y).tv_sec && \
        (x).tv_usec >= (y).tv_usec))

#define TV_ELAPSED_US(x, y)     (((x).tv_sec - (y).tv_sec) * 1000000 + \
        ((x).tv_usec - (y).tv_usec))

volatile unsigned int *dir, *dat;
unsigned int lastkey = -1;
struct timeval repeat_time;



volatile unsigned int *gpio;
volatile unsigned int *phdr;
volatile unsigned int *phddr;
volatile unsigned int *padr;
volatile unsigned int *paddr;
volatile unsigned int *pcdr;
volatile unsigned int *pcddr;


unsigned int changed_key;

#define DEFAULT_KEYPAD_DEVICE "/dev/mem"

// Generally, any function that accesses the LCD control lines needs to be
// implemented separately for each HW design. This is typically (but not
// restricted to):
// HD44780_senddata
// HD44780_readkeypad

void ts7200_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch);
void ts7200_HD44780_backlight (PrivateData *p, unsigned char state);
unsigned char ts7200_HD44780_scankeypad (PrivateData *p);

// GPIO keypad routines
unsigned int get_keys(void);
unsigned int debounce(unsigned int);
void keypad_event(unsigned int, unsigned int);


// initialise the driver
int hd_init_ts7200 (Driver *drvthis)
{
   int memfd;   
   PrivateData *p = (PrivateData*) drvthis->private_data;
   
   struct termios portset;
   char keypad_device[256] = DEFAULT_KEYPAD_DEVICE;
   
   HD44780_functions *hd44780_functions = p->hd44780_functions;

   // Read config file
   
   /****************************************************************/
   
   strncpy(keypad_device, 
  drvthis->config_get_string(drvthis->name, "Keypad_Device", 0, DEFAULT_KEYPAD_DEVICE), 
  sizeof(keypad_device));
   keypad_device[sizeof(keypad_device)-1] = '\0';
   report(RPT_INFO, "HD44780: TS7200 KEYPAD : using device %s", keypad_device);
   
   // setup port and open it
   p->fd = open(keypad_device, O_RDWR | O_SYNC);
   if (p->fd == -1)
     {
report(RPT_ERR, "HD44780 : TS7200 : Could not open device %s (%s)", 
      keypad_device, strerror(errno));
return -1;
     }
   
unsigned char *start;
  start = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, p->fd, 0x80840000);
        dat = (unsigned int *)(start + 0x4);
        dir = (unsigned int *)(start + 0x14);
        *dir = 0xf;
 
   /**************************************************************/
   
   report(RPT_INFO, "HD44780: TS7200 LCD : initialising lcd port");

   // Get I/O Access
   memfd = open("/dev/mem", O_RDWR | O_SYNC);
   gpio = (unsigned int *)mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, memfd, GPIOBASE);
   
   phdr  = &gpio[PHDR];  
   padr  = &gpio[PADR];
   paddr = &gpio[PADDR];
      
   pcdr = &gpio[PCDR]; //C Portu için yapýlan..
   pcddr = &gpio[PCDDR];
 
   phddr = &gpio[PHDDR]; 
 
   // Port H - Bit 3 = LCD_EN, output
   //          Bit 4 = LCD_RS, output
   //          Bit 5 = LCD_WR, output
   //*phddr |= (LCD_EN | LCD_RS | LCD_WR);
   *phddr |= 0x38; // bits 3:5 of port H to outputs
   
   // de-assert EN, deassert RS
   //*phdr  &= ~(LCD_EN | LCD_RS);
   *phdr &= ~0x18; // de-assert EN, de-assert RS
   
   // Set port A (databus) to inputs
   //*paddr = 0x00;
   *paddr & ~PAMASK;  // port A to inputs
   *pcddr & ~PCMASK;  // port C to inputs
   
   
   hd44780_functions->senddata = ts7200_HD44780_senddata;
   //hd44780_functions->backlight = ts7200_HD44780_backlight;
   hd44780_functions->scankeypad = ts7200_HD44780_scankeypad;
   /*
   // setup the lcd in 8 bit mode
   hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT);
   hd44780_functions->uPause (p, 4100);
   hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT);
   hd44780_functions->uPause (p, 100);
   hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT | TWOLINE | SMALLCHAR);
   hd44780_functions->uPause (p, 40);

   common_init (p, IF_8BIT);
   */

   if (p->have_keypad) {
      // Remember which input lines are stuck
      p->stuckinputs = ts7200_HD44780_scankeypad (p);
   }

   return 0;
}

// ts7200_HD44780_senddata
void ts7200_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch)
{
   
   //
   // NOTE : May want to optimise the timing in this section
   //
   // set LCD_RS
   if (flags == RS_INSTR)
     *phdr &= ~(LCD_RS);   // RS = low for control registers
   else if (flags == RS_DATA)
     *phdr |= LCD_RS;      // RS = high for data ram
     
   // set LCD_RW low for write cycle
   *phdr &= ~(LCD_WR);
   
   // Set port A all outputs to write data
   //*paddr = 0xFF;
   
   // Put value to write on port A and C
   //*padr = ch;
   *paddr = *paddr | PAMASK; //set port A to outputs
   *pcddr = *pcddr | PCMASK; //set port C to outputs
   
   
    *padr = *padr & ~PAMASK;
*pcdr = *pcdr & ~PCMASK;
*padr = *padr | (ch & PAMASK);
*pcdr = *pcdr | ((ch >> 7) & PCMASK);
   // pause for min 100ns
   p->hd44780_functions->uPause(p, 1);
   
   // Set LCD_EN
   *phdr |= LCD_EN;
   
   // Pause for min 500ns
   p->hd44780_functions->uPause(p, 1);
   
   // clear LCD_EN. Data latched on falling edge
   *phdr &= ~(LCD_EN);
  

   // pause for minimum
   // p->hd44780_functions->uPause(p, 1);
}

void ts7200_HD44780_backlight (PrivateData *p, unsigned char state)
{
   /* No Backlight Control - Yet */
}

unsigned char ts7200_HD44780_scankeypad (PrivateData *p)
{
   char in = 0;
   unsigned char keycode = 0;
   unsigned int k = 0, pressed = 0;
 k = get_keys();
                changed_key = pressed ^ k;
                if (changed_key) {
                        k = debounce(changed_key);
                        changed_key &= pressed ^ k;
                }
                if (changed_key) {
                        keypad_event(changed_key & k, changed_key & pressed);
                        pressed &= ~(changed_key & pressed);
                        pressed |= changed_key & k;
                } else {
return 0;
}
 
   in = lastkey;
   printf("%c", lastkey);
   fflush(stdout); 
  // report(RPT_INFO, "HD44780: TS7200 KEYPAD : keypress : %c", lastkey);
   if (in == '\0')
     return (unsigned char)0;
   else   
     {
switch(in)
 {     
    // Mapping for RT Nollett serial 4 x 4 keypad
    // row 1
  case '1' : keycode = 0x11; break;
  case '2' : keycode = 0x12; break;
  case '3' : keycode = 0x13; break;
  case 'A' : keycode = 0x14; break;
    // row 2
  case '4' : keycode = 0x21; break;
  case '5' : keycode = 0x22; break;
  case '6' : keycode = 0x23; break;
  case 'B' : keycode = 0x24; break;
    // row 3
  case '7' : keycode = 0x31; break;
  case '8' : keycode = 0x32; break;
  case '9' : keycode = 0x33; break;
  case 'C' : keycode = 0x34; break;
    // row 4
  case 0x08 : keycode = 0x41; break;
  case '0'  : keycode = 0x42; break;
  case 0x0D : keycode = 0x43; break;
  case 'D'  : keycode = 0x44; break;
  default  : keycode = 0; break;
 }
return keycode;
     }
   
   return NULL;
}

void keypad_event(unsigned int on, unsigned int off) {
        unsigned int i;
        unsigned char keys[] = {
          '1', '2', '3', 'A',
          '4', '5', '6', 'B',
          '7', '8', '9', 'C',
          '*', '0', '#', 'D'
        };

        lastkey = -1;
        for(i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
                if (on & (1 << i)) {
                        printf("%c", keys[i]);
                        lastkey = keys[i];
                }
        }
 if (REPEAT_DELAY_MS && lastkey != -1) {
                gettimeofday(&repeat_time, NULL);
                TV_ADD_US(repeat_time, REPEAT_DELAY_MS * 1000);
        }
}

unsigned int get_keys(void) {
        unsigned int pos, on = 0;

        for(pos = 0; pos < 4; pos++) {
                *dat = ~(1 << pos);
                on |= (~(*dat >> 4) & 0xf) << (4 * pos);
        }
        return on;
}
// debounce will return when masked keys have been stable for DEBOUNCE_STABLE_MS
unsigned int debounce(unsigned int mask) {
        struct timeval verystart, start, now;
        unsigned int last_val, val;

        last_val = get_keys();
        gettimeofday(&verystart, NULL);
        memcpy(&start, &verystart, sizeof(struct timeval));
        do {
                val = get_keys();
                gettimeofday(&now, NULL);
                if ((val ^ last_val) & mask)
                  memcpy(&start, &now, sizeof(struct timeval));
                last_val = val;
                if (DEBOUNCE_POLL_FREQ) usleep(1000000 / DEBOUNCE_POLL_FREQ);
        } while (TV_ELAPSED_US(now, start) <= (DEBOUNCE_STABLE_MS * 1000));

        return val;
}
//////////////////////////////////////////////////////////////////////////////////
   


To:
From:
Date: Sun, 10 Oct 2010 11:49:25 +0100
Subject: Re: [ts-7000] Re: ts 7300 LCD drıver problem for HD44780

 

Hi

> > > Did you write the software yourself? Or did you use some one else's code?
> > > If so can you give a url of where you got the code from?
> >
> > The attachments should be stripped by Yahoo! and put into the files
> > section I believe.
> >
> Hi I've just uploaded a software which is called metodolcdyteclado.rar,
> you may serve

Sorry I've not looked at the software, but I guess that the problem is that
you have not read the manual for the ts7300 correctly. On page 44 of the
manual it says...

"Note
On the TS-7300 only, the LCD_7 (eight data bit) is accessed on bit 0
of Port C (address location 0x8084_0008 is Port C Data Register and
0x8084_0018 is Port C Directon Register)."

This means that bits 0-6 are on Port A - as in the ts7200. If all the data
you are sending to the LCD has the top bit zero, then you might get a way
with tieing the bit7 of the lcd to ground and just driving the display with
the standard program. If however you are sending data with the top bit set,
then the code will need extensive revision to send bits 0-6 over portA and
bit 7 to port C bit 0.[1]

cheers
Jim

[1] As you would have to do if you were using the LCD in 4 bit data mode





__._,_.___


Your email settings: Individual Email|Traditional
Change settings via the Web (Yahoo! ID required)
Change settings via email: =Email Delivery: Digest | m("yahoogroups.com?subject","ts-7000-fullfeatured");=Change Delivery Format: Fully Featured">Switch to Fully Featured
Visit Your Group | Yahoo! Groups Terms of Use | =Unsubscribe

__,_._,___
<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU