- Added the Sensinode platform programming tools to /tools

This commit is contained in:
zdshelby 2009-09-09 09:48:16 +00:00
parent 83988ef554
commit fc237101be
24 changed files with 5847 additions and 0 deletions

View file

@ -0,0 +1,43 @@
EXE_MAKE=$(notdir $(shell which "make.exe" 2>/dev/null))
ifeq "$(EXE_MAKE)" "make.exe"
PLATFORM=windows
else
PLATFORM=linux
endif
OBJECTS = ihex.o $(PLATFORM)/port.o programmer.o cdi_program.o
SUBDIRS =
ifeq "$(PLATFORM)" "linux"
CFLAGS = -Wall -D_REENTRANT -I.
LDFLAGS = -L. -D_REENTRANT -lpthread
SUFFIX=
else
CFLAGS=-I. -I../nano_usb_programmer/ftdi_win32
CFLAGS+= -L. -L../nano_usb_programmer/ftdi_win32 -DPLATFORM_WINDOWS
CFLAGS+= -mwin32
LDFLAGS=../nano_usb_programmer/ftdi_win32/ftd2xx.lib -lkernel32
SUFFIX=.exe
endif
TARGET = nano_programmer$(SUFFIX)
all: binary
binary: $(TARGET)
strip $(TARGET)
$(TARGET): $(OBJECTS)
gcc -o $(TARGET) $(OBJECTS) $(LDFLAGS)
.c.o:
gcc -c -o $(<:.c=.o) -O2 -Wall $(CFLAGS) $<
platform-test:
@echo $(PLATFORM)
old-strip:
if [ -x $(TARGET).exe ]; then $(PLATFORM)strip $(TARGET).exe; else $(PLATFORM)strip $(TARGET); fi
clean:
rm -f $(TARGET) $(OBJECTS)

View file

@ -0,0 +1,34 @@
Nano Programmer
Programming tool for the Sensinode Nano series using Dxxx development boards.
Copyright 2007-2008 Sensinode Ltd.
1a - Installation (Linux)
No external libraries required.
1b - Installation (Windows/Cygwin)
Installation procedure:
See the nano_usb_programmer README file on how to install FTDI library
for nano_usb_programmer. The nano_programmer build system will fetch
the library from there.
2 - Usage
Usage info for the Nano Programmer is available with command
./nano_programmer --help. Note that use might require root/administrator privileges
depending on system configuration.
3 - Known problems
Occasional timing failures resulting in "Reinit failed."-messages do come
up in some PC configurations. If you experience programming failures (the programmer
is not able to recover), please report your system configuration to Sensinode.
On Linux, it is known that the "brltty" program causes problems with the FTDI
serial driver. Uninstalling brltty resolves the problem.
4 - README Version
v1.3 2008-01-31 Martti Huttunen Multi-platform build and created instructions

View file

@ -0,0 +1,607 @@
/*
NanoStack: MCU software and PC tools for IP-based wireless sensor networking.
Copyright (C) 2006-2007 Sensinode Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Address:
Sensinode Ltd.
Teknologiantie 6
90570 Oulu, Finland
E-mail:
info@sensinode.com
*/
#include <unistd.h>
#include <getopt.h>
#include <strings.h>
#include "port.h"
#include "programmer.h"
#include "ihex.h"
#include <stdio.h>
extern void crc_add(unsigned char *crc, unsigned char byte);
int cdi_page_write(port_t *port, unsigned long page_addr, unsigned char *page_buffer);
int cdi_write(port_t *port, conf_opts_t *conf, FILE *ihex);
int cdi_programmer(conf_opts_t *conf, char *filename)
{
int error = 0;
port_t *port = 0;
unsigned char buffer[256];
int length = 0;
FILE *ihex = 0;
error = programmer_init(conf->device, &port);
if (error < 0)
{
return error;
}
if((!error) && (conf->action != 'b'))
{
length = port_write_echo(port, "CDI\r");
bzero(buffer, sizeof(buffer));
if (length >= 4)
{
length = port_readline(port, buffer, sizeof(buffer), 100);
}
else length = 0;
if(memcmp(buffer, "OK", 2) == 0)
{
error = 0;
}
else
{
printf("Programming mode selection failed.\n");
error = -1;
}
}
if((!error) && (conf->action != 'b'))
{
printf("Initialize.\n");
// Succesfully in mode 1
sleep(1);
port_write_echo(port, "i\r");
bzero(buffer, 256);
length = port_readline(port, buffer, sizeof(buffer), 100);
if(memcmp(buffer, "85", 2) == 0)
{ /*Found CC2430 device*/
printf("Found CC2430 device revision %c%c.\n", buffer[2], buffer[3]);
}
else if (memcmp(buffer, "89", 2) == 0)
{
printf("Found CC2431 device revision %c%c.\n", buffer[2], buffer[3]);
}
else
{
printf("CC2430 not found.\n");
error = -1;
}
}
if (error) conf->action = ' ';
switch(conf->action)
{
case 'e':
// Erase programming
port_write_echo(port, "e\r");
bzero(buffer, 256);
length = port_readline(port, buffer, sizeof(buffer), 100);
if(memcmp(buffer, "OK", 2) == 0)
{
// Erase successful
printf("Erase successful.\n");
error = 0;
}
else
{
// Erase failed
printf("Erase failed: %s.\n", buffer);
error = -1;
}
if ((conf->action != 'P') || error)
break;
case 'P':
case 'w':
ihex = fopen(conf->ihex_file, "rb");
if(ihex == NULL)
{
printf("Failed to open ihex file %s.\n", conf->ihex_file);
error = -1;
}
else error = 0;
if (!error)
{
error = cdi_write(port, conf, ihex);
if (error) printf("Programming failed.\n");
}
if (ihex != NULL) fclose(ihex);
break;
case 'b':
length = port_write_echo(port, "V\r");
bzero(buffer, sizeof(buffer));
if (length >= 2)
{
length = port_readline(port, buffer, sizeof(buffer), 100);
}
else length = 0;
if(length > 4)
{
buffer[length] = 0;
printf("BIOS: %s\n", buffer);
error = 0;
}
else
{
printf("Failed to get BIOS version. Upgrade recommended.\n");
error = -1;
}
break;
case 'v':
break;
case 'r':
ihex = fopen(conf->ihex_file, "wb");
if(ihex == NULL)
{
printf("Failed to open ihex file %s.\n", conf->ihex_file);
error = -1;
}
else
{
port_write_echo(port, "a000000\r");
bzero(buffer, sizeof(buffer));
length = port_readline(port, buffer, sizeof(buffer), 200);
if (length <0) length = 0;
if(memcmp(buffer, "OK", 2) == 0)
{
uint32_t address = 0;
uint8_t check = 0;
for (address = 0; address < 128*1024; address += 64)
{
uint8_t i;
if ((address) && ((address & 0xFFFF)==0))
{
fprintf(ihex, ":02000004%4.4X%2.2X\r\n",
(int)(address>>16), (int)(0xFA-(address>>16)));
}
port_write_echo(port, "r\r");
bzero(buffer, 256);
length = 0;
while (length < 64)
{
length += port_readline(port, &buffer[length], sizeof(buffer)-length, 100);
}
for (i=0; i<64; i++)
{
if ((i & 0x0F) == 0)
{
check = 0;
check -= 0x10;
check -= (uint8_t) (address >> 8);
check -= (uint8_t) (address + i);
printf("%4.4X", (int) address + i);
fprintf(ihex, ":10%4.4X00", (int) (address + i) & 0xFFFF);
}
fprintf(ihex, "%2.2X", buffer[i]);
check -= buffer[i];
if ((i & 0x0F) == 0x0F)
{
fprintf(ihex, "%2.2X\r\n", check);
if (i > 0x30) printf("\n");
else printf(" ");
}
}
}
fprintf(ihex, ":00000001FF\r\n");
}
else
{
printf("Failed to set read address.\n");
error = -1;
}
fclose(ihex);
}
break;
/*skip for error case*/
case ' ':
break;
case 'm':
port_write_echo(port, "a01F800\r");
bzero(buffer, sizeof(buffer));
length = port_readline(port, buffer, sizeof(buffer), 200);
if (length <0) length = 0;
if(memcmp(buffer, "OK", 2) == 0)
{
uint8_t i;
uint32_t address = 0;
for (address = 0x01F800; address < 128*1024; address += 64)
{
port_write_echo(port, "r\r");
bzero(buffer, 256);
length = 0;
while (length < 64)
{
length += port_readline(port, &buffer[length], sizeof(buffer)-length, 100);
}
if ((address & 0xff) == 0)
{ printf(".");
fflush(stdout);
}
}
printf("\nDevice MAC: ");
for (i=56; i<64; i++)
{
if (i != 56) printf(":");
printf("%2.2X", buffer[i]);
}
printf("\n");
}
break;
case 'Q':
port_write_echo(port, "a01F800\r");
bzero(buffer, sizeof(buffer));
length = port_readline(port, buffer, sizeof(buffer), 200);
if (length <0) length = 0;
if(memcmp(buffer, "OK", 2) == 0)
{
uint8_t p_buffer[2048];
int error;
memset(p_buffer, 0xff, sizeof(p_buffer));
memcpy(&p_buffer[2040], conf->write_mac, 8);
printf("\rWriting MAC: ");
error = cdi_page_write(port, 0x01F800, p_buffer);
if (!error)
{
printf("Write complete.\n");
}
else
{
printf("Write failed.\n");
}
}
break;
default:
printf("Unknown CDI action.\n");
break;
}
printf("Close programmer.\n");
usleep(100000);
port_write_echo(port, "q\r");
programmer_close(port);
return error;
}
int cdi_write(port_t *port, conf_opts_t *conf, FILE *ihex)
{
int error = 0;
unsigned char buffer[256];
int length;
int i;
int pages;
unsigned long ext_addr=0;
unsigned short int addr=0;
unsigned char page_buffer[128*1024];
unsigned char page_table[64];
bzero(buffer, sizeof(buffer));
/*initialize page data*/
memset(page_table, 0, 64);
memset(page_buffer, 0xFF, sizeof(page_buffer));
pages = 0;
error = 0;
if (conf->page_mode == PAGE_UNDEFINED)
{
int retval;
while((!error) && ((retval = fscanf(ihex, "%s", buffer)) == 1) )
{
unsigned char data_len = 0;
if (memcmp(&buffer[7], "00", 2) == 0)
{ /*Data record*/
}
else if (memcmp(&buffer[7], "01", 2) == 0)
{ /*end file*/
printf("\nFile read complete.\n");
break;
}
else if (memcmp(&buffer[7], "04", 2) == 0)
{
sscanf((char *)&(buffer[3]),"%4hx", &addr);
sscanf((char *)&(buffer[9]),"%4lx", &ext_addr);
if (ext_addr >= 0x0002)
{
conf->page_mode = PAGE_SDCC;
}
else
{
if (conf->page_mode == PAGE_UNDEFINED) conf->page_mode = PAGE_LINEAR;
}
}
}
if (retval == -1)
{
printf("Read error\n");
return -1;
}
rewind(ihex);
retval = 0;
error = 0;
}
switch (conf->page_mode)
{
case PAGE_SDCC:
printf("SDCC banked file.\n");
break;
case PAGE_LINEAR:
printf("Linear banked file.\n");
break;
case PAGE_UNDEFINED:
printf("Non-banked file, assuming linear.\n");
conf->page_mode = PAGE_LINEAR;
break;
}
while( (fscanf(ihex, "%s", buffer) == 1) && !error)
{
unsigned char data_len = 0;
if (memcmp(&buffer[7], "00", 2) == 0)
{ /*Data record*/
i=0;
sscanf((char *)&buffer[1], "%2hhx", &data_len);
sscanf((char *)&(buffer[3]),"%4hx", &addr);
while(i<data_len)
{
uint32_t absolute_address = ext_addr+addr+i;
if (page_table[absolute_address/2048] == 0)
{
page_table[absolute_address/2048] = 1;
pages++;
}
sscanf((char *)&buffer[2*i+9], "%2hhx", &page_buffer[absolute_address]);
i++;
}
}
else if (memcmp(&buffer[7], "01", 2) == 0)
{ /*end file*/
printf("\nFile read complete.\n");
printf("Writing %d pages.\n", pages);
break;
}
else if (memcmp(&buffer[7], "04", 2) == 0)
{
sscanf((char *)&(buffer[3]),"%4hx", &addr);
sscanf((char *)&(buffer[9]),"%4lx", &ext_addr);
if (conf->page_mode == PAGE_SDCC)
{
if (ext_addr) ext_addr--;
ext_addr *= 0x8000;
}
else
{
ext_addr *= 0x10000;
}
printf("\rExtended page address: 0x%8.8lX\r", ext_addr);
}
}
if (pages)
{
int retry = 0;
// Successfully in mode 3 (programming)
printf("Starting programming.\n");
error = 0;
for (i=0; i<64; i++)
{
if (page_table[i] != 0)
{
ext_addr = 2048*i;
bzero(buffer, sizeof(buffer));
// Write the start address and check return
usleep(3000);
sprintf((char *)buffer, "a%6.6lX\r", ext_addr);
port_write_echo(port, (char *)buffer);
if((length = port_readline(port, buffer, sizeof(buffer), 200)) < 0)
{
printf("Read from serial timed out without data.\n");
error = -1;
break;
}
else
{
if(strncmp((char *)buffer, "OK\r\n", 4) == 0)
{
printf("\r \r");
printf("\rWriting @ 0x%6.6lX: ", ext_addr);
fflush(stdout);
error = cdi_page_write(port, ext_addr, &page_buffer[ext_addr]);
if (error)
{
usleep(20000);
port_write_echo(port, "i\r");
bzero(buffer, 256);
length = port_readline(port, buffer, sizeof(buffer), 100);
if(memcmp(buffer, "85", 2) == 0)
{ /*Found CC2430 device*/
}
else
{
printf("Reinit failed.\n");
error = -1;
}
if (retry++ < 3)
{
error = 0;
i--;
}
}
else retry = 0;
fflush(stdout);
usleep(20000);
}
else
{
printf("Failed to set CDI programming start address.\n");
error = -1;
break;
}
}
}
if (error) break;
}
usleep(200000);
printf("\n");
}
return error;
}
int cdi_page_write(port_t *port, unsigned long page_addr, unsigned char *page_buffer)
{
int error = 0;
unsigned char buffer[80];
unsigned char cmd[16];
unsigned char block, i;
int length;
int retry = 0;
// Write page
port_write_echo(port, "w\r");
usleep(10000);
for (block=0; block<(2048/64); block++)
{
sprintf((char *)cmd, "%6.6lX", page_addr + (64*block));
bzero(buffer, sizeof(buffer));
length = port_readline(port, buffer, sizeof(buffer), 2000);
if (length <0)
{ length = 0;
printf("l!");fflush(stdout);
}
buffer[length] = 0;
if (block & 1)
{
}
if(memcmp(buffer, cmd, 6) == 0)
{
#define WRITE_SIZE 64
for (i=0; i<64; i+=WRITE_SIZE)
{
port_write(port, &page_buffer[(unsigned int)(block*64)+i], WRITE_SIZE);
usleep(1250);
}
bzero(buffer, sizeof(buffer));
printf(".");
fflush(stdout);
length = port_readline(port, buffer, sizeof(buffer), 200);
if(memcmp(buffer, "OK", 2) == 0)
{
retry = 0;
}
else
{
block--;
if (retry++ >= 8)
{
error = -1;
break;
}
else
{
buffer[length] = 0;
printf("%s",buffer);
port_rts_clear(port);
usleep(300000);
port_rts_set(port);
bzero(buffer, sizeof(buffer));
length = port_readline(port, buffer, sizeof(buffer), 800);
if(memcmp(buffer, "CDI", 3) == 0)
{
printf("R");
}
}
}
}
else
{
error = -1;
break;
}
}
if (!error)
{
printf("w"); fflush(stdout);
bzero(buffer, sizeof(buffer));
length = port_readline(port, buffer, sizeof(buffer), 800);
if(memcmp(buffer, "WROK", 4) == 0)
{
error = 0;
}
else
{
printf("%c%c", buffer[0], buffer[1]);
error = -1;
}
}
if (!error) printf("OK\r");
return error;
}

View file

@ -0,0 +1,99 @@
/*
NanoStack: MCU software and PC tools for IP-based wireless sensor networking.
Copyright (C) 2006-2007 Sensinode Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Address:
Sensinode Ltd.
Teknologiantie 6
90570 Oulu, Finland
E-mail:
info@sensinode.com
*/
#include <unistd.h>
#include <strings.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
int hexfile_parse(char *line, unsigned int *type, unsigned int *addr, unsigned char *buffer)
{
unsigned int row_len = 0;
unsigned int row_index = 7;
unsigned int i;
int tmp;
uint8_t cksum = 0;
int retval = 0;
retval = sscanf(line, ":%2x%4x%2x", &row_len, addr, type);
cksum += row_len;
cksum += *addr >> 8;
cksum += *addr & 0xFF;
cksum += *type;
i = 0;
if (retval == 3)
{
while(i < row_len)
{
if (sscanf(&line[row_index], "%2x", &tmp) == 1)
{
cksum += tmp;
buffer[i++] = (unsigned char) tmp;
row_index += 2;
}
else return -1;
}
if (sscanf(&line[row_index], "%2x", &tmp) == 1)
{
if ((cksum + (uint8_t) tmp) == 0) return row_len;
}
}
return -1;
}
int hexfile_out(char *line, unsigned int type, unsigned int address, unsigned char *data, unsigned int bytes)
{
uint8_t cksum = 0;
uint8_t i = 0;
char tmp[8];
sprintf(line, ":%2.2X%4.4X%2.2X", bytes, address, type);
cksum -= bytes;
cksum -= address >> 8;
cksum -= address & 0xFF;
cksum -= type;
for (i=0; i<bytes; i++)
{
sprintf(tmp, "%2.2X", data[i]);
strcat(line, tmp);
cksum -= data[i];
}
sprintf(tmp, "%2.2X\r\n", cksum);
strcat(line, tmp);
return strlen(line);
}

View file

@ -0,0 +1,36 @@
/*
NanoStack: MCU software and PC tools for IP-based wireless sensor networking.
Copyright (C) 2006-2007 Sensinode Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Address:
Sensinode Ltd.
Teknologiantie 6
90570 Oulu, Finland
E-mail:
info@sensinode.com
*/
#ifndef _IHEX_H
#define _IHEX_H
extern int hexfile_parse(char *line, unsigned char *type, unsigned int *addr, char *buffer);
extern int hexfile_out(char *line, unsigned int type, unsigned int address, unsigned char *data, unsigned int bytes);
#endif /*_IHEX_H*/

View file

@ -0,0 +1,371 @@
/*
NanoStack: MCU software and PC tools for IP-based wireless sensor networking.
Copyright (C) 2006-2007 Sensinode Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Address:
Sensinode Ltd.
Teknologiantie 6
90570 Oulu, Finland
E-mail:
info@sensinode.com
*/
#include <sys/poll.h>
#include "port.h"
int port_open(port_t **port, char *device)
{
port_t *new_port = (port_t *) malloc(sizeof(port_t));
char err_string[128];
*port = new_port;
new_port->device = 0;
new_port->handle = 0;
new_port->handle = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if (new_port->handle <= 0)
{
strerror_r(errno, err_string, 128);
printf("Serial port open failed with error message: %s.\n", err_string);
return(-1);
}
else
{
tcgetattr(new_port->handle, &(new_port->old_params));
fcntl(new_port->handle, F_SETFL, FASYNC);
printf("Serial port %s opened succesfully.\n", device);
return(0);
}
}
int port_close(port_t *port)
{
if (!port)
return(-1);
if ((port->handle) > 0)
{
tcflush(port->handle, TCIFLUSH);
tcsetattr(port->handle,TCSANOW,&(port->old_params));
close(port->handle);
port->handle = 0;
}
if (port->device) free(port->device);
port->device = 0;
free(port);
return(1);
}
/** @todo port_write() function probably needs mutexes -mjs */
int port_write(port_t *port, unsigned char *buffer, size_t buflen)
{
int i=0;
if (!port) return -1;
/** @todo The write to serial port is at the moment done one octet at a time with 10ms interval between each write operation due to some minor problems in MCU interrupts. -mjs */
while(i < buflen)
{
write(port->handle, &(buffer[i]), 1);
tcflush(port->handle, TCIFLUSH);
i++;
}
/* write(port->handle, &(buffer[i]), buflen);*/
tcflush(port->handle, TCIFLUSH);
return(0);
}
int port_read(port_t *port, unsigned char *buffer, size_t buflen)
{
unsigned int l = 0;
l = read(port->handle, buffer, buflen);
return(l);
}
int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts)
{
int rate = B115200;
struct termios newtio;
if (!port) return -1;
switch (speed)
{
case 230400:
rate = B230400;
break;
case 0:
case 115200:
rate = B115200;
break;
case 57600:
rate = B57600;
break;
case 38400:
rate = B38400;
break;
case 19200:
rate = B19200;
break;
case 9600:
rate = B9600;
break;
default:
return -1;
}
bzero(&newtio, sizeof(newtio));
if (speed == 9600)
{
newtio.c_cflag |= CS8 | CSTOPB | CLOCAL | CREAD;
}
else
{
newtio.c_cflag |= CS8 | CLOCAL | CREAD;
}
if (rtscts)
{
newtio.c_cflag |= CRTSCTS;
}
newtio.c_iflag = IGNPAR;
cfsetispeed(&newtio, rate);
cfsetospeed(&newtio, rate);
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
#if 0
newtio.c_cflag = rate | CS8 | CLOCAL | CREAD | CSTOPB;
/* if (rts_cts) newtio.c_cflag |= CRTSCTS;*/
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
#endif
tcflush(port->handle, TCIFLUSH);
tcsetattr(port->handle,TCSANOW,&newtio);
return(0);
}
int port_dtr_set(port_t *port)
{
int port_state = TIOCM_DTR;
if (!port) return(-1);
/* error = ioctl(port->handle, TIOCMGET, &port_state);
port_state |= TIOCM_RTS;
ioctl(port->handle, TIOCMSET, &port_state);*/
ioctl(port->handle, TIOCMBIS, &port_state);
return 0;
}
int port_dtr_clear(port_t *port)
{
int port_state = TIOCM_DTR;
if (!port) return(-1);
ioctl(port->handle, TIOCMBIC, &port_state);
return 0;
}
int port_rts_set(port_t *port)
{
int port_state = TIOCM_RTS;
if (!port) return(-1);
ioctl(port->handle, TIOCMBIS, &port_state);
return 0;
}
int port_rts_clear(port_t *port)
{
int port_state = TIOCM_RTS;
if (!port) return(-1);
ioctl(port->handle, TIOCMBIC, &port_state);
return 0;
}
int port_get(port_t *port, unsigned char *buffer, int timeout)
{
struct pollfd pfds;
unsigned int nfds = 1;
int bytes = 0;
int rval;
pfds.fd = (int)(port->handle);
pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
rval = poll(&pfds, nfds, timeout);
if((rval & POLLIN) != POLLIN)
{
return(-1);
}
else
{
bytes = port_read(port, buffer, 1);
}
return bytes;
}
int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout)
{
int length = 0;
struct pollfd pfds;
unsigned int nfds = 1;
int bytes = 0;
int rval;
pfds.fd = (int)(port->handle);
pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
do
{
rval = poll(&pfds, nfds, timeout);
if((rval & POLLIN) != POLLIN)
{
return(length);
}
else
{
bytes = port_read(port, &(buffer[length]), 1);
if (buffer[length] == '\n')
{
buf_size = length;
}
length += bytes;
}
}while(length < buf_size);
buffer[length] = 0;
if(length != 0)
return length;
else
return(-1);
}
int port_write_echo(port_t *port, char *string)
{
int length = 0;
int retry = 0;
unsigned char byte;
while( (string[length]) && (retry < 100) )
{
port_write(port, (unsigned char *) &string[length], 1);
while (retry++ < 100)
{
if (port_read(port, &byte, 1) == 1)
{
/* printf("%c",byte);*/
if (byte == string[length])
{
retry = 0;
length++;
break;
}
else retry = 100;
}
else usleep(1000);
}
}
if ((string[strlen(string)-1] == '\r') && (retry < 100) )
{ /*wait for \n*/
retry = 0;
while (retry++ < 100)
{
if (port_read(port, &byte, 1) == 1)
{
/* printf("%c",byte);*/
break;
}
else usleep(1000);
}
}
if (retry >= 100) return 0;
else return length;
}
int port_write_8byte_no_echo(port_t *port, int dlen, char *string)
{
int length = 0;
int total_len;
int wrbytes = 4;
total_len = dlen;
/* printf("total: %d, length: %d, dlen: %d.\n", total_len, length, dlen); */
while(total_len > length)
{
if((total_len - length) >= wrbytes)
{
port_write(port, (unsigned char *)&string[length], wrbytes);
length += wrbytes;
}
else
{
port_write(port, (unsigned char *)&string[length], total_len - length);
length += total_len - length;
}
usleep(1250);
}
return(length);
}

Binary file not shown.

View file

@ -0,0 +1,94 @@
/*
NanoStack: MCU software and PC tools for IP-based wireless sensor networking.
Copyright (C) 2006-2007 Sensinode Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Address:
Sensinode Ltd.
Teknologiantie 6
90570 Oulu, Finland
E-mail:
info@sensinode.com
*/
#ifndef _PORT_H
#define _PORT_H
#ifndef PLATFORM_WINDOWS
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <string.h>
#else
#include "windows.h"
#include <stdint.h>
#include "ftd2xx.h"
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef PLATFORM_WINDOWS
typedef struct
{
int handle;
char *device;
struct termios old_params;
}port_t;
extern int port_open(port_t **port, char *device);
#else
typedef struct port_t
{
FT_HANDLE handle;
int device;
HANDLE event_handle;
}port_t;
extern int port_open(port_t **port, int device);
#endif
extern int port_close(port_t *port);
extern int port_write(port_t *port, unsigned char *buffer, size_t buflen);
extern int port_read(port_t *port, unsigned char *buffer, size_t buflen);
extern int port_get(port_t *port, unsigned char *buffer, int timeout);
extern int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts);
extern int port_dtr_set(port_t *port);
extern int port_dtr_clear(port_t *port);
extern int port_rts_set(port_t *port);
extern int port_rts_clear(port_t *port);
extern int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout);
extern int port_write_echo(port_t *port, char *string);
extern int port_write_8byte_no_echo(port_t *port, int dlen, char *string);
#ifdef __cplusplus
}
#endif
#endif /* _PORT_H */

View file

@ -0,0 +1,440 @@
/*
NanoStack: MCU software and PC tools for IP-based wireless sensor networking.
Copyright (C) 2006-2007 Sensinode Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Address:
Sensinode Ltd.
Teknologiantie 6
90570 Oulu, Finland
E-mail:
info@sensinode.com
*/
#include <unistd.h>
#include <getopt.h>
#include <strings.h>
#include "port.h"
#include "programmer.h"
#include <stdio.h>
extern int cdi_programmer(conf_opts_t *conf, char *filename);
void usage(char *prg_name)
{
printf("\nUsage: %s [-d device]\n", prg_name);
printf("General options:\n");
printf(" -V/--version Get programmer version\n");
printf(" -1/--d100 Use D100 board (default D200)\n");
printf("Operating modes:\n");
printf(" -b/--bios to get programmer BIOS version\n");
printf(" -P/--program [ihex file] Do a complete programming sequence (write and verify)\n");
printf(" -v/--verify [ihex file] Verify against ihex file\n");
printf(" -r/--read [ihex file] Read program code into ihex file\n");
printf(" -m/--mac Read device MAC address\n");
printf(" -Q/--write-mac [MAC address] Write device MAC address\n");
printf(" -e/--erase Erase flash (erases MAC address!)\n");
printf("Programming options:\n");
printf(" -l/--linear Force linear model for extended addresses (not SDCC file)\n");
printf(" -s/--sdcc Force SDCC model for extended addresses (SDCC file)\n");
printf("Defaults:\n");
#ifndef PLATFORM_WINDOWS
printf("device /dev/ttyUSB0\n");
#else
printf("device 0\n");
#endif
}
conf_opts_t conf_opts;
static int option_index = 0;
int do_exit = 0;
#define OPTIONS_STRING "d:ec1lsmVbP:v:r:Q:"
/* long option list */
static struct option long_options[] =
{
{"device", 1, NULL, 'd'},
{"psoc", 0, NULL, 'p'},
{"d100", 0, NULL, '1'},
{"erase", 0, NULL, 'e'},
{"mac", 0, NULL, 'm'},
{"linear", 0, NULL, 'l'},
{"sdcc", 0, NULL, 's'},
{"cdi", 0, NULL, 'c'},
{"version", 0, NULL, 'V'},
{"bios", 0, NULL, 'b'},
{"program", 1, NULL, 'P'},
{"verify", 1, NULL, 'v'},
{"read", 1, NULL, 'r'},
{"write-mac", 1, NULL, 'Q'},
{0, 0, 0, 0}
};
int parse_opts(int count, char* param[])
{
int opt;
int error=0;
conf_opts.target_type = CDI;
while ((opt = getopt_long(count, param, OPTIONS_STRING,
long_options, &option_index)) != -1)
{
switch(opt)
{
case 'V':
conf_opts.target_type = VERSION;
break;
case '1':
conf_opts.prg_type = 1;
break;
case 'c':
conf_opts.target_type = CDI;
break;
case 'd':
#ifdef PLATFORM_WINDOWS
if (sscanf(optarg, "%d", &conf_opts.device) != 1)
{
printf("Device ID must be a positive integer.\n");
conf_opts.action = ' ';
}
#else
printf("device:%s\n", optarg);
strcpy(conf_opts.device, optarg);
#endif
break;
case 'P':
printf("Programming mode.\n");
conf_opts.action = 'P';
strcpy(conf_opts.ihex_file, optarg);
break;
case 's':
if (conf_opts.page_mode == PAGE_UNDEFINED)
{
conf_opts.page_mode = PAGE_SDCC;
}
else
{
printf("Only one paging option allowed.\n");
error = -1;
}
break;
case 'l':
if (conf_opts.page_mode == PAGE_UNDEFINED)
{
conf_opts.page_mode = PAGE_LINEAR;
}
else
{
printf("Only one paging option allowed.\n");
error = -1;
}
break;
case 'e':
printf("Erase.\n");
conf_opts.action = 'e';
break;
case 'm':
printf("Get MAC.\n");
conf_opts.action = 'm';
break;
case 'b':
printf("Get BIOS version\n");
conf_opts.action = 'b';
break;
case 'Q':
printf("Write MAC.\n");
conf_opts.action = 'Q';
if (sscanf(optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&conf_opts.write_mac[0], &conf_opts.write_mac[1],
&conf_opts.write_mac[2], &conf_opts.write_mac[3],
&conf_opts.write_mac[4], &conf_opts.write_mac[5],
&conf_opts.write_mac[6], &conf_opts.write_mac[7]) != 8)
{
printf("Invalid MAC.\n");
conf_opts.action = ' ';
}
break;
case 'v':
printf("Verify by comparing to ihex file:%s\n", optarg);
conf_opts.action = 'v';
strcpy(conf_opts.ihex_file, optarg);
break;
case 'r':
printf("Read program to ihex file:%s\n", optarg);
conf_opts.action = 'r';
strcpy(conf_opts.ihex_file, optarg);
break;
case '?':
printf("Duh\n");
error = -1;
break;
}
}
if (!error && (conf_opts.target_type == CDI) )
{
#ifdef PLATFORM_WINDOWS
printf("Setup: Device %d.\n", conf_opts.device);
#else
printf("Setup: Device %s.\n", conf_opts.device);
#endif
}
return error;
}
/*
int port_write_8byte_echo(port_t *port, char *string)
{
int length = 0;
int total_len;
int i, j;
struct pollfd pfds;
unsigned int nfds = 1;
int rval = 0;
int wrbytes = 2;
unsigned char byte8[wrbytes];
pfds.fd = (int)(port->handle);
pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
total_len = strlen(string);
while(total_len > length)
{
if(total_len - length >= wrbytes)
{
i=0;
port_write(port, (unsigned char *)&string[length], wrbytes);
if((rval = poll(&pfds, nfds, 100)) == 0)
{
printf("Timed out...\n");
return(-1);
}
else
{
while(i<wrbytes)
{
i += port_read(port, &byte8[i], wrbytes);
}
if(i != wrbytes || memcmp(byte8, &string[length], wrbytes) != 0)
{
printf("Got wrong length (%d) or wrong bytes back.\n", i);
for(j=0;j<wrbytes;j++)
{
printf("%.2x <-> %.2x\n", string[length+j], byte8[j]);
}
return(-1);
}
else
{
printf("8Bwok - ");
fflush(stdout);
length += wrbytes;
}
}
}
else
{
i=0;
port_write(port, (unsigned char *)&string[length], total_len - length);
if((rval = poll(&pfds, nfds, 100)) == 0)
{
printf("Timed out...\n");
return(-1);
}
else
{
while(i<(total_len-length))
{
i = port_read(port, &byte8[i], total_len - length);
}
if(i != total_len - length || memcmp(byte8, &string[length], total_len - length) != 0)
{
printf("Got wrong length or wrong bytes back.\n");
for(j=0;j<total_len - length;j++)
{
printf("%.2x <-> %.2x\n", string[length+j], byte8[j]);
}
return(-1);
}
else
{
printf("<8Bwok - \n");
fflush(stdout);
length += (total_len - length);
}
}
}
usleep(5000);
}
return(length);
}
*/
#ifdef PLATFORM_WINDOWS
int programmer_init(int device, port_t **port)
#else
int programmer_init(char *device, port_t **port)
#endif
{
int error = port_open(port, device);
uint8_t buffer[8];
buffer[0] = 0;
if (error >= 0)
{
if (conf_opts.prg_type == 1)
{
int retry = 0;
port_set_params(*port, 9600, 0);
// Activate programming...
port_dtr_clear(*port);
port_rts_clear(*port);
sleep(1);
printf("Select D100.\n");
port_rts_set(*port);
sleep(1);
buffer[0] = '\r';
while (retry++ < 3)
{
int length;
port_write_echo(*port, "q\r");
length = port_readline(*port, buffer, sizeof(buffer), 800);
if (length)
{
if (*buffer == '!')
{
printf("D100 found.\n");
return 0;
}
}
}
printf("No programmer found.\n");
return -1;
}
else
{
port_set_params(*port, 57600, 0);
// Activate programming...
port_dtr_clear(*port);
port_rts_clear(*port);
usleep(300000);
printf("Select D200.\n");
port_rts_set(*port);
usleep(200000);
port_set_params(*port, 57600, 1);
port_write(*port, (uint8_t *)"\r", 1);
usleep(100000);
if ((port_get(*port, buffer, 500) >= 1) && (buffer[0] == '!'))
{
printf("D200 found.\n");
return 0;
}
printf("No programmer found.\n");
return -1;
}
}
return error;
}
void programmer_close(port_t *port)
{
if (port)
{
port_rts_clear(port);
port_dtr_set(port);
sleep(1);
port_close(port);
printf("Port closed.\n");
}
}
int main(int argc, char *argv[])
{
int error = 0;
conf_opts.target_type = 0;
conf_opts.action = 0;
conf_opts.prg_type = 2;
#ifndef PLATFORM_WINDOWS
strncpy(conf_opts.device, "/dev/ttyUSB0", 12);
/* Install a new handler for SIGIO.
*
* According to man 7 signal this signal is by default ignored by most systems.
* It seems that pre FC7 this was true for Fedoras also. We have noticed that at least
* on some FC7 installations the default action has changed. We avoid abnormal program
* exits by defining the SIGIO as SIG_IGN (ignore). - mjs
*/
if(signal(SIGIO, SIG_IGN) == SIG_ERR)
{
printf("%s error: failed to install SIGIO handler. Exit.\n", argv[0]);
exit(EXIT_FAILURE);
}
#else
conf_opts.device = 0;
#endif
conf_opts.page_mode = PAGE_UNDEFINED;
if ( (argc <= 1) || (error = parse_opts(argc, argv)) )
{
usage(argv[0]);
if (error < 0) return error;
else return 0;
}
if(conf_opts.target_type == CDI)
{ /*CDI*/
error = cdi_programmer(&conf_opts, conf_opts.ihex_file);
}
else
{
printf("\nSensinode Nano series programmer "PROGRAMMER_VERSION "\n");
}
return error;
}

View file

@ -0,0 +1,62 @@
/*
NanoStack: MCU software and PC tools for IP-based wireless sensor networking.
Copyright (C) 2006-2007 Sensinode Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Address:
Sensinode Ltd.
Teknologiantie 6
90570 Oulu, Finland
E-mail:
info@sensinode.com
*/
#define PROGRAMMER_VERSION "v1.3"
typedef enum
{
PAGE_SDCC,
PAGE_LINEAR,
PAGE_UNDEFINED
}page_mode_t;
typedef struct {
#ifdef PLATFORM_WINDOWS
int device;
#else
char device[128];
#endif
int target_type;
int prg_type;
int action;
char ihex_file[128];
unsigned char write_mac[8];
page_mode_t page_mode;
}conf_opts_t;
enum target { UNDEFINED, VERSION, CDI };
#ifdef PLATFORM_WINDOWS
extern int programmer_init(int device, port_t **port);
#else
extern int programmer_init(char *device, port_t **port);
#endif
extern void programmer_close(port_t *port);

View file

@ -0,0 +1,383 @@
/*
NanoStack: MCU software and PC tools for IP-based wireless sensor networking.
Copyright (C) 2006-2007 Sensinode Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Address:
Sensinode Ltd.
Teknologiantie 6
90570 Oulu, Finland
E-mail:
info@sensinode.com
*/
#include "port.h"
#include <stdio.h>
int port_open(port_t **port, int device)
{
port_t *new_port = (port_t *) malloc(sizeof(port_t));
FT_STATUS status;
*port = new_port;
new_port->device = device;
new_port->handle = 0;
status = FT_Open(device, &(new_port->handle));
if (status != FT_OK)
{
new_port->handle = 0;
printf("Serial port open failed with error message: %d.\n", (int)status);
return(-1);
}
else
{
DWORD mask;
new_port->event_handle = CreateEvent(NULL, TRUE, FALSE, "SN_USB_UART_EVENTS");
if (new_port->event_handle == NULL)
{
printf("Event handle creation failed.\n");
FT_Close(new_port->handle);
new_port->handle = 0;
return(-1);
}
mask = FT_EVENT_RXCHAR | FT_EVENT_MODEM_STATUS;
status = FT_SetEventNotification(new_port->handle,mask,new_port->event_handle);
if (status != FT_OK)
{
printf("Setting event notification failed.\n");
}
FT_SetTimeouts(new_port->handle,400,0);
return(0);
}
}
int port_close(port_t *port)
{
if (!port)
return(-1);
if ((port->event_handle) != NULL)
{
CloseHandle(port->event_handle);
port->event_handle = NULL;
FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX);
FT_Close(port->handle);
port->handle = 0;
}
port->device = 0;
free(port);
return(1);
}
int port_set_params(port_t *port, uint32_t speed, uint8_t rtscts)
{
FT_STATUS status;
if (!port) return -1;
status = FT_SetBaudRate (port->handle, speed);
if (status != FT_OK) return -1;
if (speed == 9600)
{
status = FT_SetDataCharacteristics(port->handle, FT_BITS_8, FT_STOP_BITS_2, FT_PARITY_NONE);
}
else
{
status = FT_SetDataCharacteristics(port->handle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);
}
if (status != FT_OK) return -1;
if (rtscts)
{
status = FT_SetFlowControl(port->handle, FT_FLOW_RTS_CTS, 0, 0);
}
else
{
status = FT_SetFlowControl(port->handle, FT_FLOW_NONE, 0, 0);
}
if (status != FT_OK) return -1;
FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX);
return(0);
}
int port_dtr_set(port_t *port)
{
FT_STATUS status;
if (!port) return(-1);
status = FT_SetDtr(port->handle);
if (status != FT_OK)
{
printf("Control failed.\n");
return -1;
}
return 0;
}
int port_dtr_clear(port_t *port)
{
FT_STATUS status;
if (!port) return(-1);
status = FT_ClrDtr(port->handle);
if (status != FT_OK)
{
printf("Control failed.\n");
return -1;
}
return 0;
}
int port_rts_set(port_t *port)
{
FT_STATUS status;
if (!port) return(-1);
status = FT_SetRts(port->handle);
if (status != FT_OK)
{
printf("Control failed.\n");
return -1;
}
return 0;
}
int port_rts_clear(port_t *port)
{
FT_STATUS status;
if (!port) return(-1);
status = FT_ClrRts(port->handle);
if (status != FT_OK)
{
printf("Control failed.\n");
return -1;
}
return 0;
}
int port_write(port_t *port, unsigned char *buffer, size_t buflen)
{
FT_STATUS status;
DWORD bytes_out;
if (!port) return -1;
// FT_Purge(port->handle, FT_PURGE_RX);
status = FT_Write (port->handle, (LPVOID) buffer, (DWORD) buflen,&bytes_out);
if (status != FT_OK) return -1;
return 0;
}
int port_read(port_t *port, unsigned char *buffer, size_t buflen)
{
DWORD l = 0;
FT_STATUS status;
status = FT_Read(port->handle, buffer, buflen, &l);
return((int) l);
}
int port_get(port_t *port, unsigned char *buffer, int timeout)
{
DWORD bytes = 0;
FT_STATUS status;
FT_SetTimeouts(port->handle, timeout, 0);
status = FT_Read(port->handle, buffer, 1, &bytes);
if (status != FT_OK)
{
return(-1);
}
return bytes;
}
int port_readline(port_t *port, unsigned char *buffer, int buf_size, int timeout)
{
int length = 0;
DWORD bytes = 0;
FT_STATUS status;
FT_SetTimeouts(port->handle, timeout, 0);
do
{
status = FT_Read(port->handle, &buffer[length], 1, &bytes);
length += bytes;
if ((status != FT_OK) || (bytes == 0))
{
return(length);
}
else
{
if (buffer[length-1] == '\n')
{
buf_size = length;
}
}
}while(length < buf_size);
buffer[length] = 0;
if(length != 0)
return length;
else
return(-1);
}
int port_write_echo(port_t *port, char *string)
{
int length = 0;
int retry = 0;
unsigned char byte;
DWORD bytes_out;
FT_STATUS status;
FT_Purge(port->handle, FT_PURGE_RX | FT_PURGE_TX);
while( (string[length]) && (retry < 100) )
{
retry = 0;
while (retry++ < 100)
{
status = FT_Write (port->handle, (LPVOID) &string[length], (DWORD) 1,&bytes_out);
if (status != FT_OK) return -1;
if (port_get(port, &byte, 1000) == 1)
{
/* printf("%c",byte);*/
if (byte == string[length])
{
retry = 0;
length++;
break;
}
else retry = 100;
}
else usleep(500);
}
}
if ((string[strlen(string)-1] == '\r') && (retry < 100) )
{ /*wait for \n*/
retry = 0;
while (retry++ < 100)
{
if (port_get(port, &byte, 1000) == 1)
{
/* printf("%c",byte);*/
break;
}
else usleep(500);
}
}
if (retry >= 100) return 0;
else return length;
}
#if 0
int port_write_echo(port_t *port, char *string)
{
int length = 0;
int retry = 0;
unsigned char byte;
while( (string[length]) && (retry < 100) )
{
port_write(port, (unsigned char *) &string[length], 1);
while (retry++ < 100)
{
if (port_read(port, &byte, 1) == 1)
{
/* printf("%c",byte);*/
if (byte == string[length])
{
retry = 0;
length++;
break;
}
else retry = 100;
}
else usleep(1000);
}
}
if ((string[strlen(string)-1] == '\r') && (retry < 100) )
{ /*wait for \n*/
retry = 0;
while (retry++ < 100)
{
if (port_read(port, &byte, 1) == 1)
{
/* printf("%c",byte);*/
break;
}
else usleep(1000);
}
}
if (retry >= 100) return 0;
else return length;
}
int port_write_8byte_no_echo(port_t *port, int dlen, char *string)
{
int length = 0;
int total_len;
int wrbytes = 4;
total_len = dlen;
/* printf("total: %d, length: %d, dlen: %d.\n", total_len, length, dlen); */
while(total_len > length)
{
if((total_len - length) >= wrbytes)
{
port_write(port, (unsigned char *)&string[length], wrbytes);
length += wrbytes;
}
else
{
port_write(port, (unsigned char *)&string[length], total_len - length);
length += total_len - length;
}
usleep(1250);
}
return(length);
}
#endif