- Added the Sensinode platform programming tools to /tools
This commit is contained in:
parent
83988ef554
commit
fc237101be
24 changed files with 5847 additions and 0 deletions
43
tools/sensinode/nano_programmer/Makefile
Normal file
43
tools/sensinode/nano_programmer/Makefile
Normal 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)
|
34
tools/sensinode/nano_programmer/README
Executable file
34
tools/sensinode/nano_programmer/README
Executable 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
|
607
tools/sensinode/nano_programmer/cdi_program.c
Normal file
607
tools/sensinode/nano_programmer/cdi_program.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
99
tools/sensinode/nano_programmer/ihex.c
Normal file
99
tools/sensinode/nano_programmer/ihex.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
36
tools/sensinode/nano_programmer/ihex.h
Normal file
36
tools/sensinode/nano_programmer/ihex.h
Normal 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*/
|
371
tools/sensinode/nano_programmer/linux/port.c
Normal file
371
tools/sensinode/nano_programmer/linux/port.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
BIN
tools/sensinode/nano_programmer/nano_programmer
Executable file
BIN
tools/sensinode/nano_programmer/nano_programmer
Executable file
Binary file not shown.
94
tools/sensinode/nano_programmer/port.h
Normal file
94
tools/sensinode/nano_programmer/port.h
Normal 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 */
|
440
tools/sensinode/nano_programmer/programmer.c
Normal file
440
tools/sensinode/nano_programmer/programmer.c
Normal 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;
|
||||||
|
}
|
62
tools/sensinode/nano_programmer/programmer.h
Normal file
62
tools/sensinode/nano_programmer/programmer.h
Normal 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);
|
||||||
|
|
383
tools/sensinode/nano_programmer/windows/port.c
Normal file
383
tools/sensinode/nano_programmer/windows/port.c
Normal 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
|
32
tools/sensinode/nano_usb_programmer/Makefile
Normal file
32
tools/sensinode/nano_usb_programmer/Makefile
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
EXE_MAKE=$(notdir $(shell which "make.exe"))
|
||||||
|
ifeq "$(EXE_MAKE)" "make.exe"
|
||||||
|
PLATFORM=windows
|
||||||
|
else
|
||||||
|
PLATFORM=linux
|
||||||
|
endif
|
||||||
|
|
||||||
|
include Rules.make
|
||||||
|
|
||||||
|
APP = nano_usb_programmer$(SUFFIX)
|
||||||
|
OBJS = $(SOURCES:.c=.o)
|
||||||
|
|
||||||
|
all: $(APP)
|
||||||
|
|
||||||
|
$(APP): $(OBJS) Makefile $(SOURCES)
|
||||||
|
$(CC) -o $(APP) $(CFLAGS) $(OBJS) $(LDFLAGS)
|
||||||
|
|
||||||
|
platform-test:
|
||||||
|
@echo $(PLATFORM)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o ; rm -f $(APP)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -c -o $(<:.c=.o) $(CFLAGS) $<
|
||||||
|
|
||||||
|
ftd2xx.def:
|
||||||
|
echo EXPORTS > ftd2xx.def
|
||||||
|
nm ftd2xx.lib | grep ' T _' | sed 's/.* T _//' >> ftd2xx.def
|
||||||
|
|
||||||
|
ftd2xx.dll.a: ftd2xx.def
|
||||||
|
dlltool --def ftd2xx.def --dllname ftd2xx.dll --output-lib ftd2xx.dll.a
|
56
tools/sensinode/nano_usb_programmer/README
Normal file
56
tools/sensinode/nano_usb_programmer/README
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
Nano USB Programmer
|
||||||
|
|
||||||
|
An USB programmer for the Sensinode NanoRouter N600.
|
||||||
|
|
||||||
|
Copyright 2007-2008 Sensinode Ltd.
|
||||||
|
|
||||||
|
1a - Installation (Linux)
|
||||||
|
|
||||||
|
The installation is quite simple but requires the user to obtain the FTDI
|
||||||
|
development library. The installation also requires root privileges in
|
||||||
|
some phases (the ldconfig command to be more specific). Running the
|
||||||
|
Nano_USB_Programmer executable might also require root privileges.
|
||||||
|
|
||||||
|
-unpack the Nano_USB_Programmer-v[xxx].zip to a directory
|
||||||
|
-get the FTDI development library from
|
||||||
|
|
||||||
|
http://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx0.4.13.tar.gz
|
||||||
|
|
||||||
|
-unpack the ftdi archive
|
||||||
|
-copy the library static_lib/libftd2xx.a.[version] into /usr/lib
|
||||||
|
-copy the library libftd2xx.so.[version] into /usr/lib
|
||||||
|
-make a symbolic link to the library, for example:
|
||||||
|
ln -s /usr/lib/libftd2xx.so.0.4.13 /usr/lib/libftd2xx.so
|
||||||
|
-run ldconfig
|
||||||
|
-copy the header files (*.h) into the nano_usb_programmer/ftdi_linux/ directory
|
||||||
|
-go to the programmer directory and run make
|
||||||
|
|
||||||
|
1b - Installation (Windows/Cygwin)
|
||||||
|
Installation procedure:
|
||||||
|
-The FTDI library can be downloaded at:
|
||||||
|
|
||||||
|
http://www.ftdichip.com/Drivers/CDM/CDM%202.02.04%20WHQL%20Certified.zip
|
||||||
|
|
||||||
|
-Copy header files (ftd2xx.h), ftd2xx.lib and ftd2xx.dll to nano_usb_programmer/ftdi_win32
|
||||||
|
-Copy the ftd2xx.dll to your windows system32 directory
|
||||||
|
|
||||||
|
2 - Usage
|
||||||
|
|
||||||
|
Usage info for the Nano_USB_Programmer is available with command
|
||||||
|
./nano_usb_programmer --help. Note that use might require root/administrator privileges
|
||||||
|
depending on system configuration.
|
||||||
|
|
||||||
|
3 - Known problems (Linux)
|
||||||
|
|
||||||
|
There's one known problem at the moment. The N600 must be unplugged and
|
||||||
|
plugged in again after it has been programmed or the MAC address has been
|
||||||
|
read from it before it can respond to the programmer again. The reason for
|
||||||
|
this is the FTDI library is not perfectly integrated with the Linux
|
||||||
|
serial driver.
|
||||||
|
|
||||||
|
4 - README Version
|
||||||
|
|
||||||
|
v1.0 2007-11-14 Mikko Saarnivala Initial release
|
||||||
|
v1.1 2007-11-15 Mikko Saarnivala A small error in the instructions fixed
|
||||||
|
v1.2 2007-11-19 Mikko Saarnivala Added the FTDI CBUS2 value handling
|
||||||
|
v1.3 2008-01-31 Martti Huttunen Multi-platform build and updated instructions
|
14
tools/sensinode/nano_usb_programmer/Rules.make
Normal file
14
tools/sensinode/nano_usb_programmer/Rules.make
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
ifeq "$(PLATFORM)" "linux"
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS= -I. -I./ftdi_linux -L. -L./ftdi_linux -DPLATFORM_LINUX
|
||||||
|
LDFLAGS= -lftd2xx -Wl,-rpath /usr/local/lib
|
||||||
|
SOURCES=main.c prog.c cdi.c ihex.c
|
||||||
|
SUFFIX=
|
||||||
|
else
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=-I. -I./ftdi_win32 -L. -L./ftdi_win32 -DPLATFORM_WINDOWS
|
||||||
|
CFLAGS+= -mwin32
|
||||||
|
LDFLAGS=ftdi_win32/ftd2xx.lib -lkernel32
|
||||||
|
SOURCES=main.c prog.c cdi.c ihex.c
|
||||||
|
SUFFIX=.exe
|
||||||
|
endif
|
506
tools/sensinode/nano_usb_programmer/cdi.c
Normal file
506
tools/sensinode/nano_usb_programmer/cdi.c
Normal file
|
@ -0,0 +1,506 @@
|
||||||
|
/*
|
||||||
|
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 <stdio.h>
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include "cdi.h"
|
||||||
|
|
||||||
|
/*read none/8*/
|
||||||
|
#define CDI_CHIP_ERASE 0x10
|
||||||
|
#define CDI_WR_CONFIG 0x19
|
||||||
|
#define CDI_SET_HW_BRKPNT 0x3B
|
||||||
|
|
||||||
|
/*read 8*/
|
||||||
|
#define CDI_RD_CONFIG 0x24
|
||||||
|
#define CDI_READ_STATUS 0x34
|
||||||
|
#define CDI_HALT 0x44
|
||||||
|
#define CDI_RESUME 0x4C
|
||||||
|
#define CDI_STEP_INSTR 0x5C
|
||||||
|
|
||||||
|
/*variable len, add data length to command byte*/
|
||||||
|
#define CDI_DBGINSTR 0x54
|
||||||
|
#define CDI_STEP_REPLACE 0x64
|
||||||
|
|
||||||
|
/*response = 16 bits*/
|
||||||
|
#define CDI_GET_PC 0x28
|
||||||
|
#define CDI_GET_CHIP_ID 0x68
|
||||||
|
|
||||||
|
|
||||||
|
/* internals */
|
||||||
|
void cdi_command_push(uint8_t *byte, uint8_t bytes_out, uint16_t *retval, uint8_t return_bits);
|
||||||
|
|
||||||
|
void cdi_flash_bank(uint8_t bank, uint8_t unif_mode);
|
||||||
|
|
||||||
|
void cdi_dptr_write(uint16_t value);
|
||||||
|
|
||||||
|
uint8_t cdi_reg_read(uint8_t reg_addr);
|
||||||
|
void cdi_reg_write(uint8_t reg_addr, uint8_t value);
|
||||||
|
|
||||||
|
void cdi_xdata_write(uint8_t value);
|
||||||
|
uint8_t cdi_xdata_read(void);
|
||||||
|
|
||||||
|
void cdi_flash_init(void);
|
||||||
|
void cdi_flash_write_page(void);
|
||||||
|
|
||||||
|
uint32_t cdi_addr = 0;
|
||||||
|
|
||||||
|
#define pause_ms(x) usleep(x*1000)
|
||||||
|
#define pause_us(x) usleep(x)
|
||||||
|
|
||||||
|
void cdi_command_push(uint8_t *byte, uint8_t bytes_out, uint16_t *retval, uint8_t return_bits)
|
||||||
|
{
|
||||||
|
uint8_t i, val;
|
||||||
|
|
||||||
|
for (i=0; i<bytes_out; i++)
|
||||||
|
{
|
||||||
|
prog_write(*byte);
|
||||||
|
byte++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_bits >>= 3;
|
||||||
|
for (i=0; i<return_bits; i++)
|
||||||
|
{
|
||||||
|
*retval <<= 8;
|
||||||
|
|
||||||
|
prog_read(&val);
|
||||||
|
*retval += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdi_reg_write(uint8_t reg_addr, uint8_t value)
|
||||||
|
{
|
||||||
|
uint8_t out[4];
|
||||||
|
uint16_t retval;
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 3; /*command length 3 bytes*/
|
||||||
|
out[1] = 0x75; /*mov sfr, #immediate*/
|
||||||
|
out[2] = reg_addr; /*sfr = reg_addr*/
|
||||||
|
out[3] = value; /*immediate*/
|
||||||
|
cdi_command_push(out, 4, &retval, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdi_xdata_write(uint8_t value)
|
||||||
|
{
|
||||||
|
uint8_t out[3];
|
||||||
|
uint16_t retval;
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 2; /*command length 3 bytes*/
|
||||||
|
out[1] = 0x74; /*mov a, #immediate*/
|
||||||
|
out[2] = value; /*immediate*/
|
||||||
|
cdi_command_push(out, 3, &retval, 8);
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 1; /*command length 3 bytes*/
|
||||||
|
out[1] = 0xF0; /*movx @dptr, a*/
|
||||||
|
cdi_command_push(out, 2, &retval, 8);
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 1; /*command length 1 byte*/
|
||||||
|
out[1] = 0xA3; /*inc DPTR*/
|
||||||
|
cdi_command_push(out, 2, &retval, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t cdi_xdata_read(void)
|
||||||
|
{
|
||||||
|
uint8_t out[2];
|
||||||
|
uint16_t retval;
|
||||||
|
uint8_t retval8;
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 1; /*command length 3 bytes*/
|
||||||
|
out[1] = 0xE0; /*movx a, @dptr*/
|
||||||
|
cdi_command_push(out, 2, &retval, 8);
|
||||||
|
retval8 = retval;
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 1; /*command length 1 byte*/
|
||||||
|
out[1] = 0xA3; /*inc DPTR*/
|
||||||
|
cdi_command_push(out, 2, &retval, 8);
|
||||||
|
|
||||||
|
return retval8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdi_dptr_write(uint16_t value)
|
||||||
|
{
|
||||||
|
uint8_t out[4];
|
||||||
|
uint16_t retval;
|
||||||
|
|
||||||
|
/*set DPTR to address*/
|
||||||
|
out[0] = CDI_DBGINSTR + 3; /*command length 3 bytes*/
|
||||||
|
out[1] = 0x90; /*mov DPTR, #immediate16*/
|
||||||
|
out[2] = (value >> 8); /*immediateh*/
|
||||||
|
out[3] = value; /*immediatel*/
|
||||||
|
cdi_command_push(out, 4, &retval, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t cdi_reg_read(uint8_t reg_addr)
|
||||||
|
{
|
||||||
|
uint8_t out[3];
|
||||||
|
uint16_t retval;
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 2; /*command length 2 bytes*/
|
||||||
|
out[1] = 0xE5; /*mov a, sfr*/
|
||||||
|
out[2] = reg_addr; /*sfr = reg_addr*/
|
||||||
|
cdi_command_push(out, 3, &retval, 8);
|
||||||
|
|
||||||
|
return (uint8_t) retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cdi_flash_bank(uint8_t bank, uint8_t unif_mode)
|
||||||
|
{
|
||||||
|
uint8_t out;
|
||||||
|
|
||||||
|
out = (bank << 4) + 1;
|
||||||
|
out &= 0x31;
|
||||||
|
if (unif_mode) out |= 0x40; /*set unified memory model*/
|
||||||
|
|
||||||
|
cdi_reg_write(0xC7, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cdi_flash_read(uint8_t *ptr, uint16_t bytes)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
uint8_t out[4];
|
||||||
|
uint16_t retval;
|
||||||
|
|
||||||
|
cdi_flash_bank((cdi_addr >> 15), 0);
|
||||||
|
|
||||||
|
cdi_dptr_write(cdi_addr | 0x8000);
|
||||||
|
|
||||||
|
for (i=0; i<bytes; i++)
|
||||||
|
{
|
||||||
|
out[0] = CDI_DBGINSTR + 1; /*command length 1 byte*/
|
||||||
|
out[1] = 0xE4; /*clr a*/
|
||||||
|
cdi_command_push(out, 2, &retval, 8);
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 1; /*command length 1 byte*/
|
||||||
|
out[1] = 0x93; /*movc a, @A+DPTR*/
|
||||||
|
cdi_command_push(out, 2, &retval, 8);
|
||||||
|
*ptr++ = retval;
|
||||||
|
|
||||||
|
out[0] = CDI_DBGINSTR + 1; /*command length 1 byte*/
|
||||||
|
out[1] = 0xA3; /*inc DPTR*/
|
||||||
|
cdi_command_push(out, 2, &retval, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
cdi_addr += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t cdi_ram_code[] =
|
||||||
|
{
|
||||||
|
0x7E, 0x00, /*mov r6, #0*/
|
||||||
|
0x7D, 0x04, /*mov r5, #4*/
|
||||||
|
/*C0:*/
|
||||||
|
0xE5, 0xAE, /*MOV A,_FCTL*/
|
||||||
|
0x20, 0xE7, 0xFB, /*JB ACC.7,C0*/
|
||||||
|
0x75, 0xAE, 0x02, /*mov _FCTL,#0x02*/
|
||||||
|
/*C1:*/
|
||||||
|
0xE0, /*movx a, @DPTR*/
|
||||||
|
0xF5, 0xAF, /*MOV _FWDATA, a*/
|
||||||
|
0xA3, /*inc DPTR*/
|
||||||
|
0xE0, /*movx a, @DPTR*/
|
||||||
|
0xF5, 0xAF, /*MOV _FWDATA, a*/
|
||||||
|
0xA3, /*inc DPTR*/
|
||||||
|
0xE0, /*movx a, @DPTR*/
|
||||||
|
0xF5, 0xAF, /*MOV _FWDATA, a*/
|
||||||
|
0xA3, /*inc DPTR*/
|
||||||
|
0xE0, /*movx a, @DPTR*/
|
||||||
|
0xF5, 0xAF, /*MOV _FWDATA, a*/
|
||||||
|
0xA3, /*inc DPTR*/
|
||||||
|
/*C2:*/
|
||||||
|
0xE5, 0xAE, /*MOV A,_FCTL*/
|
||||||
|
0x20, 0xE6, 0xFB, /*JB ACC.6,C2*/
|
||||||
|
0x1E, /*dec r6*/
|
||||||
|
0xDE, 0xE8, /*djnz r6,C1*/
|
||||||
|
0xDD, 0xE6, /*djnz r5,C1*/
|
||||||
|
/*C3:*/
|
||||||
|
0xE5, 0xAE, /*MOV A,_FCTL*/
|
||||||
|
0x20, 0xE7, 0xFB, /*JB ACC.7,C3*/
|
||||||
|
0x00, /*nop*/
|
||||||
|
0x00, /*nop*/
|
||||||
|
/*C4:*/
|
||||||
|
0x80, 0xFE /*sjmp C4*/
|
||||||
|
};
|
||||||
|
|
||||||
|
void cdi_flash_init(void)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
/*set clock*/
|
||||||
|
cdi_reg_write(0xC6, 0xC9); /*sfr = CLKCON*/
|
||||||
|
/*set timing*/
|
||||||
|
cdi_reg_write(0xAB, 0x15); /*sfr = FWT*/
|
||||||
|
/*copy code to ram*/
|
||||||
|
cdi_dptr_write(0xE000);
|
||||||
|
for (i=0; i<sizeof(cdi_ram_code); i++)
|
||||||
|
{
|
||||||
|
cdi_xdata_write(cdi_ram_code[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdi_flash_write_page(void)
|
||||||
|
{
|
||||||
|
uint16_t retval;
|
||||||
|
uint8_t out[4];
|
||||||
|
|
||||||
|
/*set unified memory model*/
|
||||||
|
cdi_flash_bank(0, 1);
|
||||||
|
|
||||||
|
/*set FADDR to page start*/
|
||||||
|
cdi_reg_write(0xAD, (cdi_addr >> 10) & 0x7F); /*sfr = FADDRH*/
|
||||||
|
cdi_reg_write(0xAC, (cdi_addr >> 2)); /*sfr = FADDRL*/
|
||||||
|
|
||||||
|
/*erase page*/
|
||||||
|
cdi_reg_write(0xAE, 0x01);
|
||||||
|
pause_ms(40);
|
||||||
|
|
||||||
|
/*set program counter*/
|
||||||
|
out[0] = CDI_DBGINSTR + 3; /*command length 3 bytes*/
|
||||||
|
out[1] = 0x02; /*ljmp immediate16*/
|
||||||
|
out[2] = 0xE0; /*immediateh*/
|
||||||
|
out[3] = 0x00; /*immediatel*/
|
||||||
|
cdi_command_push(out, 4, &retval, 8);
|
||||||
|
|
||||||
|
/*set breakpoint*/
|
||||||
|
out[0] = CDI_SET_HW_BRKPNT; /*command length 3 bytes*/
|
||||||
|
out[1] = 0x04;
|
||||||
|
out[2] = 0xE0; /*immediateh*/
|
||||||
|
out[3] = sizeof(cdi_ram_code)-2; /*immediatel*/
|
||||||
|
cdi_command_push(out, 4, &retval, 0);
|
||||||
|
|
||||||
|
cdi_dptr_write(0xE800); /*data area, set your page data here*/
|
||||||
|
/*execute*/
|
||||||
|
out[0] = CDI_RESUME; /*command length 3 bytes*/
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
|
||||||
|
pause_ms(30);
|
||||||
|
out[3]= 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pause_ms(20);
|
||||||
|
out[0] = CDI_READ_STATUS;
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
printf("-");
|
||||||
|
fflush(stdout);
|
||||||
|
}while( ((retval & 0x20) == 0) && (out[3]++ < 200) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int cdi_flash_write(uint8_t *ptr, uint16_t length)
|
||||||
|
{
|
||||||
|
uint16_t i, retval;
|
||||||
|
uint8_t out[3];
|
||||||
|
|
||||||
|
if (length > 2048) return -1;
|
||||||
|
|
||||||
|
cdi_addr &= 0x1F800; /*make sure address is on page boundary*/
|
||||||
|
|
||||||
|
printf("0x%6.6X: ", cdi_addr);
|
||||||
|
fflush(stdout);
|
||||||
|
cdi_dptr_write(0xE800); /*our page data buffer is here*/
|
||||||
|
for (i=0; i< length; i++)
|
||||||
|
{
|
||||||
|
cdi_xdata_write(*ptr++);
|
||||||
|
if ((i & 0x3F) == 0)
|
||||||
|
{
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
if ((i & 0x0F) == 0x00)
|
||||||
|
{
|
||||||
|
printf("\bo");
|
||||||
|
}
|
||||||
|
if ((i & 0x0F) == 0x08)
|
||||||
|
{
|
||||||
|
printf("\b.");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
while(i<2048)
|
||||||
|
{
|
||||||
|
cdi_xdata_write(0xFF);
|
||||||
|
if ((i & 0x3F) == 0)
|
||||||
|
{
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
if ((i & 0x0F) == 0x00)
|
||||||
|
{
|
||||||
|
printf("\bo");
|
||||||
|
}
|
||||||
|
if ((i & 0x0F) == 0x08)
|
||||||
|
{
|
||||||
|
printf("\b.");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
out[0] = CDI_HALT;
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
|
||||||
|
out[0] = CDI_READ_STATUS;
|
||||||
|
retval = 0;
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
if ((retval & 0xFF) == 0xB2)
|
||||||
|
{
|
||||||
|
/*restore config*/
|
||||||
|
out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/
|
||||||
|
out[1] = 0x0E; /*write flash area*/
|
||||||
|
cdi_command_push(out, 2, &retval, 0);
|
||||||
|
/*set flash timings and copy code to ram*/
|
||||||
|
cdi_flash_init();
|
||||||
|
/*write page*/
|
||||||
|
cdi_flash_write_page();
|
||||||
|
cdi_addr += 2048; /*increment page address*/
|
||||||
|
pause_ms(10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cdi_flash_write_mac(uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint16_t i, retval;
|
||||||
|
uint8_t out[3];
|
||||||
|
|
||||||
|
cdi_addr = 0x1F800; /*last page*/
|
||||||
|
|
||||||
|
printf("0x%6.6X", cdi_addr);
|
||||||
|
fflush(stdout);
|
||||||
|
cdi_dptr_write(0xEFF8); /*our page data buffer is here*/
|
||||||
|
for (i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
cdi_xdata_write(*ptr++);
|
||||||
|
if ((i & 0x0F) == 0)
|
||||||
|
{
|
||||||
|
printf(".");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out[0] = CDI_HALT;
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
|
||||||
|
out[0] = CDI_READ_STATUS;
|
||||||
|
retval = 0;
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
if ((retval & 0xFF) == 0xB2)
|
||||||
|
{
|
||||||
|
/*restore config*/
|
||||||
|
out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/
|
||||||
|
out[1] = 0x0E; /*write flash area*/
|
||||||
|
cdi_command_push(out, 2, &retval, 0);
|
||||||
|
/*set flash timings and copy code to ram*/
|
||||||
|
cdi_flash_init();
|
||||||
|
/*write page*/
|
||||||
|
cdi_flash_write_page();
|
||||||
|
cdi_addr += 2048; /*increment page address*/
|
||||||
|
pause_ms(10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cdi_start(uint16_t *chip_id)
|
||||||
|
{
|
||||||
|
uint8_t out[3];
|
||||||
|
uint16_t retval;
|
||||||
|
|
||||||
|
prog_start(); /*do the CDI startup sequence*/
|
||||||
|
|
||||||
|
out[0] = CDI_READ_STATUS;
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
|
||||||
|
printf("Status: %2.2X.\n", retval & 0xFF);
|
||||||
|
|
||||||
|
out[0] = CDI_GET_CHIP_ID;
|
||||||
|
cdi_command_push(out, 1, &retval, 16);
|
||||||
|
|
||||||
|
*chip_id = retval;
|
||||||
|
|
||||||
|
out[0] = CDI_HALT;
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
|
||||||
|
pause_ms(100);
|
||||||
|
|
||||||
|
out[0] = CDI_WR_CONFIG; /*command length 3 bytes*/
|
||||||
|
out[1] = 0x0E; /*write flash area*/
|
||||||
|
cdi_command_push(out, 2, &retval, 0);
|
||||||
|
|
||||||
|
pause_ms(10);
|
||||||
|
|
||||||
|
cdi_reg_write(0xC6, 0xC9); /*sfr = CLKCON*/
|
||||||
|
|
||||||
|
pause_ms(10);
|
||||||
|
|
||||||
|
cdi_reg_write(0xAB, 0x15); /*sfr = FWT*/
|
||||||
|
|
||||||
|
cdi_addr = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cdi_erase(void)
|
||||||
|
{
|
||||||
|
uint8_t out[3];
|
||||||
|
uint16_t retval;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
out[0] = CDI_WR_CONFIG;
|
||||||
|
out[1] = 0x0E;
|
||||||
|
cdi_command_push(out, 2, &retval, 0);
|
||||||
|
out[0] = CDI_CHIP_ERASE;
|
||||||
|
cdi_command_push(out, 1, &retval, 0);
|
||||||
|
retval = 0;
|
||||||
|
i = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pause_ms(30);
|
||||||
|
out[0] = CDI_READ_STATUS;
|
||||||
|
cdi_command_push(out, 1, &retval, 8);
|
||||||
|
}while( ((retval & 0x84) != 0x80) && (i++ < 100) );
|
||||||
|
|
||||||
|
cdi_addr = 0;
|
||||||
|
|
||||||
|
if (i >= 100)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdi_set_address(uint32_t address)
|
||||||
|
{
|
||||||
|
cdi_addr = address;
|
||||||
|
}
|
44
tools/sensinode/nano_usb_programmer/cdi.h
Normal file
44
tools/sensinode/nano_usb_programmer/cdi.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
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 _CDI_H
|
||||||
|
#define _CDI_H
|
||||||
|
|
||||||
|
#include "prog.h"
|
||||||
|
|
||||||
|
/* export these */
|
||||||
|
extern int cdi_start(uint16_t *chip_id);
|
||||||
|
extern int cdi_erase(void);
|
||||||
|
|
||||||
|
extern void cdi_set_address(uint32_t address);
|
||||||
|
|
||||||
|
extern void cdi_flash_read(uint8_t *ptr, uint16_t bytes);
|
||||||
|
extern int cdi_flash_write(uint8_t *ptr, uint16_t length);
|
||||||
|
|
||||||
|
#endif
|
116
tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h
Normal file
116
tools/sensinode/nano_usb_programmer/ftdi_linux/WinTypes.h
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
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 __WINDOWS_TYPES__
|
||||||
|
#define __WINDOWS_TYPES__
|
||||||
|
|
||||||
|
#define MAX_NUM_DEVICES 50
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
typedef unsigned long DWORD;
|
||||||
|
typedef unsigned long ULONG;
|
||||||
|
typedef unsigned short USHORT;
|
||||||
|
typedef short SHORT;
|
||||||
|
typedef unsigned char UCHAR;
|
||||||
|
typedef unsigned short WORD;
|
||||||
|
typedef unsigned char BYTE;
|
||||||
|
typedef unsigned char *LPBYTE;
|
||||||
|
typedef int BOOL;
|
||||||
|
typedef char BOOLEAN;
|
||||||
|
typedef char CHAR;
|
||||||
|
typedef int *LPBOOL;
|
||||||
|
typedef unsigned char *PUCHAR;
|
||||||
|
typedef const char *LPCSTR;
|
||||||
|
typedef char *PCHAR;
|
||||||
|
typedef void *PVOID;
|
||||||
|
typedef void *HANDLE;
|
||||||
|
typedef long LONG;
|
||||||
|
typedef int INT;
|
||||||
|
typedef unsigned int UINT;
|
||||||
|
typedef char *LPSTR;
|
||||||
|
typedef char *LPTSTR;
|
||||||
|
typedef DWORD *LPDWORD;
|
||||||
|
typedef WORD *LPWORD;
|
||||||
|
typedef ULONG *PULONG;
|
||||||
|
typedef PVOID LPVOID;
|
||||||
|
typedef void VOID;
|
||||||
|
typedef unsigned long long int ULONGLONG;
|
||||||
|
|
||||||
|
typedef struct _OVERLAPPED {
|
||||||
|
DWORD Internal;
|
||||||
|
DWORD InternalHigh;
|
||||||
|
DWORD Offset;
|
||||||
|
DWORD OffsetHigh;
|
||||||
|
HANDLE hEvent;
|
||||||
|
} OVERLAPPED, *LPOVERLAPPED;
|
||||||
|
|
||||||
|
typedef struct _SECURITY_ATTRIBUTES {
|
||||||
|
DWORD nLength;
|
||||||
|
LPVOID lpSecurityDescriptor;
|
||||||
|
BOOL bInheritHandle;
|
||||||
|
} SECURITY_ATTRIBUTES , *LPSECURITY_ATTRIBUTES;
|
||||||
|
|
||||||
|
typedef struct timeval SYSTEMTIME;
|
||||||
|
typedef struct timeval FILETIME;
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Modem Status Flags
|
||||||
|
//
|
||||||
|
#define MS_CTS_ON ((DWORD)0x0010)
|
||||||
|
#define MS_DSR_ON ((DWORD)0x0020)
|
||||||
|
#define MS_RING_ON ((DWORD)0x0040)
|
||||||
|
#define MS_RLSD_ON ((DWORD)0x0080)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Error Flags
|
||||||
|
//
|
||||||
|
|
||||||
|
#define CE_RXOVER 0x0001 // Receive Queue overflow
|
||||||
|
#define CE_OVERRUN 0x0002 // Receive Overrun Error
|
||||||
|
#define CE_RXPARITY 0x0004 // Receive Parity Error
|
||||||
|
#define CE_FRAME 0x0008 // Receive Framing error
|
||||||
|
#define CE_BREAK 0x0010 // Break Detected
|
||||||
|
#define CE_TXFULL 0x0100 // TX Queue is full
|
||||||
|
#define CE_PTO 0x0200 // LPTx Timeout
|
||||||
|
#define CE_IOE 0x0400 // LPTx I/O Error
|
||||||
|
#define CE_DNS 0x0800 // LPTx Device not selected
|
||||||
|
#define CE_OOP 0x1000 // LPTx Out-Of-Paper
|
||||||
|
#define CE_MODE 0x8000 // Requested mode unsupported
|
||||||
|
|
||||||
|
#ifndef INVALID_HANDLE_VALUE
|
||||||
|
#define INVALID_HANDLE_VALUE 0xFFFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
975
tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h
Normal file
975
tools/sensinode/nano_usb_programmer/ftdi_linux/ftd2xx.h
Normal file
|
@ -0,0 +1,975 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2001-2006 Future Technology Devices International Ltd.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
ftd2xx.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Native USB interface for FTDI FT8U232/245/2232C
|
||||||
|
FTD2XX library definitions
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
|
||||||
|
kernel & user mode
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
13/03/01 awm Created.
|
||||||
|
13/01/03 awm Added device information support.
|
||||||
|
19/03/03 awm Added FT_W32_CancelIo.
|
||||||
|
12/06/03 awm Added FT_StopInTask and FT_RestartInTask.
|
||||||
|
18/09/03 awm Added FT_SetResetPipeRetryCount.
|
||||||
|
10/10/03 awm Added FT_ResetPort.
|
||||||
|
/03/04 st modified for linux users
|
||||||
|
12/10/04 st added FT_SetVIDPID
|
||||||
|
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FTD2XX_H
|
||||||
|
#define FTD2XX_H
|
||||||
|
|
||||||
|
#ifndef _WINDOWS
|
||||||
|
#include <pthread.h>
|
||||||
|
#define WINAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The following ifdef block is the standard way of creating macros
|
||||||
|
// which make exporting from a DLL simpler. All files within this DLL
|
||||||
|
// are compiled with the FTD2XX_EXPORTS symbol defined on the command line.
|
||||||
|
// This symbol should not be defined on any project that uses this DLL.
|
||||||
|
// This way any other project whose source files include this file see
|
||||||
|
// FTD2XX_API functions as being imported from a DLL, whereas this DLL
|
||||||
|
// sees symbols defined with this macro as being exported.
|
||||||
|
|
||||||
|
#ifdef FTD2XX_EXPORTS
|
||||||
|
#define FTD2XX_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define FTD2XX_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WINDOWS
|
||||||
|
#include "WinTypes.h"
|
||||||
|
|
||||||
|
#ifdef FTD2XX_API
|
||||||
|
#undef FTD2XX_API
|
||||||
|
#define FTD2XX_API
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
typedef struct _EVENT_HANDLE{
|
||||||
|
pthread_cond_t eCondVar;
|
||||||
|
pthread_mutex_t eMutex;
|
||||||
|
int iVar;
|
||||||
|
} EVENT_HANDLE;
|
||||||
|
|
||||||
|
typedef DWORD *FT_HANDLE;
|
||||||
|
|
||||||
|
typedef ULONG FT_STATUS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Device status
|
||||||
|
//
|
||||||
|
enum {
|
||||||
|
FT_OK,
|
||||||
|
FT_INVALID_HANDLE,
|
||||||
|
FT_DEVICE_NOT_FOUND,
|
||||||
|
FT_DEVICE_NOT_OPENED,
|
||||||
|
FT_IO_ERROR,
|
||||||
|
FT_INSUFFICIENT_RESOURCES,
|
||||||
|
FT_INVALID_PARAMETER,
|
||||||
|
FT_INVALID_BAUD_RATE, //7
|
||||||
|
|
||||||
|
FT_DEVICE_NOT_OPENED_FOR_ERASE,
|
||||||
|
FT_DEVICE_NOT_OPENED_FOR_WRITE,
|
||||||
|
FT_FAILED_TO_WRITE_DEVICE,
|
||||||
|
FT_EEPROM_READ_FAILED,
|
||||||
|
FT_EEPROM_WRITE_FAILED,
|
||||||
|
FT_EEPROM_ERASE_FAILED,
|
||||||
|
FT_EEPROM_NOT_PRESENT,
|
||||||
|
FT_EEPROM_NOT_PROGRAMMED,
|
||||||
|
FT_INVALID_ARGS,
|
||||||
|
FT_NOT_SUPPORTED,
|
||||||
|
FT_OTHER_ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define FT_SUCCESS(status) ((status) == FT_OK)
|
||||||
|
|
||||||
|
//
|
||||||
|
// FT_OpenEx Flags
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_OPEN_BY_SERIAL_NUMBER 1
|
||||||
|
#define FT_OPEN_BY_DESCRIPTION 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_LIST_NUMBER_ONLY 0x80000000
|
||||||
|
#define FT_LIST_BY_INDEX 0x40000000
|
||||||
|
#define FT_LIST_ALL 0x20000000
|
||||||
|
|
||||||
|
#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Baud Rates
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_BAUD_300 300
|
||||||
|
#define FT_BAUD_600 600
|
||||||
|
#define FT_BAUD_1200 1200
|
||||||
|
#define FT_BAUD_2400 2400
|
||||||
|
#define FT_BAUD_4800 4800
|
||||||
|
#define FT_BAUD_9600 9600
|
||||||
|
#define FT_BAUD_14400 14400
|
||||||
|
#define FT_BAUD_19200 19200
|
||||||
|
#define FT_BAUD_38400 38400
|
||||||
|
#define FT_BAUD_57600 57600
|
||||||
|
#define FT_BAUD_115200 115200
|
||||||
|
#define FT_BAUD_230400 230400
|
||||||
|
#define FT_BAUD_460800 460800
|
||||||
|
#define FT_BAUD_921600 921600
|
||||||
|
|
||||||
|
//
|
||||||
|
// Word Lengths
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_BITS_8 (UCHAR) 8
|
||||||
|
#define FT_BITS_7 (UCHAR) 7
|
||||||
|
#define FT_BITS_6 (UCHAR) 6
|
||||||
|
#define FT_BITS_5 (UCHAR) 5
|
||||||
|
|
||||||
|
//
|
||||||
|
// Stop Bits
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_STOP_BITS_1 (UCHAR) 0
|
||||||
|
#define FT_STOP_BITS_1_5 (UCHAR) 1
|
||||||
|
#define FT_STOP_BITS_2 (UCHAR) 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parity
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_PARITY_NONE (UCHAR) 0
|
||||||
|
#define FT_PARITY_ODD (UCHAR) 1
|
||||||
|
#define FT_PARITY_EVEN (UCHAR) 2
|
||||||
|
#define FT_PARITY_MARK (UCHAR) 3
|
||||||
|
#define FT_PARITY_SPACE (UCHAR) 4
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flow Control
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_FLOW_NONE 0x0000
|
||||||
|
#define FT_FLOW_RTS_CTS 0x0100
|
||||||
|
#define FT_FLOW_DTR_DSR 0x0200
|
||||||
|
#define FT_FLOW_XON_XOFF 0x0400
|
||||||
|
|
||||||
|
//
|
||||||
|
// Purge rx and tx buffers
|
||||||
|
//
|
||||||
|
#define FT_PURGE_RX 1
|
||||||
|
#define FT_PURGE_TX 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Events
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD);
|
||||||
|
|
||||||
|
#define FT_EVENT_RXCHAR 1
|
||||||
|
#define FT_EVENT_MODEM_STATUS 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Timeouts
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_DEFAULT_RX_TIMEOUT 300
|
||||||
|
#define FT_DEFAULT_TX_TIMEOUT 300
|
||||||
|
|
||||||
|
//
|
||||||
|
// Device types
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef ULONG FT_DEVICE;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FT_DEVICE_BM,
|
||||||
|
FT_DEVICE_AM,
|
||||||
|
FT_DEVICE_100AX,
|
||||||
|
FT_DEVICE_UNKNOWN,
|
||||||
|
FT_DEVICE_2232C,
|
||||||
|
FT_DEVICE_232R
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Open(
|
||||||
|
int deviceNumber,
|
||||||
|
FT_HANDLE *pHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_OpenEx(
|
||||||
|
PVOID pArg1,
|
||||||
|
DWORD Flags,
|
||||||
|
FT_HANDLE *pHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ListDevices(
|
||||||
|
PVOID pArg1,
|
||||||
|
PVOID pArg2,
|
||||||
|
DWORD Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS FT_SetVIDPID(
|
||||||
|
DWORD dwVID,
|
||||||
|
DWORD dwPID
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS FT_GetVIDPID(
|
||||||
|
DWORD * pdwVID,
|
||||||
|
DWORD * pdwPID
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Close(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Read(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
DWORD nBufferSize,
|
||||||
|
LPDWORD lpBytesReturned
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Write(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
DWORD nBufferSize,
|
||||||
|
LPDWORD lpBytesWritten
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_IoCtl( // Linux, OS X: Not supported
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwIoControlCode,
|
||||||
|
LPVOID lpInBuf,
|
||||||
|
DWORD nInBufSize,
|
||||||
|
LPVOID lpOutBuf,
|
||||||
|
DWORD nOutBufSize,
|
||||||
|
LPDWORD lpBytesReturned,
|
||||||
|
LPOVERLAPPED lpOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetBaudRate(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG BaudRate
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetDivisor(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
USHORT Divisor
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetDataCharacteristics(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
UCHAR WordLength,
|
||||||
|
UCHAR StopBits,
|
||||||
|
UCHAR Parity
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetFlowControl(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
USHORT FlowControl,
|
||||||
|
UCHAR XonChar,
|
||||||
|
UCHAR XoffChar
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ResetDevice(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetDtr(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ClrDtr(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetRts(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ClrRts(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetModemStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG *pModemStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetChars(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
UCHAR EventChar,
|
||||||
|
UCHAR EventCharEnabled,
|
||||||
|
UCHAR ErrorChar,
|
||||||
|
UCHAR ErrorCharEnabled
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Purge(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG Mask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetTimeouts(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG ReadTimeout,
|
||||||
|
ULONG WriteTimeout
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetQueueStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD *dwRxBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetEventNotification(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD Mask,
|
||||||
|
PVOID Param
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD *dwRxBytes,
|
||||||
|
DWORD *dwTxBytes,
|
||||||
|
DWORD *dwEventDWord
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetBreakOn(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetBreakOff(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetWaitMask( // Linux, OS X: Not supported
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD Mask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_WaitOnMask( // Linux, OS X: Not supported
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD *Mask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetEventStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD *dwEventDWord
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ReadEE(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwWordOffset,
|
||||||
|
LPWORD lpwValue
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_WriteEE(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwWordOffset,
|
||||||
|
WORD wValue
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EraseEE(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// structure to hold program data for FT_Program function
|
||||||
|
//
|
||||||
|
typedef struct ft_program_data {
|
||||||
|
|
||||||
|
DWORD Signature1; // Header - must be 0x00000000
|
||||||
|
DWORD Signature2; // Header - must be 0xffffffff
|
||||||
|
DWORD Version; // Header - FT_PROGRAM_DATA version
|
||||||
|
// 0 = original
|
||||||
|
// 1 = FT2232C extensions
|
||||||
|
// 2 = FT232R extensions
|
||||||
|
|
||||||
|
WORD VendorId; // 0x0403
|
||||||
|
WORD ProductId; // 0x6001
|
||||||
|
char *Manufacturer; // "FTDI"
|
||||||
|
char *ManufacturerId; // "FT"
|
||||||
|
char *Description; // "USB HS Serial Converter"
|
||||||
|
char *SerialNumber; // "FT000001" if fixed, or NULL
|
||||||
|
WORD MaxPower; // 0 < MaxPower <= 500
|
||||||
|
WORD PnP; // 0 = disabled, 1 = enabled
|
||||||
|
WORD SelfPowered; // 0 = bus powered, 1 = self powered
|
||||||
|
WORD RemoteWakeup; // 0 = not capable, 1 = capable
|
||||||
|
//
|
||||||
|
// Rev4 extensions
|
||||||
|
//
|
||||||
|
UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise
|
||||||
|
UCHAR IsoIn; // non-zero if in endpoint is isochronous
|
||||||
|
UCHAR IsoOut; // non-zero if out endpoint is isochronous
|
||||||
|
UCHAR PullDownEnable; // non-zero if pull down enabled
|
||||||
|
UCHAR SerNumEnable; // non-zero if serial number to be used
|
||||||
|
UCHAR USBVersionEnable; // non-zero if chip uses USBVersion
|
||||||
|
WORD USBVersion; // BCD (0x0200 => USB2)
|
||||||
|
//
|
||||||
|
// FT2232C extensions
|
||||||
|
//
|
||||||
|
UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise
|
||||||
|
UCHAR IsoInA; // non-zero if in endpoint is isochronous
|
||||||
|
UCHAR IsoInB; // non-zero if in endpoint is isochronous
|
||||||
|
UCHAR IsoOutA; // non-zero if out endpoint is isochronous
|
||||||
|
UCHAR IsoOutB; // non-zero if out endpoint is isochronous
|
||||||
|
UCHAR PullDownEnable5; // non-zero if pull down enabled
|
||||||
|
UCHAR SerNumEnable5; // non-zero if serial number to be used
|
||||||
|
UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion
|
||||||
|
WORD USBVersion5; // BCD (0x0200 => USB2)
|
||||||
|
UCHAR AIsHighCurrent; // non-zero if interface is high current
|
||||||
|
UCHAR BIsHighCurrent; // non-zero if interface is high current
|
||||||
|
UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO
|
||||||
|
UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target
|
||||||
|
UCHAR IFAIsFastSer; // non-zero if interface is Fast serial
|
||||||
|
UCHAR AIsVCP; // non-zero if interface is to use VCP drivers
|
||||||
|
UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO
|
||||||
|
UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target
|
||||||
|
UCHAR IFBIsFastSer; // non-zero if interface is Fast serial
|
||||||
|
UCHAR BIsVCP; // non-zero if interface is to use VCP drivers
|
||||||
|
//
|
||||||
|
// FT232R extensions
|
||||||
|
//
|
||||||
|
UCHAR UseExtOsc; // Use External Oscillator
|
||||||
|
UCHAR HighDriveIOs; // High Drive I/Os
|
||||||
|
UCHAR EndpointSize; // Endpoint size
|
||||||
|
|
||||||
|
UCHAR PullDownEnableR; // non-zero if pull down enabled
|
||||||
|
UCHAR SerNumEnableR; // non-zero if serial number to be used
|
||||||
|
|
||||||
|
UCHAR InvertTXD; // non-zero if invert TXD
|
||||||
|
UCHAR InvertRXD; // non-zero if invert RXD
|
||||||
|
UCHAR InvertRTS; // non-zero if invert RTS
|
||||||
|
UCHAR InvertCTS; // non-zero if invert CTS
|
||||||
|
UCHAR InvertDTR; // non-zero if invert DTR
|
||||||
|
UCHAR InvertDSR; // non-zero if invert DSR
|
||||||
|
UCHAR InvertDCD; // non-zero if invert DCD
|
||||||
|
UCHAR InvertRI; // non-zero if invert RI
|
||||||
|
|
||||||
|
UCHAR Cbus0; // Cbus Mux control
|
||||||
|
UCHAR Cbus1; // Cbus Mux control
|
||||||
|
UCHAR Cbus2; // Cbus Mux control
|
||||||
|
UCHAR Cbus3; // Cbus Mux control
|
||||||
|
UCHAR Cbus4; // Cbus Mux control
|
||||||
|
|
||||||
|
UCHAR RIsVCP; // zero if using VCP drivers
|
||||||
|
|
||||||
|
} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_Program(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PFT_PROGRAM_DATA pData
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_ProgramEx(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PFT_PROGRAM_DATA lpData,
|
||||||
|
char *Manufacturer,
|
||||||
|
char *ManufacturerId,
|
||||||
|
char *Description,
|
||||||
|
char *SerialNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_Read(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PFT_PROGRAM_DATA pData
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_ReadEx(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PFT_PROGRAM_DATA lpData,
|
||||||
|
char *Manufacturer,
|
||||||
|
char *ManufacturerId,
|
||||||
|
char *Description,
|
||||||
|
char *SerialNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_UASize(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwSize
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_UAWrite(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PUCHAR pucData,
|
||||||
|
DWORD dwDataLen
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_UARead(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PUCHAR pucData,
|
||||||
|
DWORD dwDataLen,
|
||||||
|
LPDWORD lpdwBytesRead
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetLatencyTimer(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
UCHAR ucLatency
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetLatencyTimer(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PUCHAR pucLatency
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetBitMode(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
UCHAR ucMask,
|
||||||
|
UCHAR ucEnable
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetBitMode(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PUCHAR pucMode
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetUSBParameters(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG ulInTransferSize,
|
||||||
|
ULONG ulOutTransferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetDeadmanTimeout(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG ulDeadmanTimeout
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetDeviceInfo(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
FT_DEVICE *lpftDevice,
|
||||||
|
LPDWORD lpdwID,
|
||||||
|
PCHAR SerialNumber,
|
||||||
|
PCHAR Description,
|
||||||
|
LPVOID Dummy
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_StopInTask(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_RestartInTask(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetResetPipeRetryCount( // Linux, OS X: Not supported
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwCount
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ResetPort( // Linux, OS X: Not supported
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_CyclePort( // Linux, OS X: Not supported
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Win32-type functions
|
||||||
|
//
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_HANDLE WINAPI FT_W32_CreateFile(
|
||||||
|
LPCSTR lpszName,
|
||||||
|
DWORD dwAccess,
|
||||||
|
DWORD dwShareMode,
|
||||||
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||||
|
DWORD dwCreate,
|
||||||
|
DWORD dwAttrsAndFlags,
|
||||||
|
HANDLE hTemplate
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_CloseHandle(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_ReadFile(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
DWORD nBufferSize,
|
||||||
|
LPDWORD lpBytesReturned,
|
||||||
|
LPOVERLAPPED lpOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_WriteFile(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
DWORD nBufferSize,
|
||||||
|
LPDWORD lpBytesWritten,
|
||||||
|
LPOVERLAPPED lpOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
DWORD WINAPI FT_W32_GetLastError(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetOverlappedResult( // Linux, OS X: Not supported
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPOVERLAPPED lpOverlapped,
|
||||||
|
LPDWORD lpdwBytesTransferred,
|
||||||
|
BOOL bWait
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_CancelIo( // Linux, OS X: Not supported
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Win32 COMM API type functions
|
||||||
|
//
|
||||||
|
typedef struct _FTCOMSTAT {
|
||||||
|
DWORD fCtsHold : 1;
|
||||||
|
DWORD fDsrHold : 1;
|
||||||
|
DWORD fRlsdHold : 1;
|
||||||
|
DWORD fXoffHold : 1;
|
||||||
|
DWORD fXoffSent : 1;
|
||||||
|
DWORD fEof : 1;
|
||||||
|
DWORD fTxim : 1;
|
||||||
|
DWORD fReserved : 25;
|
||||||
|
DWORD cbInQue;
|
||||||
|
DWORD cbOutQue;
|
||||||
|
} FTCOMSTAT, *LPFTCOMSTAT;
|
||||||
|
|
||||||
|
typedef struct _FTDCB {
|
||||||
|
DWORD DCBlength; /* sizeof(FTDCB) */
|
||||||
|
DWORD BaudRate; /* Baudrate at which running */
|
||||||
|
DWORD fBinary: 1; /* Binary Mode (skip EOF check) */
|
||||||
|
DWORD fParity: 1; /* Enable parity checking */
|
||||||
|
DWORD fOutxCtsFlow:1; /* CTS handshaking on output */
|
||||||
|
DWORD fOutxDsrFlow:1; /* DSR handshaking on output */
|
||||||
|
DWORD fDtrControl:2; /* DTR Flow control */
|
||||||
|
DWORD fDsrSensitivity:1; /* DSR Sensitivity */
|
||||||
|
DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
|
||||||
|
DWORD fOutX: 1; /* Enable output X-ON/X-OFF */
|
||||||
|
DWORD fInX: 1; /* Enable input X-ON/X-OFF */
|
||||||
|
DWORD fErrorChar: 1; /* Enable Err Replacement */
|
||||||
|
DWORD fNull: 1; /* Enable Null stripping */
|
||||||
|
DWORD fRtsControl:2; /* Rts Flow control */
|
||||||
|
DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
|
||||||
|
DWORD fDummy2:17; /* Reserved */
|
||||||
|
WORD wReserved; /* Not currently used */
|
||||||
|
WORD XonLim; /* Transmit X-ON threshold */
|
||||||
|
WORD XoffLim; /* Transmit X-OFF threshold */
|
||||||
|
BYTE ByteSize; /* Number of bits/byte, 4-8 */
|
||||||
|
BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */
|
||||||
|
BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */
|
||||||
|
char XonChar; /* Tx and Rx X-ON character */
|
||||||
|
char XoffChar; /* Tx and Rx X-OFF character */
|
||||||
|
char ErrorChar; /* Error replacement char */
|
||||||
|
char EofChar; /* End of Input character */
|
||||||
|
char EvtChar; /* Received Event character */
|
||||||
|
WORD wReserved1; /* Fill for now. */
|
||||||
|
} FTDCB, *LPFTDCB;
|
||||||
|
|
||||||
|
typedef struct _FTTIMEOUTS {
|
||||||
|
DWORD ReadIntervalTimeout; /* Maximum time between read chars. */
|
||||||
|
DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */
|
||||||
|
DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */
|
||||||
|
DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */
|
||||||
|
DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */
|
||||||
|
} FTTIMEOUTS,*LPFTTIMEOUTS;
|
||||||
|
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_ClearCommBreak(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_ClearCommError(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwErrors,
|
||||||
|
LPFTCOMSTAT lpftComstat
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_EscapeCommFunction(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwFunc
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetCommModemStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwModemStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetCommState(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPFTDCB lpftDcb
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetCommTimeouts(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
FTTIMEOUTS *pTimeouts
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_PurgeComm(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwMask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetCommBreak(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetCommMask(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG ulEventMask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetCommState(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPFTDCB lpftDcb
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetCommTimeouts(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
FTTIMEOUTS *pTimeouts
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetupComm(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwReadBufferSize,
|
||||||
|
DWORD dwWriteBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_WaitCommEvent(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PULONG pulEvent,
|
||||||
|
LPOVERLAPPED lpOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Device information
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct _ft_device_list_info_node {
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG Type;
|
||||||
|
ULONG ID;
|
||||||
|
DWORD LocId;
|
||||||
|
char SerialNumber[16];
|
||||||
|
char Description[64];
|
||||||
|
FT_HANDLE ftHandle;
|
||||||
|
} FT_DEVICE_LIST_INFO_NODE;
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_CreateDeviceInfoList(
|
||||||
|
LPDWORD lpdwNumDevs
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetDeviceInfoList(
|
||||||
|
FT_DEVICE_LIST_INFO_NODE *pDest,
|
||||||
|
LPDWORD lpdwNumDevs
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetDeviceInfoDetail(
|
||||||
|
DWORD dwIndex,
|
||||||
|
LPDWORD lpdwFlags,
|
||||||
|
LPDWORD lpdwType,
|
||||||
|
LPDWORD lpdwID,
|
||||||
|
LPDWORD lpdwLocId,
|
||||||
|
LPVOID lpSerialNumber,
|
||||||
|
LPVOID lpDescription,
|
||||||
|
FT_HANDLE *pftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetDriverVersion(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwVersion
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetLibraryVersion(
|
||||||
|
LPDWORD lpdwVersion
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Events
|
||||||
|
//
|
||||||
|
|
||||||
|
#define EV_RXCHAR 0x0001 // Any Character received
|
||||||
|
#define EV_RXFLAG 0x0002 // Received certain character
|
||||||
|
#define EV_TXEMPTY 0x0004 // Transmitt Queue Empty
|
||||||
|
#define EV_CTS 0x0008 // CTS changed state
|
||||||
|
#define EV_DSR 0x0010 // DSR changed state
|
||||||
|
#define EV_RLSD 0x0020 // RLSD changed state
|
||||||
|
#define EV_BREAK 0x0040 // BREAK received
|
||||||
|
#define EV_ERR 0x0080 // Line status error occurred
|
||||||
|
#define EV_RING 0x0100 // Ring signal detected
|
||||||
|
#define EV_PERR 0x0200 // Printer error occured
|
||||||
|
#define EV_RX80FULL 0x0400 // Receive buffer is 80 percent full
|
||||||
|
#define EV_EVENT1 0x0800 // Provider specific event 1
|
||||||
|
#define EV_EVENT2 0x1000 // Provider specific event 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Escape Functions
|
||||||
|
//
|
||||||
|
|
||||||
|
#define SETXOFF 1 // Simulate XOFF received
|
||||||
|
#define SETXON 2 // Simulate XON received
|
||||||
|
#define SETRTS 3 // Set RTS high
|
||||||
|
#define CLRRTS 4 // Set RTS low
|
||||||
|
#define SETDTR 5 // Set DTR high
|
||||||
|
#define CLRDTR 6 // Set DTR low
|
||||||
|
#define RESETDEV 7 // Reset device if possible
|
||||||
|
#define SETBREAK 8 // Set the device break line.
|
||||||
|
#define CLRBREAK 9 // Clear the device break line.
|
||||||
|
|
||||||
|
//
|
||||||
|
// PURGE function flags.
|
||||||
|
//
|
||||||
|
#define PURGE_TXABORT 0x0001 // Kill the pending/current writes to the comm port.
|
||||||
|
#define PURGE_RXABORT 0x0002 // Kill the pending/current reads to the comm port.
|
||||||
|
#define PURGE_TXCLEAR 0x0004 // Kill the transmit queue if there.
|
||||||
|
#define PURGE_RXCLEAR 0x0008 // Kill the typeahead buffer if there.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FTD2XX_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
923
tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h
Executable file
923
tools/sensinode/nano_usb_programmer/ftdi_win32/ftd2xx.h
Executable file
|
@ -0,0 +1,923 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 2001-2006 Future Technology Devices International Ltd.
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
ftd2xx.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Native USB device driver for FTDI FT8U232/245
|
||||||
|
FTD2XX library definitions
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
|
||||||
|
kernel & user mode
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
13/03/01 awm Created.
|
||||||
|
13/01/03 awm Added device information support.
|
||||||
|
19/03/03 awm Added FT_W32_CancelIo.
|
||||||
|
12/06/03 awm Added FT_StopInTask and FT_RestartInTask.
|
||||||
|
18/09/03 awm Added FT_SetResetPipeRetryCount.
|
||||||
|
10/10/03 awm Added FT_ResetPort.
|
||||||
|
23/01/04 awm Added support for open-by-location.
|
||||||
|
16/03/04 awm Added support for FT2232C.
|
||||||
|
23/09/04 awm Added support for FT232R.
|
||||||
|
20/10/04 awm Added FT_CyclePort.
|
||||||
|
18/01/05 awm Added FT_DEVICE_LIST_INFO_NODE type.
|
||||||
|
11/02/05 awm Added LocId to FT_DEVICE_LIST_INFO_NODE.
|
||||||
|
25/08/05 awm Added FT_SetDeadmanTimeout.
|
||||||
|
02/12/05 awm Removed obsolete references.
|
||||||
|
05/12/05 awm Added FT_GetVersion, FT_GetVersionEx.
|
||||||
|
08/09/06 awm Added FT_W32_GetCommMask.
|
||||||
|
11/09/06 awm Added FT_Rescan.
|
||||||
|
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FTD2XX_H
|
||||||
|
#define FTD2XX_H
|
||||||
|
|
||||||
|
// The following ifdef block is the standard way of creating macros
|
||||||
|
// which make exporting from a DLL simpler. All files within this DLL
|
||||||
|
// are compiled with the FTD2XX_EXPORTS symbol defined on the command line.
|
||||||
|
// This symbol should not be defined on any project that uses this DLL.
|
||||||
|
// This way any other project whose source files include this file see
|
||||||
|
// FTD2XX_API functions as being imported from a DLL, whereas this DLL
|
||||||
|
// sees symbols defined with this macro as being exported.
|
||||||
|
|
||||||
|
#ifdef FTD2XX_EXPORTS
|
||||||
|
#define FTD2XX_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define FTD2XX_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef PVOID FT_HANDLE;
|
||||||
|
typedef ULONG FT_STATUS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Device status
|
||||||
|
//
|
||||||
|
enum {
|
||||||
|
FT_OK,
|
||||||
|
FT_INVALID_HANDLE,
|
||||||
|
FT_DEVICE_NOT_FOUND,
|
||||||
|
FT_DEVICE_NOT_OPENED,
|
||||||
|
FT_IO_ERROR,
|
||||||
|
FT_INSUFFICIENT_RESOURCES,
|
||||||
|
FT_INVALID_PARAMETER,
|
||||||
|
FT_INVALID_BAUD_RATE,
|
||||||
|
|
||||||
|
FT_DEVICE_NOT_OPENED_FOR_ERASE,
|
||||||
|
FT_DEVICE_NOT_OPENED_FOR_WRITE,
|
||||||
|
FT_FAILED_TO_WRITE_DEVICE,
|
||||||
|
FT_EEPROM_READ_FAILED,
|
||||||
|
FT_EEPROM_WRITE_FAILED,
|
||||||
|
FT_EEPROM_ERASE_FAILED,
|
||||||
|
FT_EEPROM_NOT_PRESENT,
|
||||||
|
FT_EEPROM_NOT_PROGRAMMED,
|
||||||
|
FT_INVALID_ARGS,
|
||||||
|
FT_NOT_SUPPORTED,
|
||||||
|
FT_OTHER_ERROR,
|
||||||
|
FT_DEVICE_LIST_NOT_READY,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define FT_SUCCESS(status) ((status) == FT_OK)
|
||||||
|
|
||||||
|
//
|
||||||
|
// FT_OpenEx Flags
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_OPEN_BY_SERIAL_NUMBER 1
|
||||||
|
#define FT_OPEN_BY_DESCRIPTION 2
|
||||||
|
#define FT_OPEN_BY_LOCATION 4
|
||||||
|
|
||||||
|
//
|
||||||
|
// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_LIST_NUMBER_ONLY 0x80000000
|
||||||
|
#define FT_LIST_BY_INDEX 0x40000000
|
||||||
|
#define FT_LIST_ALL 0x20000000
|
||||||
|
|
||||||
|
#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Baud Rates
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_BAUD_300 300
|
||||||
|
#define FT_BAUD_600 600
|
||||||
|
#define FT_BAUD_1200 1200
|
||||||
|
#define FT_BAUD_2400 2400
|
||||||
|
#define FT_BAUD_4800 4800
|
||||||
|
#define FT_BAUD_9600 9600
|
||||||
|
#define FT_BAUD_14400 14400
|
||||||
|
#define FT_BAUD_19200 19200
|
||||||
|
#define FT_BAUD_38400 38400
|
||||||
|
#define FT_BAUD_57600 57600
|
||||||
|
#define FT_BAUD_115200 115200
|
||||||
|
#define FT_BAUD_230400 230400
|
||||||
|
#define FT_BAUD_460800 460800
|
||||||
|
#define FT_BAUD_921600 921600
|
||||||
|
|
||||||
|
//
|
||||||
|
// Word Lengths
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_BITS_8 (UCHAR) 8
|
||||||
|
#define FT_BITS_7 (UCHAR) 7
|
||||||
|
#define FT_BITS_6 (UCHAR) 6
|
||||||
|
#define FT_BITS_5 (UCHAR) 5
|
||||||
|
|
||||||
|
//
|
||||||
|
// Stop Bits
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_STOP_BITS_1 (UCHAR) 0
|
||||||
|
#define FT_STOP_BITS_1_5 (UCHAR) 1
|
||||||
|
#define FT_STOP_BITS_2 (UCHAR) 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parity
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_PARITY_NONE (UCHAR) 0
|
||||||
|
#define FT_PARITY_ODD (UCHAR) 1
|
||||||
|
#define FT_PARITY_EVEN (UCHAR) 2
|
||||||
|
#define FT_PARITY_MARK (UCHAR) 3
|
||||||
|
#define FT_PARITY_SPACE (UCHAR) 4
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flow Control
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_FLOW_NONE 0x0000
|
||||||
|
#define FT_FLOW_RTS_CTS 0x0100
|
||||||
|
#define FT_FLOW_DTR_DSR 0x0200
|
||||||
|
#define FT_FLOW_XON_XOFF 0x0400
|
||||||
|
|
||||||
|
//
|
||||||
|
// Purge rx and tx buffers
|
||||||
|
//
|
||||||
|
#define FT_PURGE_RX 1
|
||||||
|
#define FT_PURGE_TX 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Events
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD);
|
||||||
|
|
||||||
|
#define FT_EVENT_RXCHAR 1
|
||||||
|
#define FT_EVENT_MODEM_STATUS 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Timeouts
|
||||||
|
//
|
||||||
|
|
||||||
|
#define FT_DEFAULT_RX_TIMEOUT 300
|
||||||
|
#define FT_DEFAULT_TX_TIMEOUT 300
|
||||||
|
|
||||||
|
//
|
||||||
|
// Device types
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef ULONG FT_DEVICE;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FT_DEVICE_BM,
|
||||||
|
FT_DEVICE_AM,
|
||||||
|
FT_DEVICE_100AX,
|
||||||
|
FT_DEVICE_UNKNOWN,
|
||||||
|
FT_DEVICE_2232C,
|
||||||
|
FT_DEVICE_232R
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Open(
|
||||||
|
int deviceNumber,
|
||||||
|
FT_HANDLE *pHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_OpenEx(
|
||||||
|
PVOID pArg1,
|
||||||
|
DWORD Flags,
|
||||||
|
FT_HANDLE *pHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ListDevices(
|
||||||
|
PVOID pArg1,
|
||||||
|
PVOID pArg2,
|
||||||
|
DWORD Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Close(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Read(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
DWORD nBufferSize,
|
||||||
|
LPDWORD lpBytesReturned
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Write(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
DWORD nBufferSize,
|
||||||
|
LPDWORD lpBytesWritten
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_IoCtl(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwIoControlCode,
|
||||||
|
LPVOID lpInBuf,
|
||||||
|
DWORD nInBufSize,
|
||||||
|
LPVOID lpOutBuf,
|
||||||
|
DWORD nOutBufSize,
|
||||||
|
LPDWORD lpBytesReturned,
|
||||||
|
LPOVERLAPPED lpOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetBaudRate(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG BaudRate
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetDivisor(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
USHORT Divisor
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetDataCharacteristics(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
UCHAR WordLength,
|
||||||
|
UCHAR StopBits,
|
||||||
|
UCHAR Parity
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetFlowControl(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
USHORT FlowControl,
|
||||||
|
UCHAR XonChar,
|
||||||
|
UCHAR XoffChar
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ResetDevice(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetDtr(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ClrDtr(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetRts(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ClrRts(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetModemStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG *pModemStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetChars(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
UCHAR EventChar,
|
||||||
|
UCHAR EventCharEnabled,
|
||||||
|
UCHAR ErrorChar,
|
||||||
|
UCHAR ErrorCharEnabled
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Purge(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG Mask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetTimeouts(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG ReadTimeout,
|
||||||
|
ULONG WriteTimeout
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetQueueStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD *dwRxBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetEventNotification(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD Mask,
|
||||||
|
PVOID Param
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD *dwRxBytes,
|
||||||
|
DWORD *dwTxBytes,
|
||||||
|
DWORD *dwEventDWord
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetBreakOn(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetBreakOff(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetWaitMask(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD Mask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_WaitOnMask(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD *Mask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetEventStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD *dwEventDWord
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ReadEE(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwWordOffset,
|
||||||
|
LPWORD lpwValue
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_WriteEE(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwWordOffset,
|
||||||
|
WORD wValue
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EraseEE(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// structure to hold program data for FT_Program function
|
||||||
|
//
|
||||||
|
typedef struct ft_program_data {
|
||||||
|
|
||||||
|
DWORD Signature1; // Header - must be 0x00000000
|
||||||
|
DWORD Signature2; // Header - must be 0xffffffff
|
||||||
|
DWORD Version; // Header - FT_PROGRAM_DATA version
|
||||||
|
// 0 = original
|
||||||
|
// 1 = FT2232C extensions
|
||||||
|
// 2 = FT232R extensions
|
||||||
|
|
||||||
|
WORD VendorId; // 0x0403
|
||||||
|
WORD ProductId; // 0x6001
|
||||||
|
char *Manufacturer; // "FTDI"
|
||||||
|
char *ManufacturerId; // "FT"
|
||||||
|
char *Description; // "USB HS Serial Converter"
|
||||||
|
char *SerialNumber; // "FT000001" if fixed, or NULL
|
||||||
|
WORD MaxPower; // 0 < MaxPower <= 500
|
||||||
|
WORD PnP; // 0 = disabled, 1 = enabled
|
||||||
|
WORD SelfPowered; // 0 = bus powered, 1 = self powered
|
||||||
|
WORD RemoteWakeup; // 0 = not capable, 1 = capable
|
||||||
|
//
|
||||||
|
// Rev4 extensions
|
||||||
|
//
|
||||||
|
UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise
|
||||||
|
UCHAR IsoIn; // non-zero if in endpoint is isochronous
|
||||||
|
UCHAR IsoOut; // non-zero if out endpoint is isochronous
|
||||||
|
UCHAR PullDownEnable; // non-zero if pull down enabled
|
||||||
|
UCHAR SerNumEnable; // non-zero if serial number to be used
|
||||||
|
UCHAR USBVersionEnable; // non-zero if chip uses USBVersion
|
||||||
|
WORD USBVersion; // BCD (0x0200 => USB2)
|
||||||
|
//
|
||||||
|
// FT2232C extensions
|
||||||
|
//
|
||||||
|
UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise
|
||||||
|
UCHAR IsoInA; // non-zero if in endpoint is isochronous
|
||||||
|
UCHAR IsoInB; // non-zero if in endpoint is isochronous
|
||||||
|
UCHAR IsoOutA; // non-zero if out endpoint is isochronous
|
||||||
|
UCHAR IsoOutB; // non-zero if out endpoint is isochronous
|
||||||
|
UCHAR PullDownEnable5; // non-zero if pull down enabled
|
||||||
|
UCHAR SerNumEnable5; // non-zero if serial number to be used
|
||||||
|
UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion
|
||||||
|
WORD USBVersion5; // BCD (0x0200 => USB2)
|
||||||
|
UCHAR AIsHighCurrent; // non-zero if interface is high current
|
||||||
|
UCHAR BIsHighCurrent; // non-zero if interface is high current
|
||||||
|
UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO
|
||||||
|
UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target
|
||||||
|
UCHAR IFAIsFastSer; // non-zero if interface is Fast serial
|
||||||
|
UCHAR AIsVCP; // non-zero if interface is to use VCP drivers
|
||||||
|
UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO
|
||||||
|
UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target
|
||||||
|
UCHAR IFBIsFastSer; // non-zero if interface is Fast serial
|
||||||
|
UCHAR BIsVCP; // non-zero if interface is to use VCP drivers
|
||||||
|
//
|
||||||
|
// FT232R extensions
|
||||||
|
//
|
||||||
|
UCHAR UseExtOsc; // Use External Oscillator
|
||||||
|
UCHAR HighDriveIOs; // High Drive I/Os
|
||||||
|
UCHAR EndpointSize; // Endpoint size
|
||||||
|
|
||||||
|
UCHAR PullDownEnableR; // non-zero if pull down enabled
|
||||||
|
UCHAR SerNumEnableR; // non-zero if serial number to be used
|
||||||
|
|
||||||
|
UCHAR InvertTXD; // non-zero if invert TXD
|
||||||
|
UCHAR InvertRXD; // non-zero if invert RXD
|
||||||
|
UCHAR InvertRTS; // non-zero if invert RTS
|
||||||
|
UCHAR InvertCTS; // non-zero if invert CTS
|
||||||
|
UCHAR InvertDTR; // non-zero if invert DTR
|
||||||
|
UCHAR InvertDSR; // non-zero if invert DSR
|
||||||
|
UCHAR InvertDCD; // non-zero if invert DCD
|
||||||
|
UCHAR InvertRI; // non-zero if invert RI
|
||||||
|
|
||||||
|
UCHAR Cbus0; // Cbus Mux control
|
||||||
|
UCHAR Cbus1; // Cbus Mux control
|
||||||
|
UCHAR Cbus2; // Cbus Mux control
|
||||||
|
UCHAR Cbus3; // Cbus Mux control
|
||||||
|
UCHAR Cbus4; // Cbus Mux control
|
||||||
|
|
||||||
|
UCHAR RIsD2XX; // non-zero if using D2XX driver
|
||||||
|
|
||||||
|
} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA;
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_Program(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PFT_PROGRAM_DATA pData
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_ProgramEx(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PFT_PROGRAM_DATA pData,
|
||||||
|
char *Manufacturer,
|
||||||
|
char *ManufacturerId,
|
||||||
|
char *Description,
|
||||||
|
char *SerialNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_Read(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PFT_PROGRAM_DATA pData
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_ReadEx(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PFT_PROGRAM_DATA pData,
|
||||||
|
char *Manufacturer,
|
||||||
|
char *ManufacturerId,
|
||||||
|
char *Description,
|
||||||
|
char *SerialNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_UASize(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwSize
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_UAWrite(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PUCHAR pucData,
|
||||||
|
DWORD dwDataLen
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_EE_UARead(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PUCHAR pucData,
|
||||||
|
DWORD dwDataLen,
|
||||||
|
LPDWORD lpdwBytesRead
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetLatencyTimer(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
UCHAR ucLatency
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetLatencyTimer(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PUCHAR pucLatency
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetBitMode(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
UCHAR ucMask,
|
||||||
|
UCHAR ucEnable
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetBitMode(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PUCHAR pucMode
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetUSBParameters(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG ulInTransferSize,
|
||||||
|
ULONG ulOutTransferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetDeadmanTimeout(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG ulDeadmanTimeout
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetDeviceInfo(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
FT_DEVICE *lpftDevice,
|
||||||
|
LPDWORD lpdwID,
|
||||||
|
PCHAR SerialNumber,
|
||||||
|
PCHAR Description,
|
||||||
|
LPVOID Dummy
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_StopInTask(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_RestartInTask(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_SetResetPipeRetryCount(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwCount
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_ResetPort(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_CyclePort(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Win32-type functions
|
||||||
|
//
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_HANDLE WINAPI FT_W32_CreateFile(
|
||||||
|
LPCTSTR lpszName,
|
||||||
|
DWORD dwAccess,
|
||||||
|
DWORD dwShareMode,
|
||||||
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||||
|
DWORD dwCreate,
|
||||||
|
DWORD dwAttrsAndFlags,
|
||||||
|
HANDLE hTemplate
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_CloseHandle(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_ReadFile(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
DWORD nBufferSize,
|
||||||
|
LPDWORD lpBytesReturned,
|
||||||
|
LPOVERLAPPED lpOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_WriteFile(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
DWORD nBufferSize,
|
||||||
|
LPDWORD lpBytesWritten,
|
||||||
|
LPOVERLAPPED lpOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
DWORD WINAPI FT_W32_GetLastError(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetOverlappedResult(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPOVERLAPPED lpOverlapped,
|
||||||
|
LPDWORD lpdwBytesTransferred,
|
||||||
|
BOOL bWait
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_CancelIo(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Win32 COMM API type functions
|
||||||
|
//
|
||||||
|
typedef struct _FTCOMSTAT {
|
||||||
|
DWORD fCtsHold : 1;
|
||||||
|
DWORD fDsrHold : 1;
|
||||||
|
DWORD fRlsdHold : 1;
|
||||||
|
DWORD fXoffHold : 1;
|
||||||
|
DWORD fXoffSent : 1;
|
||||||
|
DWORD fEof : 1;
|
||||||
|
DWORD fTxim : 1;
|
||||||
|
DWORD fReserved : 25;
|
||||||
|
DWORD cbInQue;
|
||||||
|
DWORD cbOutQue;
|
||||||
|
} FTCOMSTAT, *LPFTCOMSTAT;
|
||||||
|
|
||||||
|
typedef struct _FTDCB {
|
||||||
|
DWORD DCBlength; /* sizeof(FTDCB) */
|
||||||
|
DWORD BaudRate; /* Baudrate at which running */
|
||||||
|
DWORD fBinary: 1; /* Binary Mode (skip EOF check) */
|
||||||
|
DWORD fParity: 1; /* Enable parity checking */
|
||||||
|
DWORD fOutxCtsFlow:1; /* CTS handshaking on output */
|
||||||
|
DWORD fOutxDsrFlow:1; /* DSR handshaking on output */
|
||||||
|
DWORD fDtrControl:2; /* DTR Flow control */
|
||||||
|
DWORD fDsrSensitivity:1; /* DSR Sensitivity */
|
||||||
|
DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
|
||||||
|
DWORD fOutX: 1; /* Enable output X-ON/X-OFF */
|
||||||
|
DWORD fInX: 1; /* Enable input X-ON/X-OFF */
|
||||||
|
DWORD fErrorChar: 1; /* Enable Err Replacement */
|
||||||
|
DWORD fNull: 1; /* Enable Null stripping */
|
||||||
|
DWORD fRtsControl:2; /* Rts Flow control */
|
||||||
|
DWORD fAbortOnError:1; /* Abort all reads and writes on Error */
|
||||||
|
DWORD fDummy2:17; /* Reserved */
|
||||||
|
WORD wReserved; /* Not currently used */
|
||||||
|
WORD XonLim; /* Transmit X-ON threshold */
|
||||||
|
WORD XoffLim; /* Transmit X-OFF threshold */
|
||||||
|
BYTE ByteSize; /* Number of bits/byte, 4-8 */
|
||||||
|
BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */
|
||||||
|
BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */
|
||||||
|
char XonChar; /* Tx and Rx X-ON character */
|
||||||
|
char XoffChar; /* Tx and Rx X-OFF character */
|
||||||
|
char ErrorChar; /* Error replacement char */
|
||||||
|
char EofChar; /* End of Input character */
|
||||||
|
char EvtChar; /* Received Event character */
|
||||||
|
WORD wReserved1; /* Fill for now. */
|
||||||
|
} FTDCB, *LPFTDCB;
|
||||||
|
|
||||||
|
typedef struct _FTTIMEOUTS {
|
||||||
|
DWORD ReadIntervalTimeout; /* Maximum time between read chars. */
|
||||||
|
DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */
|
||||||
|
DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */
|
||||||
|
DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */
|
||||||
|
DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */
|
||||||
|
} FTTIMEOUTS,*LPFTTIMEOUTS;
|
||||||
|
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_ClearCommBreak(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_ClearCommError(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwErrors,
|
||||||
|
LPFTCOMSTAT lpftComstat
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_EscapeCommFunction(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwFunc
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetCommModemStatus(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwModemStatus
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetCommState(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPFTDCB lpftDcb
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetCommTimeouts(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
FTTIMEOUTS *pTimeouts
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_PurgeComm(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwMask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetCommBreak(
|
||||||
|
FT_HANDLE ftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetCommMask(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
ULONG ulEventMask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_GetCommMask(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwEventMask
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetCommState(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPFTDCB lpftDcb
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetCommTimeouts(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
FTTIMEOUTS *pTimeouts
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_SetupComm(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
DWORD dwReadBufferSize,
|
||||||
|
DWORD dwWriteBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
BOOL WINAPI FT_W32_WaitCommEvent(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
PULONG pulEvent,
|
||||||
|
LPOVERLAPPED lpOverlapped
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Device information
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct _ft_device_list_info_node {
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG Type;
|
||||||
|
ULONG ID;
|
||||||
|
DWORD LocId;
|
||||||
|
char SerialNumber[16];
|
||||||
|
char Description[64];
|
||||||
|
FT_HANDLE ftHandle;
|
||||||
|
} FT_DEVICE_LIST_INFO_NODE;
|
||||||
|
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_CreateDeviceInfoList(
|
||||||
|
LPDWORD lpdwNumDevs
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetDeviceInfoList(
|
||||||
|
FT_DEVICE_LIST_INFO_NODE *pDest,
|
||||||
|
LPDWORD lpdwNumDevs
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetDeviceInfoDetail(
|
||||||
|
DWORD dwIndex,
|
||||||
|
LPDWORD lpdwFlags,
|
||||||
|
LPDWORD lpdwType,
|
||||||
|
LPDWORD lpdwID,
|
||||||
|
LPDWORD lpdwLocId,
|
||||||
|
LPVOID lpSerialNumber,
|
||||||
|
LPVOID lpDescription,
|
||||||
|
FT_HANDLE *pftHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Version information
|
||||||
|
//
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetDriverVersion(
|
||||||
|
FT_HANDLE ftHandle,
|
||||||
|
LPDWORD lpdwVersion
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_GetLibraryVersion(
|
||||||
|
LPDWORD lpdwVersion
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Rescan(
|
||||||
|
void
|
||||||
|
);
|
||||||
|
|
||||||
|
FTD2XX_API
|
||||||
|
FT_STATUS WINAPI FT_Reload(
|
||||||
|
WORD wVid,
|
||||||
|
WORD wPid
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* FTD2XX_H */
|
||||||
|
|
210
tools/sensinode/nano_usb_programmer/ihex.c
Normal file
210
tools/sensinode/nano_usb_programmer/ihex.c
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
/*
|
||||||
|
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_build_tables(char *ihexfile, unsigned char *page_buffer, unsigned char *page_table)
|
||||||
|
{
|
||||||
|
unsigned char buffer[256];
|
||||||
|
int length;
|
||||||
|
int i;
|
||||||
|
int pages;
|
||||||
|
|
||||||
|
unsigned long ext_addr=0;
|
||||||
|
unsigned short int addr=0;
|
||||||
|
FILE *ihex_fp;
|
||||||
|
|
||||||
|
if((ihex_fp = (FILE *)fopen(ihexfile, "r")) == NULL)
|
||||||
|
{
|
||||||
|
printf("Failed to open .ihex file %s\n", ihexfile);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(".ihex file ok.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
/*initialize page data*/
|
||||||
|
memset(page_table, 0, 64);
|
||||||
|
memset(page_buffer, 0xFF, sizeof(page_buffer));
|
||||||
|
pages = 0;
|
||||||
|
|
||||||
|
while((fscanf(ihex_fp, "%s", buffer) == 1))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
printf("Writing %d pages.\r", ++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");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (memcmp(&buffer[7], "04", 2) == 0)
|
||||||
|
{
|
||||||
|
sscanf((char *)&(buffer[3]),"%4hx", &addr);
|
||||||
|
sscanf((char *)&(buffer[9]),"%4lx", &ext_addr);
|
||||||
|
printf("\nExtended page address: 0x%8.8lX\n", ext_addr*0x8000 );
|
||||||
|
if (ext_addr) ext_addr--;
|
||||||
|
ext_addr *= 0x8000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(ihex_fp);
|
||||||
|
return(pages);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int hexfile_program(unsigned char *page_buffer, unsigned char *page_table)
|
||||||
|
{
|
||||||
|
int retry = 0;
|
||||||
|
int error = 0;
|
||||||
|
unsigned char buffer[256];
|
||||||
|
int length;
|
||||||
|
int i;
|
||||||
|
int pages;
|
||||||
|
|
||||||
|
unsigned long ext_addr=0;
|
||||||
|
unsigned short int addr=0;
|
||||||
|
|
||||||
|
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);
|
||||||
|
cdi_set_address(ext_addr);
|
||||||
|
|
||||||
|
printf("\r \r");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
cdi_flash_write(&page_buffer[ext_addr], 2048);
|
||||||
|
|
||||||
|
usleep(20000);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
36
tools/sensinode/nano_usb_programmer/ihex.h
Normal file
36
tools/sensinode/nano_usb_programmer/ihex.h
Normal 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*/
|
348
tools/sensinode/nano_usb_programmer/main.c
Normal file
348
tools/sensinode/nano_usb_programmer/main.c
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
To build use the following gcc statement
|
||||||
|
(assuming you have the d2xx library in the /usr/local/lib directory).
|
||||||
|
gcc -o bitmode main.c -L. -lftd2xx -Wl,-rpath /usr/local/lib
|
||||||
|
*/
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include "prog.h"
|
||||||
|
|
||||||
|
#define PRG_VERSION "1.3"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
USAGE,
|
||||||
|
VERSION,
|
||||||
|
SCAN,
|
||||||
|
WRITE,
|
||||||
|
READ,
|
||||||
|
WRITE_MAC,
|
||||||
|
READ_MAC,
|
||||||
|
ERASE
|
||||||
|
}mode_t;
|
||||||
|
|
||||||
|
typedef struct opts_t
|
||||||
|
{
|
||||||
|
int port;
|
||||||
|
mode_t mode;
|
||||||
|
uint8_t write_mac[8];
|
||||||
|
char *filename;
|
||||||
|
}opts_t;
|
||||||
|
|
||||||
|
opts_t opts;
|
||||||
|
|
||||||
|
void usage(char *prg_name)
|
||||||
|
{
|
||||||
|
printf("\nUsage: %s [-p port] [-h] [-v] [-f file] [-r] [-w] [-m] [-M <mac>]\n", prg_name);
|
||||||
|
printf("General options:\n");
|
||||||
|
printf(" -p/--port [port] Select FTDI device\n");
|
||||||
|
printf(" -f/--file [filename] File to read/write\n");
|
||||||
|
printf("Operating modes:\n");
|
||||||
|
printf(" -d/--devices Scan available devices\n");
|
||||||
|
printf(" -v/--version Print program version\n");
|
||||||
|
printf(" -r/--read Read program code into ihex file (see -f)\n");
|
||||||
|
printf(" -w/--write Program firmware from ihex file (see -f)\n");
|
||||||
|
printf(" -m/--read-mac Read device MAC address\n");
|
||||||
|
printf(" -M/--write-mac xx:xx:xx:xx:xx:xx:xx:xx Write device MAC address\n");
|
||||||
|
printf(" -e/--erase Erase flash (erases MAC address!)\n");
|
||||||
|
printf("Defaults:\n");
|
||||||
|
printf("mode = usage\n");
|
||||||
|
printf("port = undefined\n");
|
||||||
|
printf("file = stdout\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
DWORD dwBytesInQueue = 0;
|
||||||
|
FT_STATUS ftStatus;
|
||||||
|
FT_HANDLE ftHandle;
|
||||||
|
unsigned char ucMode = 0x00;
|
||||||
|
int i=0;
|
||||||
|
unsigned char wr[1] = { 0x30 };
|
||||||
|
unsigned char rd[1];
|
||||||
|
uint16_t chip_id;
|
||||||
|
|
||||||
|
if (opts_parse(argc, argv) < 0)
|
||||||
|
{
|
||||||
|
usage(argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch(opts.mode)
|
||||||
|
{
|
||||||
|
case VERSION:
|
||||||
|
printf("Sensinode Nano USB Programmer version %s\n", PRG_VERSION);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case USAGE:
|
||||||
|
usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case SCAN:
|
||||||
|
prog_scan();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case ERASE:
|
||||||
|
case READ:
|
||||||
|
case WRITE:
|
||||||
|
case READ_MAC:
|
||||||
|
case WRITE_MAC:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Opening programmer.\n");
|
||||||
|
ftHandle = prog_open(opts.port);
|
||||||
|
if (ftHandle == 0)
|
||||||
|
{
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cdi_start(&chip_id);
|
||||||
|
|
||||||
|
printf("Chip ID = %4.4hX.\n", chip_id);
|
||||||
|
|
||||||
|
if ((chip_id & 0xFF00) == 0x8500)
|
||||||
|
{
|
||||||
|
printf("CC2430 chip found.\n");
|
||||||
|
}
|
||||||
|
else if ((chip_id & 0xFF00) == 0x8900)
|
||||||
|
{
|
||||||
|
printf("CC2431 chip found.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Unknown chip found.\n");
|
||||||
|
opts.mode = USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(opts.mode)
|
||||||
|
{
|
||||||
|
case VERSION:
|
||||||
|
case USAGE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERASE:
|
||||||
|
printf("Erase.\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case READ:
|
||||||
|
printf("Read Flash.\n");
|
||||||
|
cdi_set_address(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WRITE:
|
||||||
|
{
|
||||||
|
int rval;
|
||||||
|
unsigned char page_table[64];
|
||||||
|
unsigned char page_buffer[128*1024];
|
||||||
|
|
||||||
|
printf("Write Flash.\n");
|
||||||
|
|
||||||
|
if((rval = hexfile_build_tables(opts.filename, page_buffer, page_table)) == -1)
|
||||||
|
{
|
||||||
|
printf("Error\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
else if(rval == 0)
|
||||||
|
{
|
||||||
|
printf(".ihex file OK but nothing to write...\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
hexfile_program(page_buffer, page_table);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case READ_MAC:
|
||||||
|
printf("Read MAC: ");
|
||||||
|
cdi_set_address(0x1FFF8);
|
||||||
|
{
|
||||||
|
uint8_t mac[8];
|
||||||
|
|
||||||
|
cdi_flash_read(mac, 8);
|
||||||
|
for (i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
if (i) printf(":");
|
||||||
|
printf("%2.2X", mac[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WRITE_MAC:
|
||||||
|
printf("Write MAC: ");
|
||||||
|
/* cdi_set_address(0x1F800);
|
||||||
|
{
|
||||||
|
uint8_t block[2048];
|
||||||
|
|
||||||
|
memset(block, 0xFF, 2048);
|
||||||
|
for (i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
block[2040+i] = opts.write_mac[i];
|
||||||
|
}
|
||||||
|
cdi_flash_write(block, 2048);
|
||||||
|
printf("\n");
|
||||||
|
}*/
|
||||||
|
cdi_flash_write_mac(opts.write_mac);
|
||||||
|
printf("\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("Duh\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("Closing programmer.\n");
|
||||||
|
prog_close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int option_index = 0;
|
||||||
|
|
||||||
|
int do_exit = 0;
|
||||||
|
|
||||||
|
#define OPTIONS_STRING "p:vdhf:rwmM:e"
|
||||||
|
/* long option list */
|
||||||
|
static struct option long_options[] =
|
||||||
|
{
|
||||||
|
{"port", 1, NULL, 'p'},
|
||||||
|
{"version", 0, NULL, 'v'},
|
||||||
|
{"devices", 0, NULL, 'd'},
|
||||||
|
{"help", 0, NULL, 'h'},
|
||||||
|
{"file", 1, NULL, 'f'},
|
||||||
|
{"read", 0, NULL, 'r'},
|
||||||
|
{"write", 0, NULL, 'w'},
|
||||||
|
{"read-mac", 0, NULL, 'm'},
|
||||||
|
{"write-mac", 1, NULL, 'M'},
|
||||||
|
{"erase", 0, NULL, 'e'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
int opts_parse(int count, char* param[])
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
int error=0;
|
||||||
|
|
||||||
|
opts.mode = USAGE;
|
||||||
|
opts.filename = 0;
|
||||||
|
while ((opt = getopt_long(count, param, OPTIONS_STRING,
|
||||||
|
long_options, &option_index)) != -1)
|
||||||
|
{
|
||||||
|
fflush(stdout);
|
||||||
|
switch(opt)
|
||||||
|
{
|
||||||
|
case 'p':
|
||||||
|
opts.port = 0;
|
||||||
|
if (sscanf(optarg, "%d", &(opts.port)) != 1)
|
||||||
|
{
|
||||||
|
if (sscanf(optarg, "/dev/ttyUSB%d", &(opts.port)) != 1)
|
||||||
|
{
|
||||||
|
printf("Invalid port.\n");
|
||||||
|
opts.mode = USAGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Port %d.\n", opts.port);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
opts.mode = VERSION;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
opts.mode = SCAN;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
opts.mode = USAGE;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 'e':
|
||||||
|
opts.mode = ERASE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
printf("Filename: %s\n", optarg);
|
||||||
|
opts.filename = malloc(strlen(optarg)+1);
|
||||||
|
strcpy(opts.filename, optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
opts.mode = READ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
opts.mode = WRITE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
opts.mode = READ_MAC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
opts.mode = WRITE_MAC;
|
||||||
|
if (sscanf(optarg, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
|
&opts.write_mac[0], &opts.write_mac[1],
|
||||||
|
&opts.write_mac[2], &opts.write_mac[3],
|
||||||
|
&opts.write_mac[4], &opts.write_mac[5],
|
||||||
|
&opts.write_mac[6], &opts.write_mac[7]) != 8)
|
||||||
|
{
|
||||||
|
printf("Invalid MAC.\n");
|
||||||
|
opts.mode = USAGE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("MAC to write: %2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX:%2.2hhX\n",
|
||||||
|
opts.write_mac[0], opts.write_mac[1],
|
||||||
|
opts.write_mac[2], opts.write_mac[3],
|
||||||
|
opts.write_mac[4], opts.write_mac[5],
|
||||||
|
opts.write_mac[6], opts.write_mac[7]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
printf("Duh\n");
|
||||||
|
error = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
372
tools/sensinode/nano_usb_programmer/prog.c
Normal file
372
tools/sensinode/nano_usb_programmer/prog.c
Normal file
|
@ -0,0 +1,372 @@
|
||||||
|
/*
|
||||||
|
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 <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include <ftd2xx.h>
|
||||||
|
|
||||||
|
FT_HANDLE curr_handle = 0;
|
||||||
|
uint8_t curr_mode = 0; /* 0 = in, 1=out */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function checks if the CBUS2 ise set to SLEEP and modifies it if necessary.
|
||||||
|
* The CBUS2 must be set to sleep in order the programming to succeed.
|
||||||
|
*/
|
||||||
|
int check_cbus2(FT_HANDLE fthandle)
|
||||||
|
{
|
||||||
|
FT_PROGRAM_DATA eeprom_data;
|
||||||
|
char manufacturer_buf[32];
|
||||||
|
char manufacturer_id[16];
|
||||||
|
char description_buf[64];
|
||||||
|
char serialnumber_buf[16];
|
||||||
|
eeprom_data.Signature1 = 0x00000000; // This is a given value from the FT232R programming guide
|
||||||
|
eeprom_data.Signature2 = 0xffffffff; // This is a given value from the FT232R programming guide
|
||||||
|
eeprom_data.Version = 0x00000002; // This is a given value from the FT232R programming guide
|
||||||
|
eeprom_data.Manufacturer = manufacturer_buf;
|
||||||
|
eeprom_data.ManufacturerId = manufacturer_id;
|
||||||
|
eeprom_data.Description = description_buf;
|
||||||
|
eeprom_data.SerialNumber = serialnumber_buf;
|
||||||
|
|
||||||
|
|
||||||
|
if(FT_EE_Read(fthandle, &eeprom_data) != FT_OK)
|
||||||
|
{
|
||||||
|
printf("FTDI EEPROM read failed.\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(eeprom_data.Cbus2 != 0x05)
|
||||||
|
{
|
||||||
|
printf("Need to re-program the CBUS2 to 0x05\n");
|
||||||
|
eeprom_data.Cbus2 = 0x05;
|
||||||
|
|
||||||
|
if(FT_EE_Program(fthandle, &eeprom_data) != FT_OK)
|
||||||
|
{
|
||||||
|
printf("FTDI EEPROM program error.\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("FTDI EEPROM program ok\n");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void prog_scan(void)
|
||||||
|
{
|
||||||
|
FT_STATUS ftStatus;
|
||||||
|
FT_DEVICE_LIST_INFO_NODE *info;
|
||||||
|
unsigned long n_devices = 0;
|
||||||
|
uint8_t out;
|
||||||
|
|
||||||
|
ftStatus = FT_CreateDeviceInfoList(&n_devices);
|
||||||
|
if (ftStatus == FT_OK)
|
||||||
|
{
|
||||||
|
FT_DEVICE_LIST_INFO_NODE devices[n_devices];
|
||||||
|
|
||||||
|
ftStatus = FT_GetDeviceInfoList(devices,&n_devices);
|
||||||
|
if (ftStatus == FT_OK)
|
||||||
|
{
|
||||||
|
for (out = 0; out < n_devices; out++)
|
||||||
|
{
|
||||||
|
printf("Dev %d:",n_devices - out -1);
|
||||||
|
printf(" Type=0x%x",devices[n_devices - out -1].Type);
|
||||||
|
printf(" SerialNumber=%s",devices[n_devices - out -1].SerialNumber);
|
||||||
|
printf(" Description=%s\n",devices[n_devices - out -1].Description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Failed to fetch device list.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Failed to fetch device list.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_HANDLE prog_open(int iport)
|
||||||
|
{
|
||||||
|
FT_HANDLE ftHandle;
|
||||||
|
FT_STATUS ftStatus;
|
||||||
|
FT_DEVICE_LIST_INFO_NODE *info;
|
||||||
|
unsigned long n_devices = 0;
|
||||||
|
uint8_t out;
|
||||||
|
|
||||||
|
if (curr_handle) return 0;
|
||||||
|
|
||||||
|
ftStatus = FT_CreateDeviceInfoList(&n_devices);
|
||||||
|
if (ftStatus == FT_OK)
|
||||||
|
{
|
||||||
|
FT_DEVICE_LIST_INFO_NODE devices[n_devices];
|
||||||
|
|
||||||
|
ftStatus = FT_GetDeviceInfoList(devices,&n_devices);
|
||||||
|
if (ftStatus == FT_OK)
|
||||||
|
{
|
||||||
|
iport = n_devices - iport - 1;
|
||||||
|
|
||||||
|
if (iport < 0)
|
||||||
|
{
|
||||||
|
printf("Invalid port id.\n");
|
||||||
|
for (out = 0; out < n_devices; out++)
|
||||||
|
{
|
||||||
|
printf("Dev %d:",n_devices - out -1);
|
||||||
|
printf(" Type=0x%x",devices[n_devices - out -1].Type);
|
||||||
|
printf(" SerialNumber=%s",devices[n_devices - out -1].SerialNumber);
|
||||||
|
printf(" Description=%s\n",devices[n_devices - out -1].Description);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ftStatus = FT_Open(iport, &ftHandle);
|
||||||
|
if(ftStatus != FT_OK) {
|
||||||
|
/*
|
||||||
|
This can fail if the ftdi_sio driver is loaded
|
||||||
|
use lsmod to check this and rmmod ftdi_sio to remove
|
||||||
|
also rmmod usbserial
|
||||||
|
*/
|
||||||
|
printf("FT_Open(%d) failed\n", iport);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(check_cbus2(ftHandle) < 0)
|
||||||
|
{
|
||||||
|
printf("Nano USB Programmer exiting...\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_ResetDevice(ftHandle);
|
||||||
|
|
||||||
|
FT_SetBaudRate(ftHandle, 115200);
|
||||||
|
|
||||||
|
FT_SetUSBParameters(ftHandle, 64, 0);
|
||||||
|
|
||||||
|
out = 0x04;
|
||||||
|
|
||||||
|
ftStatus = FT_SetBitMode(ftHandle, out, 0x20);
|
||||||
|
if (ftStatus == FT_OK)
|
||||||
|
{
|
||||||
|
ftStatus = FT_SetLatencyTimer(ftHandle, 2);
|
||||||
|
}
|
||||||
|
if (ftStatus == FT_OK)
|
||||||
|
{
|
||||||
|
DWORD bytes;
|
||||||
|
out = 0xE0;
|
||||||
|
ftStatus = FT_SetBitMode(ftHandle, out, 0x04);
|
||||||
|
out = 0x80;
|
||||||
|
FT_Write(ftHandle, &out, 1, &bytes); /*write reset high*/
|
||||||
|
FT_Read(ftHandle, &out, 1, &bytes); /*read out*/
|
||||||
|
curr_mode = 1;
|
||||||
|
}
|
||||||
|
if (ftStatus != FT_OK)
|
||||||
|
{
|
||||||
|
printf("Failed to set CBUS2/bit bang mode.\n");
|
||||||
|
|
||||||
|
FT_ResetDevice(ftHandle);
|
||||||
|
sleep(3);
|
||||||
|
FT_Close(ftHandle);
|
||||||
|
ftHandle = 0;
|
||||||
|
}
|
||||||
|
curr_handle = ftHandle;
|
||||||
|
return ftHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prog_close(void)
|
||||||
|
{
|
||||||
|
FT_STATUS ftStatus;
|
||||||
|
DWORD bytes;
|
||||||
|
|
||||||
|
if (curr_handle)
|
||||||
|
{
|
||||||
|
FT_HANDLE ftHandle = curr_handle;
|
||||||
|
uint8_t out = 0x00;
|
||||||
|
|
||||||
|
FT_Write(ftHandle, &out, 1, &bytes); /*write reset low*/
|
||||||
|
FT_Read(ftHandle, &out, 1, &bytes); /*read out*/
|
||||||
|
sleep(1);
|
||||||
|
out = 0x80;
|
||||||
|
FT_Write(ftHandle, &out, 1, &bytes); /*write reset high*/
|
||||||
|
FT_Read(ftHandle, &out, 1, &bytes); /*read out*/
|
||||||
|
sleep(1);
|
||||||
|
out = 0x00;
|
||||||
|
ftStatus = FT_SetBitMode(ftHandle, out, 0x04);
|
||||||
|
FT_ResetDevice(ftHandle);
|
||||||
|
FT_Close(ftHandle);
|
||||||
|
|
||||||
|
ftHandle = 0;
|
||||||
|
curr_handle = ftHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int prog_write(uint8_t byte)
|
||||||
|
{
|
||||||
|
FT_STATUS ftStatus;
|
||||||
|
uint8_t out[16];
|
||||||
|
uint8_t mask = 0x80;
|
||||||
|
int i;
|
||||||
|
DWORD bytes;
|
||||||
|
|
||||||
|
if (curr_mode == 0)
|
||||||
|
{
|
||||||
|
out[0] = 0xE0;
|
||||||
|
ftStatus = FT_SetBitMode(curr_handle, out[0], 0x04); /*Set DD as output*/
|
||||||
|
if (ftStatus != FT_OK)
|
||||||
|
{ printf("!WR");
|
||||||
|
fflush(stdout);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
curr_mode = 1;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while (mask)
|
||||||
|
{
|
||||||
|
out[i] = 0xC0; /*clock high, reset high*/
|
||||||
|
if (byte & mask) out[i] |= 0x20;
|
||||||
|
i++;
|
||||||
|
out[i] = 0x80; /*clock low, reset high*/
|
||||||
|
if (byte & mask) out[i] |= 0x20;
|
||||||
|
i++;
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
ftStatus = FT_Write(curr_handle, out, 16, &bytes); /*write clock high and data bit*/
|
||||||
|
if (ftStatus != FT_OK)
|
||||||
|
{
|
||||||
|
printf("!W");
|
||||||
|
fflush(stdout);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FT_Read(curr_handle, out, 16, &bytes) != FT_OK)
|
||||||
|
{
|
||||||
|
printf("!R");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prog_read(uint8_t *byte)
|
||||||
|
{
|
||||||
|
FT_STATUS ftStatus;
|
||||||
|
uint8_t rd;
|
||||||
|
uint8_t mask = 0x80;
|
||||||
|
DWORD bytes;
|
||||||
|
uint8_t out[17];
|
||||||
|
uint8_t i=0;
|
||||||
|
|
||||||
|
*byte = 0;
|
||||||
|
if (curr_mode == 1)
|
||||||
|
{
|
||||||
|
out[0] = 0xC0;
|
||||||
|
ftStatus = FT_SetBitMode(curr_handle, out[0], 0x04); /*Set DD as input*/
|
||||||
|
if (ftStatus != FT_OK)
|
||||||
|
{ printf("!RD");
|
||||||
|
fflush(stdout);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
curr_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (mask)
|
||||||
|
{
|
||||||
|
out[i] = 0xC0; /*clock high, reset high*/
|
||||||
|
if (*byte & mask) out[i] |= 0x20;
|
||||||
|
i++;
|
||||||
|
out[i] = 0x80; /*clock low, reset high*/
|
||||||
|
if (*byte & mask) out[i] |= 0x20;
|
||||||
|
i++;
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out[16] = out[15];
|
||||||
|
|
||||||
|
ftStatus = FT_Write(curr_handle, out, 17, &bytes); /*write clock high and data bit*/
|
||||||
|
|
||||||
|
if(FT_Read(curr_handle, out, 17, &bytes) != FT_OK)
|
||||||
|
{
|
||||||
|
printf("!R");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = 0x80;
|
||||||
|
i = 1;
|
||||||
|
while (mask)
|
||||||
|
{
|
||||||
|
if (out[i] & 0x20) *byte |= mask;
|
||||||
|
mask >>= 1;
|
||||||
|
i+=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int prog_start(void)
|
||||||
|
{
|
||||||
|
FT_STATUS ftStatus;
|
||||||
|
uint8_t wr;
|
||||||
|
uint8_t mask = 0x80;
|
||||||
|
DWORD bytes;
|
||||||
|
uint8_t out[16] = { 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80 };
|
||||||
|
|
||||||
|
printf("prog_start()\n");
|
||||||
|
|
||||||
|
if (curr_mode == 0)
|
||||||
|
{
|
||||||
|
wr = 0xE0;
|
||||||
|
|
||||||
|
ftStatus = FT_SetBitMode(curr_handle, wr, 0x04); /*Set DD as output*/
|
||||||
|
curr_mode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FT_Write(curr_handle, out, 7, &bytes) != FT_OK)
|
||||||
|
{
|
||||||
|
printf("!W\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(FT_Read(curr_handle, out, 7, &bytes) != FT_OK)
|
||||||
|
{
|
||||||
|
printf("!R\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
tools/sensinode/nano_usb_programmer/prog.h
Normal file
46
tools/sensinode/nano_usb_programmer/prog.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
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 _PROG_H
|
||||||
|
#define _PROG_H
|
||||||
|
|
||||||
|
#include "ftd2xx.h"
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
extern FT_HANDLE prog_open(int iport);
|
||||||
|
extern void prog_close(void);
|
||||||
|
|
||||||
|
extern int prog_write(uint8_t byte);
|
||||||
|
extern int prog_read(uint8_t *byte);
|
||||||
|
|
||||||
|
extern int prog_start(void);
|
||||||
|
|
||||||
|
extern int check_cbus2(FT_HANDLE fthandle);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue