Commit 5ca6e20c authored by Benoit Rat's avatar Benoit Rat

usb-loader: adding NAND, DDR, multiple files support & clean the code

parent ffd8d8de
#!/bin/sh
# A script to compile the usb loader, possibly changing the mac address
showhelp()
{
echo "Usage: $0 [options] MAC [DEV]\n"
echo "MAC:\t MAC address in hexadecimal seperated by ':' (i.e, AB:CD:EF:01:23:45)"
echo "DEV:\t The usb device (by default it is /dev/ttyACM0)"
echo "Options: "
echo "\t-h|--help\t\t Show this help message"
echo "\t-m|--memmode\t\t can be: default, df (dataflash), nf (nandflash), test."
echo "\t-e \t\t\t Completely erase the memory (Can erase your configuration)"
echo "\t--build\t\t\t Use file that you have build in the WRS_OUTPUT_DIR"
echo "\t--test\t\t\t Use file for testing the switch (not available)"
echo "\t--silent\t\t Don't ask MAC or S/N and use default 02:0B:AD:C0:FF:EE"
echo ""
exit 0
}
checkExit()
{
err=0;
if [ $1 ]; then
if [ -f $1 ]; then
return 0;
else
echo "Can't find $1" >& 2;
fi
else
echo "varname not set"
fi
exit 1
}
modifyMAC()
{
origin=$1
new=$2
cp $origin $new
# check & change mac address
X="[0-9a-fA-F][0-9a-fA-F]"
while true; do
if echo $MAC | grep "^${X}:${X}:${X}:${X}:${X}:${X}\$" > /dev/null; then
sed -i "s/02:0B:AD:C0:FF:EE/$MAC/" $new
echo "MAC is now: $MAC"
return 0
else
if [ "x$MAC" != "x" ]; then
echo "$0: Invalid MAC address \"$MAC\"" >&2;
fi
if [ $silent ]; then
return 1;
fi
read -p "Enter MAC (XX:XX:XX:XX:XX:XX): " MAC
fi
done
}
# Sanity checks
if [ -d ./usb-loader ]; then true; else
......@@ -8,62 +67,91 @@ if [ -d ./usb-loader ]; then true; else
exit 1
fi
# build flasher itself
if CC=cc make -s -C usb-loader; then true; else
echo "$0: Error compiling usb-loader" >&2; exit 1;
fi
# Check if atmel sam-ba is find by lusb
lsusb | grep "at91sam SAMBA" &> /dev/null
lsusb | grep "at91sam SAMBA" > /dev/null
if [ $? -gt "0" ]; then
echo "Did not find the sam-ba bootloader in lsub....\nPlease check that the Dataflash is short-circuited!"
echo "Did not find the sam-ba monitor in lsusb....\nPlease check that the Dataflash is short-circuited!"
exit 1;
fi
err=0;
if [ -f ./binaries/at91bootstrap.bin ]; then true; else err=1; fi
if [ -f ./binaries/barebox.bin ]; then true; else err=1; fi
if [ $err -eq 1 ]; then
echo "$0: Can't find either ./binaries/at91bootstrap.bin" >& 2
echo "$0: or ./binaries/barebox.bin" >& 2
exit 1
fi
# parse command line
MAC=""
DEV=""
FLAGS=""
at91bs="./binaries/at91bootstrap.bin"
barebox="./binaries/barebox.bin"
kernel="${WRS_OUTPUT_DIR}/images/zImage"
rootfs="${WRS_OUTPUT_DIR}/images/wrs-image.jffs2.img"
while [ $# -ge 1 ]; do
case $1 in
--help|-h) echo "Usage :\t $0 [options] MAC \nOptions:\t same as mch_flasher\n\n";
echo ">\$ usb-loader/mch_flasher -h"; usb-loader/mch_flasher -h;
exit 0;;
-b|--build)
at91bs=${WRS_OUTPUT_DIR}/images/at91bootstrap.bin;
barebox=${WRS_OUTPUT_DIR}/images/barebox.bin
kernel=${WRS_OUTPUT_DIR}/images/zImage
rootfs=${WRS_OUTPUT_DIR}/images/wrs-image.jffs2.img
shift;;
-h|--help) showhelp; shift;;
-m|--memmode) memmode="$2"; shift; shift;;
--silent) silent=1; shift;;
/* ) DEV="-s $1"; shift ;;
*:* ) MAC="$1"; shift ;;
-*) FLAGS="${FLAGS} $1"; shift;;
* ) echo "$0: Invalid argument \"$1\"" >&2; exit 1;;
esac
done
## Selecting the running memmode
if [ "x$memmode" = "xdf" ]; then
df=1
elif [ "x$memmode" = "xnf" ]; then
nf=1
elif [ "x$memmode" = "xtest" ]; then
test=1
else
df=1
nf=1
fi
# build flasher itself
if CC=cc make -s -C usb-loader; then true; else
echo "$0: Error compiling usb-loader" >&2; exit 1;
## Flashing DataFlash
if [ $df ]; then
checkExit $at91bs
checkExit $barebox
Tbarebox=$(mktemp /tmp/barebox.XXXXXX)
modifyMAC ${barebox} ${Tbarebox}
./usb-loader/mch_flasher -m df $FLAGS $DEV ${at91bs} 0 ${Tbarebox} 33792
fi
# check & change mac address
if [ "x$MAC" != "x" ]; then
X="[0-9a-fA-F][0-9a-fA-F]"
if echo $MAC | grep "^${X}:${X}:${X}:${X}:${X}:${X}\$" > /dev/null; then
sed -i "s/02:0B:AD:C0:FF:EE/$MAC/" $T
echo "MAC is now: $MAC"
else
echo "$0: Invalid MAC address \"$MAC\"" >&2; exit 1;
fi
## Flashing NANDFlash
if [ $nf ]; then
checkExit $kernel
checkExit $rootfs
./usb-loader/mch_flasher -m nand $FLAGS $DEV ${kernel} 0x00100000 ${rootfs} 0x04000000
fi
# cat binaries to temp file. Increase size of at91boot (0x8400)
T=$(mktemp /tmp/wrs-flash.XXXXXX)
cp ./binaries/at91bootstrap.bin $T
dd if=./binaries/barebox.bin of=$T conv=notrunc bs=1 seek=33792 2> /dev/null
## Loading in DDR
if [ $test ]; then
checkExit $barebox
checkExit $kernel
checkExit $rootfs
Tbarebox=$(mktemp /tmp/barebox.XXXXXX)
modifyMAC ${barebox} ${Tbarebox}
./usb-loader/mch_flasher -m ddr $FLAGS $DEV ${Tbarebox} 0x0 ${kernel} 0x1000000 ${rootfs} 0x2000000
fi
# flash it (msc...)
(cd usb-loader && ./mch_flasher $FLAGS $DEV $T )
#rm -f $T
......@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <getopt.h>
#include <libgen.h>
......@@ -32,9 +33,12 @@
#define MBOX_DATAFLASH_BUFFER_ADDR 0x10
#define MBOX_PROG_BUF_SIZE 0x
#define MBOX_DATAFLASH_BUF_ADDR 0xc
#define MBOX_DATAFLASH_BUF_SIZE 0x10
#define MBOX_DATAFLASH_MEM_OFFSET 0x14
#define MBOX_MEM_BUF_ADDR 0xc
#define MBOX_MEM_BUF_SIZE 0x10
#define MBOX_MEM_BUF_OFFSET 0x14
#define MBOX_MEM_ERASE_TYPE 0xc
#define INTERNAL_SRAM_BUF 0x300000
#define SDRAM_START 0x70000000
......@@ -42,6 +46,21 @@
#define PORT_SPEED 115200
#define MEMTYPE_DDR 0
#define MEMTYPE_DF 1
#define MEMTYPE_NAND 2
const char* memName[3] = { "DDR", "DataFlash", "NandFlash" };
typedef struct {
char *fname;
uint32_t offset;
} sndfile;
sndfile filearray[3];
//External variable from version.c
extern const char build_time[];
extern const char git_user[];
......@@ -54,51 +73,57 @@ int applet_silent_mode = 1;
unsigned int buffer_size = 0x3000;
unsigned int buffer_addr ;
int crc16(int value, int crcin)
{
int k = (((crcin >> 8) ^ value) & 255) << 8;
int crc = 0;
int bits = 8;
do
{
if (( crc ^ k ) & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
k <<= 1;
}
while (--bits);
return ((crcin << 8) ^ crc);
int k = (((crcin >> 8) ^ value) & 255) << 8;
int crc = 0;
int bits = 8;
do
{
if (( crc ^ k ) & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
k <<= 1;
}
while (--bits);
return ((crcin << 8) ^ crc);
}
static int write_xmodem(int index, char *p)
{
unsigned char data[133],c;
unsigned short crc=0;
int i;
data[0]=1;
data[1]=index;
data[2]=0xff-index;
memcpy(data+3,p,128);
for(i=3;i<131;i++){
crc=crc16(data[i],crc);
}
data[131] = (crc>>8)&0xff;
data[132] = (crc)&0xff;
printf("XMDump: ");
for(i=0;i<133;i++) printf("%02x ", data[i]);
printf("\n\n");
serial_write(data,133);
return serial_read_byte();
unsigned char data[133],c;
unsigned short crc=0;
int i;
data[0]=1;
data[1]=index;
data[2]=0xff-index;
memcpy(data+3,p,128);
for(i=3;i<131;i++){
crc=crc16(data[i],crc);
}
data[131] = (crc>>8)&0xff;
data[132] = (crc)&0xff;
printf("XMDump: ");
for(i=0;i<133;i++) printf("%02x ", data[i]);
printf("\n\n");
serial_write(data,133);
return serial_read_byte();
}
void die(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "Error: ");
vfprintf(stderr, fmt, ap);
......@@ -118,19 +143,19 @@ void samba_write (uint32_t addr, uint32_t data, int size, int timeout)
snprintf(tmpbuf, 1024, "%c%08x,%08x#", size==1?'O':(size==2?'H':'W'), addr, data);
serial_write(tmpbuf, strlen(tmpbuf));
tstart = sys_get_clock_usec();
tstart = sys_get_clock_usec();
while(1)
{
if(serial_data_avail())
{
if(serial_read_byte() =='>') break;
}
if(sys_get_clock_usec() - tstart > timeout) die("tx timeout");
if(serial_data_avail())
{
if(serial_read_byte() =='>') break;
}
if(sys_get_clock_usec() - tstart > timeout) die("tx timeout");
}
}
......@@ -141,98 +166,105 @@ uint32_t samba_read (uint32_t addr, int size, int timeout)
int i,xpos=-1;
uint32_t rval;
uint32_t tstart;
serial_purge();
snprintf(tmpbuf, 1024, "%c%08x,#", size==1?'o':(size==2?'h':'w'), addr);
// printf("--> cmd: '%s'\n", tmpbuf);
// printf("--> cmd: '%s'\n", tmpbuf);
serial_write(tmpbuf, strlen(tmpbuf));
tstart = sys_get_clock_usec();
tstart = sys_get_clock_usec();
for(i=0;i<1024 && c!='>';)
{
if(serial_data_avail())
{
tmpbuf[i]=c=serial_read_byte();
// fprintf(stderr,"%c", c);
if(c=='x') xpos=i;
i++;
}
if(sys_get_clock_usec()-tstart>timeout) die("rx timeout");
if(serial_data_avail())
{
tmpbuf[i]=c=serial_read_byte();
// fprintf(stderr,"%c", c);
if(c=='x') xpos=i;
i++;
}
if(sys_get_clock_usec()-tstart>timeout) die("rx timeout");
}
if(xpos<0) die("invalid response from samba");
sscanf(tmpbuf, "%x", &rval);
// fprintf(stderr,"samba_read: %x\n", rval);
// fprintf(stderr,"samba_read: %x\n", rval);
return rval;
}
/**
* filename: name of the file in the host
* address: place to send to file on the device
* offset: internal offset, can be use with size
* size: can be 0
*/
static int samba_send_file(const char *filename, uint32_t address, uint32_t offset, uint32_t size, int quiet)
{
FILE *f;
unsigned char *buf;
uint32_t file_size, sent;
int idx = 0;
int boffset = 0;
char tmp[4097];
uint32_t tstart;
// printf("SendFile: %s\n", filename);
f = fopen(filename, "rb");
if(!f) die("file open error: '%s'",filename);
if(!size)
{
fseek(f, 0, SEEK_END);
size = ftell(f);
offset = 0;
rewind(f);
} else
fseek(f, offset, SEEK_SET);
buf = malloc(size+1);
if(!buf) die("malloc failed");
fread(buf, 1, size, f);
fclose(f);
// printf("Send: %s\n", filename);
while(size > 0)
{
int tosend = size > 1024 ? 1024 : size;
// printf("Sending %d bytes\n", tosend);
snprintf(tmp, 128, "S%08x,%x#", address, tosend);
serial_write(tmp, strlen(tmp));
memcpy(tmp, buf + boffset, tosend);
tmp[tosend]='\n';
serial_write(tmp, tosend+1);
size -= tosend;
boffset +=tosend;
address += tosend;
while(1)
{
if(serial_data_avail())
if(serial_read_byte() == '>')
break;
}
}
free(buf);
return boffset;
FILE *f;
unsigned char *buf;
uint32_t file_size, sent;
int idx = 0;
int boffset = 0;
char tmp[4097];
uint32_t tstart;
// printf("SendFile: %s\n", filename);
f = fopen(filename, "rb");
if(!f) die("file open error: '%s'",filename);
if(!size)
{
fseek(f, 0, SEEK_END);
size = ftell(f);
offset = 0;
rewind(f);
} else
fseek(f, offset, SEEK_SET);
if(!quiet) printf("size 0x%x (%dKb)\n",size,size/1024);
buf = malloc(size+1);
if(!buf) die("malloc failed");
fread(buf, 1, size, f);
fclose(f);
// printf("Send: %s\n", filename);
while(size > 0)
{
int tosend = size > 1024 ? 1024 : size;
// printf("Sending %d bytes\n", tosend);
snprintf(tmp, 128, "S%08x,%x#", address, tosend);
serial_write(tmp, strlen(tmp));
memcpy(tmp, buf + boffset, tosend);
tmp[tosend]='\n';
serial_write(tmp, tosend+1);
size -= tosend;
boffset +=tosend;
address += tosend;
while(1)
{
if(serial_data_avail())
if(serial_read_byte() == '>')
break;
}
}
free(buf);
return boffset;
}
......@@ -241,7 +273,7 @@ static void samba_load_applet(char *applet_name, uint32_t address)
char namebuf[1024];
printf("loading applet %s at 0x%08x\n", applet_name, address);
snprintf(namebuf, 1024, "%s/samba_applets/%s.bin", program_path, applet_name);
samba_send_file(namebuf, address, 0, 0, 1);
}
......@@ -249,7 +281,7 @@ static void samba_load_applet(char *applet_name, uint32_t address)
static void mbox_write(uint32_t base, uint32_t offset, uint32_t value)
{
samba_write(base+offset, value, 4, SERIAL_TIMEOUT);
samba_write(base+offset, value, 4, SERIAL_TIMEOUT);
}
void samba_run(uint32_t addr, int timeout)
......@@ -261,37 +293,39 @@ void samba_run(uint32_t addr, int timeout)
snprintf(tmpbuf, 1024, "G%08x#", addr);
serial_write(tmpbuf, strlen(tmpbuf));
t1 = tstart = sys_get_clock_usec();
while((timeout && (sys_get_clock_usec()- tstart < timeout)) || !timeout)
{
if(serial_data_avail()) {
c = serial_read_byte();
if(c == '>') break;
if(!applet_silent_mode )fprintf(stderr,"%c", c);
t1 = sys_get_clock_usec();
} else if(sys_get_clock_usec() - t1 > 10000)
{
// fprintf(stderr,"Phase1\n");
// serial_write_byte('\n');
serial_write_byte(0x0a);
serial_write_byte(0x0d);
serial_write_byte('T');
serial_write_byte('#');
serial_write_byte(0x0a);
serial_write_byte(0x0d);
usleep(10000);
while(serial_data_avail())
if(serial_data_avail()) {
c = serial_read_byte();
if(c == '>') break;
if(!applet_silent_mode )fprintf(stderr,"%c", c);
t1 = sys_get_clock_usec();
}
else if(sys_get_clock_usec() - t1 > 10000)
{
c=serial_read_byte();
if( c == '>')
return;
else if(!applet_silent_mode)
fprintf(stderr,"%c", c);
// fprintf(stderr,"Phase1\n");
// serial_write_byte('\n');
serial_write_byte(0x0a);
serial_write_byte(0x0d);
serial_write_byte('T');
serial_write_byte('#');
serial_write_byte(0x0a);
serial_write_byte(0x0d);
usleep(10000);
while(serial_data_avail())
{
c=serial_read_byte();
if( c == '>')
return;
else if(!applet_silent_mode)
fprintf(stderr,"%c", c);
}
}
}
usleep(1000);
//TODO: Improve data available for DDR load
}
}
......@@ -299,19 +333,20 @@ void samba_run(uint32_t addr, int timeout)
int samba_connect(int board_rev)
{
char handshake[] = {0x80, 0x80, 0x23}, cmd[128], buffer[16384];
int tstart,i,length,npages;
char handshake[] = {0x80, 0x80, 0x23}, cmd[128], buffer[16384];
int tstart,i,length,npages;
int c;
serial_write(handshake,3);
sys_delay(100);
uint32_t id = samba_read(0xffffee40, 4, SERIAL_TIMEOUT);
printf("CPU ID: 0x%08x\n",id);
if(board_rev == BOARD_REV_V2 && id != ID_SAM9263) die ("Not a 9263 CPU");
if(board_rev == BOARD_REV_V3 && id != ID_SAM9G45) die ("Not a 9G45 CPU");
return 0;
}
int ddr_init(int board_rev)
......@@ -320,42 +355,57 @@ int ddr_init(int board_rev)
samba_load_applet("isp-extram-at91sam9263", INTERNAL_SRAM_BUF);
else if(board_rev == BOARD_REV_V3)
samba_load_applet("isp-extram-at91sam9g45", INTERNAL_SRAM_BUF);
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMMAND, APPLET_CMD_INIT);
mbox_write(INTERNAL_SRAM_BUF, MBOX_TRACELEVEL, 0);
mbox_write(INTERNAL_SRAM_BUF, MBOX_EXTRAM_RAMTYPE, 1);
mbox_write(INTERNAL_SRAM_BUF, MBOX_EXTRAM_VDDMEM, 0);
mbox_write(INTERNAL_SRAM_BUF, MBOX_EXTRAM_BUSWIDTH, 16);
mbox_write(INTERNAL_SRAM_BUF, MBOX_EXTRAM_DDRMODEL, 0);
samba_run(INTERNAL_SRAM_BUF, 100000000);
if((samba_read(INTERNAL_SRAM_BUF + MBOX_COMMAND, 4, 10000000)) != ~APPLET_CMD_INIT) die("invalid response from applet init");
if((samba_read(INTERNAL_SRAM_BUF + MBOX_STATUS, 4, 10000000)) != APPLET_SUCCESS) die("invalid response from applet status");
return 0;
}
int ddr_check(int board_rev)
int ddr_load(int nFile, const sndfile* pFileArray)
{
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMMAND, APPLET_CMD_WRITE);
samba_run(INTERNAL_SRAM_BUF, 0);
if((samba_read(INTERNAL_SRAM_BUF + MBOX_COMMAND, 4, 10000000)) != ~APPLET_CMD_WRITE) die("invalid response from applet write");
if((samba_read(INTERNAL_SRAM_BUF + MBOX_STATUS, 4, 10000000)) != APPLET_SUCCESS) die("invalid response from applet status");
int i;
uint32_t len=0;
fprintf(stderr,"Loading DDR...\n");
for(i=0;i<nFile; i++)
{
printf("\t @ 0x%08x : %s ; ",SDRAM_START+ pFileArray[i].offset, pFileArray[i].fname);
len += samba_send_file(pFileArray[i].fname, SDRAM_START+pFileArray[i].offset,0, 0, 0);
}
mem_write(MEMTYPE_DDR,0,SDRAM_START,len);
fprintf(stderr,"Loading DDR...!!!\n");
return 0;
}
int dataflash_init(int board_rev)
int memflash_init(int type, int board_rev)
{
fprintf(stderr,"Initializing %s...\n",memName[type]);
// samba_write(0xfffff410, 0x04000000, 4, 100000);
// samba_write(0xfffff430, 0x04000000, 4, 100000);
//Load the correct applet
if(board_rev == BOARD_REV_V2)
samba_load_applet("isp-dataflash-at91sam9263", INTERNAL_SRAM_BUF);
{
if(type==MEMTYPE_NAND) samba_load_applet("isp-nandflash-at91sam9263", INTERNAL_SRAM_BUF);
else if(type==MEMTYPE_DF) samba_load_applet("isp-dataflash-at91sam9263", INTERNAL_SRAM_BUF);
}
else if(board_rev == BOARD_REV_V3)
samba_load_applet("isp-dataflash-at91sam9g45", INTERNAL_SRAM_BUF);
// samba_load_applet("isp-dataflash-at91sam9263", SDRAM_START);
{
if(type==MEMTYPE_NAND) samba_load_applet("isp-nandflash-at91sam9g45", INTERNAL_SRAM_BUF);
else if(type==MEMTYPE_DF) samba_load_applet("isp-dataflash-at91sam9g45", INTERNAL_SRAM_BUF);
}
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMMAND, APPLET_CMD_INIT);
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMTYPE, 1);
......@@ -365,55 +415,110 @@ int dataflash_init(int board_rev)
samba_run(INTERNAL_SRAM_BUF, 0);
if(samba_read(INTERNAL_SRAM_BUF + MBOX_COMMAND, 4, 10000000) != ~APPLET_CMD_INIT) die("invalid response from applet");
if(samba_read(INTERNAL_SRAM_BUF + MBOX_STATUS, 4, 10000000) != APPLET_SUCCESS) die(" DataFlash initialization failure (no chip deteted?)");
if(samba_read(INTERNAL_SRAM_BUF + MBOX_STATUS, 4, 10000000) != APPLET_SUCCESS) die("Initialization failure (no chip deteted?)");
buffer_addr = samba_read(INTERNAL_SRAM_BUF + MBOX_DATAFLASH_BUFFER_ADDR, 4, 10000000);
// fprintf(stderr,"DF Initialized");
fprintf(stderr,"Initializing %s > Done! \n\n",memName[type]);
return 0;
}
int mem_program(int type, int nFile, const sndfile* pFileArray)
{
int i;
uint32_t len=0;
if(type==MEMTYPE_DDR) return ddr_load(nFile,pFileArray);
else
{
fprintf(stderr,"Programming %s...\n",memName[type]);
for(i=0;i<nFile; i++)
{
printf("\t @ 0x%08x : %s ; ",SDRAM_START+ pFileArray[i].offset, pFileArray[i].fname);
len = samba_send_file(pFileArray[i].fname, SDRAM_START,0,0,0);
mem_write(type,pFileArray[i].offset, SDRAM_START, len);
}
fprintf(stderr,"Programming %s Done!!!\n",memName[type]);
return 0;
}
}
void mem_check(int type)
{
fprintf(stderr,"Checking %s...\n\n",memName[type]);
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMMAND, APPLET_CMD_LIST_BAD_BLOCKS);
samba_run(INTERNAL_SRAM_BUF, 0);
if((samba_read(INTERNAL_SRAM_BUF + MBOX_COMMAND, 4, 10000000)) != ~APPLET_CMD_LIST_BAD_BLOCKS) die("invalid response from applet write");
if((samba_read(INTERNAL_SRAM_BUF + MBOX_STATUS, 4, 10000000)) != APPLET_SUCCESS) die("invalid response from applet status");
}
void mem_full_erase(int type)
{
fprintf(stderr,"Erasing %s...",memName[type]);
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMMAND, APPLET_CMD_FULL_ERASE);
samba_run(INTERNAL_SRAM_BUF, 0);
fprintf(stderr,"\rErasing %s > DONE\n\n",memName[type]);
}
int dataflash_write(uint32_t offset, uint32_t buf_addr, uint32_t size)
int mem_write(int type, uint32_t offset, uint32_t buf_addr, uint32_t size)
{
uint32_t timeout;
applet_silent_mode=1;
fprintf(stderr, "%s: Writing %d bytes at offset 0x%x buffer %x....", memName[type], size, offset, buf_addr);
mbox_write(INTERNAL_SRAM_BUF, MBOX_MEM_BUF_ADDR, buf_addr);
fprintf(stderr,"A");
mbox_write(INTERNAL_SRAM_BUF, MBOX_MEM_BUF_ADDR, buf_addr);
fprintf(stderr,"B");
mbox_write(INTERNAL_SRAM_BUF, MBOX_MEM_BUF_SIZE, size);
fprintf(stderr,"C");
mbox_write(INTERNAL_SRAM_BUF, MBOX_MEM_BUF_OFFSET, offset);
fprintf(stderr,"D");
applet_silent_mode=0;
fprintf(stderr, "Dataflash: Writing %d bytes at offset 0x%x buffer %x....", size, offset, buf_addr);
mbox_write(INTERNAL_SRAM_BUF, MBOX_DATAFLASH_BUF_ADDR, buf_addr);
fprintf(stderr,"A");
mbox_write(INTERNAL_SRAM_BUF, MBOX_DATAFLASH_BUF_ADDR, buf_addr);
fprintf(stderr,"B");
mbox_write(INTERNAL_SRAM_BUF, MBOX_DATAFLASH_BUF_SIZE, size);
fprintf(stderr,"C");
mbox_write(INTERNAL_SRAM_BUF, MBOX_DATAFLASH_MEM_OFFSET, offset);
fprintf(stderr,"D");
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMMAND, APPLET_CMD_WRITE);
fprintf(stderr,"E");
samba_run(INTERNAL_SRAM_BUF, 0);
fprintf(stderr,"F");
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMMAND, APPLET_CMD_WRITE);
fprintf(stderr,"E");
if(samba_read(INTERNAL_SRAM_BUF + MBOX_COMMAND, 4, 10000000) != ~APPLET_CMD_WRITE) die(" invalid response from applet");
if(samba_read(INTERNAL_SRAM_BUF + MBOX_STATUS, 4, 10000000) != APPLET_SUCCESS) die(" write failure");
if(type==MEMTYPE_DDR) timeout=10;
else timeout=0;
samba_run(INTERNAL_SRAM_BUF, timeout);
fprintf(stderr,"F");
printf("done. \n\n");
if(samba_read(INTERNAL_SRAM_BUF + MBOX_COMMAND, 4, 10000000) != ~APPLET_CMD_WRITE) die(" invalid response from applet");
if(samba_read(INTERNAL_SRAM_BUF + MBOX_STATUS, 4, 10000000) != APPLET_SUCCESS) die(" write failure");
printf(" OK\n");
}
int dataflash_erase_all()
void nand_scrub()
{
fprintf(stderr,"Scrubing NAND...");
mbox_write(INTERNAL_SRAM_BUF, MBOX_COMMAND, APPLET_CMD_FULL_ERASE);
mbox_write(INTERNAL_SRAM_BUF, MBOX_MEM_ERASE_TYPE,0x0000EA11);
samba_run(INTERNAL_SRAM_BUF, 0);
fprintf(stderr,"Done\n\n");
}
int dataflash_program(const char *filename)
uint32_t getOffset(const char *str)
{
uint32_t len = samba_send_file(filename, SDRAM_START, 0, 0, 0);
dataflash_write(0, SDRAM_START, len);
uint32_t ret=0;
if (str == NULL || *str == '\0') return ret;
if(str[0]=='0' && (str[1]=='X' || str[1]=='x'))
{
str+=2;
sscanf(str, "%x", &ret);
}
else sscanf(str, "%d", &ret);
return ret;
}
......@@ -421,13 +526,15 @@ void show_help(const char* serial_port)
{
printf("WhiteRabbit MCH DataFlash programmer (c) T.W. 2010\n");
printf("Compiled by %s (%s)\ngit rev:%s\n\n",git_user,build_time,git_revision);
printf("Usage: %s [options] <dataflash image>\n", program_name);
printf("Usage: %s [options] [<FILE1> <OFFSET1> <FILE2> <OFFSET2> <FILE3> <OFFSET3>]\n", program_name);
printf("if FILEx set it will write the FILEx at the given OFFSETx (by default 0x0), "
"otherwise you can use this binary to erase, check or scrub a memory\n");
printf("Options:\n");
printf("\t-a \t\t perform all actions (same as -wec). Default option.\n");
printf("\t-w \t\t write the dataflash\n");
printf("\t-e \t\t erase the dataflash\n");
printf("\t-c \t\t check the DDR\n");
printf("\t-s SERIAL_PORT\t By default it is: -s %s\n",serial_port);
printf("\t-m \t Select the memory type: ddr, nf, df\n");
printf("\t-e \t\t erase the memory\n");
printf("\t-c \t\t check the memory (not available for df)\n");
printf("\t-s \t\t scrub the memory (only available for nf)\n");
printf("\t-p SERIAL_PORT\t By default it is: -p %s\n",serial_port);
printf("\t-h \t\t Show this little help\n");
printf("\n");
}
......@@ -436,84 +543,86 @@ main(int argc, char *argv[])
{
int board_rev = BOARD_REV_V3;
char *serial_port = "/dev/ttyACM0";
char c;
int erase=0;
int check=0;
int write=0;
char * mode_str ="df";
char opt;
int erase=0, check=0, scrub=0;
int type=-1;
unsigned int offset=0;
int noopts=1;
int nFile=0;
program_name = basename(argv[0]);
program_path = dirname(argv[0]);
program_path = dirname(argv[0]);
if(argc==1)
{
show_help(serial_port);
return 1;
}
//Parse options
while (--argc > 0 && (*++argv)[0] == '-') {
noopts=0;
while (c = *++argv[0]) {
switch (c) {
case 'a': erase = 1; check=1; write=1; break;
case 'e': erase=1; break;
case 'c': check=1; break;
case 'w': write=1; break;
case 's': serial_port = argv[1]; break;
case 'h': show_help(serial_port);
return 0;
break;
default:
printf("find: illegal option %c\n", c);
argc = 0;
break;
}
while ((opt = getopt (argc, argv, "m:p:ecsh")) != -1)
switch (opt)
{
case 'm': mode_str = optarg; break;
case 'p': serial_port = optarg; break;
case 'e': erase = 1; break;
case 'c': check = 1; break;
case 's': scrub = 1; break;
case 'h':
case '?':
show_help(serial_port);
return 0;
default:
printf("find: illegal option %c\n", opt);
break;
}
}
--argv;
++argc;
//Default value are all
if(noopts) { erase = 1; check=1; write=1; }
printf("prog=%s, n=%d, serial=%s, (e=%d,c=%d,w=%d)\n", argv[1],argc,serial_port, erase,check,write);
if(write && argc < 2)
//Obtain the various filename & offset (3 MAX)
for(nFile=0; optind < argc; nFile++)
{
show_help(serial_port);
return 0;
filearray[nFile].fname=argv[optind++];
filearray[nFile].offset=getOffset(argv[optind++]);
}
//Print line to know the version of software for testing purpose
fprintf(stderr,"\nCompiled by %s (%s)\ngit rev:%s\n\n",git_user,build_time,git_revision);
printf("n=%d, mode=%s, nFile=%d, serial=%s, (e=%d,c=%d,s=%d)\n", argc, mode_str, nFile, serial_port, erase,check,scrub);
serial_open(serial_port, PORT_SPEED);
fprintf(stderr,"Initializing SAM-BA: ");
samba_connect(board_rev);
fprintf(stderr,"Initializing DDR...\n\n");
//Init the DDR for every action (used as buffer)
fprintf(stderr,"\nInitializing DDR...\n");
ddr_init(board_rev);
if(check)
{
fprintf(stderr,"Checking DDR...\n\n");
ddr_check(board_rev);
}
fprintf(stderr,"Initializing DataFlash...\n\n");
dataflash_init(board_rev);
fprintf(stderr,"Initializing DDR > Done\n\n");
if(erase)
{
fprintf(stderr,"Erasing DataFlash...\n\n");
dataflash_erase_all();
}
if(write)
//Obtain the memory type mode
if(strcmp(mode_str,"nand")==0 || strcmp(mode_str,"nf")==0) type=MEMTYPE_NAND;
else if(strcmp(mode_str,"dataflash")==0 || strcmp(mode_str,"df")==0) type=MEMTYPE_DF;
else if(strcmp(mode_str,"ddr")==0 || strcmp(mode_str,"ram")==0) type=MEMTYPE_DDR;
else
{
fprintf(stderr,"Programming DataFlash...\n");
dataflash_program(argv[1]);
fprintf(stderr,"Bad memory type %s...\n\n",mode_str);
show_help(serial_port);
return 0;
}
printf("Programming done!\n");
//Init the memory (except DDR which is already init)
if(type!=MEMTYPE_DDR) memflash_init(type, board_rev);
//Run the action
if(erase) mem_full_erase(type);
if(check) mem_check(type);
if(scrub && type==MEMTYPE_NAND) nand_scrub();
if(nFile>0) mem_program(type,nFile,(const sndfile*)&filearray);
serial_close();
return 0;
printf("Closing...\n");
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment