add initial version of flasher tool
This commit is contained in:
parent
79c3f63c78
commit
a59a982503
|
@ -0,0 +1,87 @@
|
|||
# binary file name
|
||||
TARGET=sdr-samba
|
||||
|
||||
# CROSS_COMPILE=
|
||||
QUIET=@
|
||||
|
||||
# N = build release version
|
||||
# y = optimize but include debugger info
|
||||
# Y = build debug version
|
||||
DEBUG=N
|
||||
|
||||
C_SOURCES=\
|
||||
src/main.c \
|
||||
src/osmosdr.c \
|
||||
src/sam3u.c \
|
||||
src/serial.c \
|
||||
src/utils.c
|
||||
|
||||
# general compiler flags
|
||||
CFLAGS=-Wall
|
||||
LDFLAGS=-Wl,-Map=$(FULLTARGET).map
|
||||
LIBS=-lrt
|
||||
|
||||
##############################################################################
|
||||
|
||||
SUBDIRS=$(sort $(dir $(C_SOURCES)))
|
||||
|
||||
DEPDIR=deps
|
||||
OBJDIR=objs
|
||||
BINDIR=bin
|
||||
DEPDIRS=$(addprefix $(DEPDIR)/,$(SUBDIRS))
|
||||
OBJDIRS=$(addprefix $(OBJDIR)/,$(SUBDIRS))
|
||||
|
||||
CC=$(CROSS_COMPILE)gcc
|
||||
LD=$(CROSS_COMPILE)gcc
|
||||
|
||||
COBJS=$(C_SOURCES:%.c=%.o)
|
||||
DEPS=$(C_SOURCES:%.c=%.dep)
|
||||
FULLDEPS=$(addprefix $(DEPDIR)/,$(DEPS))
|
||||
FULLCOBJS=$(addprefix $(OBJDIR)/,$(COBJS))
|
||||
FULLTARGET=$(addprefix $(BINDIR)/,$(TARGET))
|
||||
|
||||
ifeq ($(DEBUG),Y)
|
||||
# debug version
|
||||
CFLAGS+=-O0 -g3
|
||||
LDFLAGS+=-g3
|
||||
else ifeq ($(DEBUG),y)
|
||||
# optimized version with debugger info
|
||||
CFLAGS+=-O2 -g3 -Werror -ffunction-sections -fdata-sections
|
||||
LDFLAGS+=-g3 -Wl,--gc-sections
|
||||
else
|
||||
# release version
|
||||
CFLAGS+=-O2 -s -Werror -ffunction-sections -fdata-sections
|
||||
LDFLAGS+=-s -Wl,--gc-sections
|
||||
endif
|
||||
|
||||
.PHONY: all build clean distclean
|
||||
|
||||
all: build
|
||||
|
||||
build: $(FULLTARGET)
|
||||
|
||||
-include $(FULLDEPS)
|
||||
|
||||
$(FULLTARGET): $(DEPDIRS) $(OBJDIRS) $(BINDIR) $(FULLCOBJS)
|
||||
@echo LD \ $(TARGET)
|
||||
$(QUIET)$(LD) $(LDFLAGS) -o $(FULLTARGET) -Wl,--start-group $(FULLCOBJS) $(LIBS) -Wl,--end-group
|
||||
$(QUIET)ln -sf $(FULLTARGET) $(TARGET)
|
||||
|
||||
$(FULLCOBJS):
|
||||
@echo C\ \ \ $(patsubst $(OBJDIR)/%,%,$(patsubst %.o,%.c, $@))
|
||||
$(QUIET)$(CC) $(CFLAGS) $(CFLAGS_$(subst /,_,$(patsubst %.o,%,$@))) -MD -MP -MF $(patsubst %.o,$(DEPDIR)/%.dep,$(patsubst $(OBJDIR)/%,%,$@)) -c $(patsubst $(OBJDIR)/%,%,$(patsubst %.o,%.c, $@)) -o $@
|
||||
|
||||
$(DEPDIRS):
|
||||
$(QUIET)mkdir -p $@
|
||||
|
||||
$(OBJDIRS):
|
||||
$(QUIET)mkdir -p $@
|
||||
|
||||
$(BINDIR):
|
||||
$(QUIET)mkdir -p $@
|
||||
|
||||
clean:
|
||||
$(QUIET)echo CLEAN
|
||||
$(QUIET)rm -Rf $(DEPDIR) $(OBJDIR) $(BINDIR) $(TARGET) $(TARGET).map *~ *.s *.ss
|
||||
|
||||
distclean: clean
|
|
@ -0,0 +1,86 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "serial.h"
|
||||
#include "osmosdr.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int printSyntax()
|
||||
{
|
||||
fprintf(stderr, "Error: Invalid command line!\n\n"
|
||||
"syntax: sdr-samba /dev/ttyACM0 command\n"
|
||||
"valid commands are:\n"
|
||||
" - detect: detect OsmoSDR and print unique ID\n"
|
||||
" - blink: blink LEDs on board\n"
|
||||
" - ramload image.bin: load image.bin into SRAM and start it\n"
|
||||
" - flash image.bin: write image.bin to FLASH\n");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int fd;
|
||||
int res = -1;
|
||||
void* bin;
|
||||
size_t binSize;
|
||||
|
||||
if(argc < 3)
|
||||
return printSyntax();
|
||||
|
||||
if(strcmp(argv[2], "detect") == 0) {
|
||||
if(argc != 3)
|
||||
return printSyntax();
|
||||
if((fd = serialOpen(argv[1])) < 0)
|
||||
return EXIT_FAILURE;
|
||||
res = 0;
|
||||
if(res >= 0)
|
||||
res = osmoSDRDetect(fd);
|
||||
if(res >= 0)
|
||||
res = osmoSDRPrintUID(fd, 0);
|
||||
if(res >= 0)
|
||||
res = osmoSDRPrintUID(fd, 1);
|
||||
serialClose(fd);
|
||||
} else if(strcmp(argv[2], "blink") == 0) {
|
||||
if(argc != 3)
|
||||
return printSyntax();
|
||||
if((fd = serialOpen(argv[1])) < 0)
|
||||
return EXIT_FAILURE;
|
||||
res = 0;
|
||||
if(res >= 0)
|
||||
res = osmoSDRDetect(fd);
|
||||
if(res >= 0)
|
||||
res = osmoSDRBlink(fd);
|
||||
serialClose(fd);
|
||||
} else if(strcmp(argv[2], "ramload") == 0) {
|
||||
if(argc != 4)
|
||||
return printSyntax();
|
||||
if((bin = loadFile(argv[3], &binSize)) == NULL)
|
||||
return EXIT_FAILURE;
|
||||
if((fd = serialOpen(argv[1])) < 0)
|
||||
return EXIT_FAILURE;
|
||||
res = 0;
|
||||
if(res >= 0)
|
||||
res = osmoSDRDetect(fd);
|
||||
if(res >= 0)
|
||||
res = osmoSDRRamLoad(fd, bin, binSize);
|
||||
serialClose(fd);
|
||||
} else if(strcmp(argv[2], "flash") == 0) {
|
||||
if(argc != 4)
|
||||
return printSyntax();
|
||||
if((bin = loadFile(argv[3], &binSize)) == NULL)
|
||||
return EXIT_FAILURE;
|
||||
if((fd = serialOpen(argv[1])) < 0)
|
||||
return EXIT_FAILURE;
|
||||
res = 0;
|
||||
if(res >= 0)
|
||||
res = osmoSDRDetect(fd);
|
||||
if(res >= 0)
|
||||
res = osmoSDRFlash(fd, bin, binSize);
|
||||
serialClose(fd);
|
||||
} else {
|
||||
return printSyntax();
|
||||
}
|
||||
|
||||
return (res < 0) ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "osmosdr.h"
|
||||
#include "sam3u.h"
|
||||
|
||||
int osmoSDRDetect(int fd)
|
||||
{
|
||||
uint32_t chipID;
|
||||
|
||||
if(sam3uDetect(fd, &chipID) < 0)
|
||||
return -1;
|
||||
|
||||
if((chipID & 0xffffffe0) == 0x28000960) {
|
||||
printf("Chip ID: 0x%08x -- ok\n", chipID);
|
||||
} else {
|
||||
printf("Chip ID: 0x%08x -- ERROR\n", chipID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int osmoSDRPrintUID(int fd, int bank)
|
||||
{
|
||||
uint8_t uniqueID[16];
|
||||
int i;
|
||||
|
||||
if(sam3uReadUniqueID(fd, bank, uniqueID) < 0) {
|
||||
fprintf(stderr, "could not read unique ID\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("UID%d : ", bank);
|
||||
for(i = 0; i < 16; i++)
|
||||
printf("%02x", uniqueID[i]);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int osmoSDRBlink(int fd)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(sam3uWrite32(fd, 0x400e0e00 + 0x44, 1 << 19) < 0)
|
||||
return -1;
|
||||
if(sam3uWrite32(fd, 0x400e0e00 + 0x60, 1 << 19) < 0)
|
||||
return -1;
|
||||
if(sam3uWrite32(fd, 0x400e0e00 + 0x54, 1 << 19) < 0)
|
||||
return -1;
|
||||
if(sam3uWrite32(fd, 0x400e0e00 + 0x10, 1 << 19) < 0)
|
||||
return -1;
|
||||
if(sam3uWrite32(fd, 0x400e0e00 + 0x00, 1 << 19) < 0)
|
||||
return -1;
|
||||
|
||||
for(i = 0; i < 10; i++) {
|
||||
printf("on."); fflush(stdout);
|
||||
if(sam3uWrite32(fd, 0x400e0e00 + 0x34, 1 << 19) < 0)
|
||||
return -1;
|
||||
usleep(250 * 1000);
|
||||
printf("off."); fflush(stdout);
|
||||
if(sam3uWrite32(fd, 0x400e0e00 + 0x30, 1 << 19) < 0)
|
||||
return -1;
|
||||
usleep(250 * 1000);
|
||||
}
|
||||
|
||||
printf(" -- ok\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int osmoSDRRamLoad(int fd, void* bin, size_t binSize)
|
||||
{
|
||||
size_t ofs;
|
||||
uint32_t tmp;
|
||||
|
||||
printf("Uploading %zu bytes @ 0x20001000", binSize);
|
||||
|
||||
for(ofs = 0; ofs < binSize; ofs += 4) {
|
||||
if(sam3uWrite32(fd, 0x20001000 + ofs, ((uint32_t*)bin)[ofs / 4]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(ofs = 0; ofs < binSize; ofs += 4) {
|
||||
if(sam3uRead32(fd, 0x20001000 + ofs, &tmp) < 0)
|
||||
return -1;
|
||||
if(tmp != ((uint32_t*)bin)[ofs / 4]) {
|
||||
printf(" -- RAM verify failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
printf(" -- ok\n");
|
||||
|
||||
printf("Starting @ 0x%08x\n", ((uint32_t*)bin)[1]);
|
||||
|
||||
if(sam3uRun(fd, ((uint32_t*)bin)[1]) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int osmoSDRFlash(int fd, void* bin, size_t binSize)
|
||||
{
|
||||
return sam3uFlash(fd, 0, bin, binSize);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef INCLUDE_OSMOSDR_H
|
||||
#define INCLUDE_OSMOSDR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int osmoSDRDetect(int fd);
|
||||
int osmoSDRPrintUID(int fd, int bank);
|
||||
int osmoSDRBlink(int fd);
|
||||
int osmoSDRRamLoad(int fd, void* bin, size_t binSize);
|
||||
int osmoSDRFlash(int fd, void* bin, size_t binSize);
|
||||
|
||||
#endif // INCLUDE_OSMOSDR_H
|
|
@ -0,0 +1,308 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "sam3u.h"
|
||||
#include "serial.h"
|
||||
|
||||
int sam3uRead32(int fd, uint32_t address, uint32_t* value)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "w%08X,4#", address);
|
||||
if(serialPutS(fd, str) < 0)
|
||||
return -1;
|
||||
if(serialExpect(fd, "\n\r0x", 100) < 0)
|
||||
return -1;
|
||||
if(serialGetS(fd, str, 8, 100) < 0)
|
||||
return -1;
|
||||
str[8] = '\0';
|
||||
errno = 0;
|
||||
*value = strtoll(str, NULL, 16);
|
||||
if(errno != 0) {
|
||||
fprintf(stderr, "number conversion failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(serialExpect(fd, "\n\r>", 100) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3uRead16(int fd, uint32_t address, uint16_t* value)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "h%08X,2#", address);
|
||||
if(serialPutS(fd, str) < 0)
|
||||
return -1;
|
||||
if(serialExpect(fd, "\n\r0x", 100) < 0)
|
||||
return -1;
|
||||
if(serialGetS(fd, str, 4, 100) < 0)
|
||||
return -1;
|
||||
str[4] = '\0';
|
||||
errno = 0;
|
||||
*value = strtol(str, NULL, 16);
|
||||
if(errno != 0) {
|
||||
fprintf(stderr, "number conversion failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(serialExpect(fd, "\n\r>", 100) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3uRead8(int fd, uint32_t address, uint8_t* value)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "o%08X,1#", address);
|
||||
if(serialPutS(fd, str) < 0)
|
||||
return -1;
|
||||
if(serialExpect(fd, "\n\r0x", 100) < 0)
|
||||
return -1;
|
||||
if(serialGetS(fd, str, 2, 100) < 0)
|
||||
return -1;
|
||||
str[2] = '\0';
|
||||
errno = 0;
|
||||
*value = strtol(str, NULL, 16);
|
||||
if(errno != 0) {
|
||||
fprintf(stderr, "number conversion failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(serialExpect(fd, "\n\r>", 100) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3uWrite32(int fd, uint32_t address, uint32_t value)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "W%08X,%08X#", address, value);
|
||||
if(serialPutS(fd, str) < 0)
|
||||
return -1;
|
||||
if(serialExpect(fd, "\n\r>", 100) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3uWrite16(int fd, uint32_t address, uint16_t value)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "H%08X,%04X#", address, value);
|
||||
if(serialPutS(fd, str) < 0)
|
||||
return -1;
|
||||
if(serialExpect(fd, "\n\r>", 100) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3uWrite8(int fd, uint32_t address, uint8_t value)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "O%08X,%02X#", address, value);
|
||||
if(serialPutS(fd, str) < 0)
|
||||
return -1;
|
||||
if(serialExpect(fd, "\n\r>", 100) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3uRun(int fd, uint32_t address)
|
||||
{
|
||||
char str[32];
|
||||
sprintf(str, "G%08X#", address);
|
||||
if(serialPutS(fd, str) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3uDetect(int fd, uint32_t* chipID)
|
||||
{
|
||||
char c;
|
||||
|
||||
while(serialGetC(fd, &c, 100) >= 0) ;
|
||||
|
||||
if(serialPutS(fd, "T#") < 0)
|
||||
return -1;
|
||||
|
||||
if(serialExpect(fd, "\n\r\n\r>", 100) < 0) {
|
||||
fprintf(stderr, "did not receive expected answer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sam3uRead32(fd, 0x400e0740, chipID);
|
||||
}
|
||||
|
||||
int sam3uReadUniqueID(int fd, int bank, uint8_t* uniqueID)
|
||||
{
|
||||
uint32_t regBase;
|
||||
uint32_t flashBase;
|
||||
uint32_t fsr;
|
||||
int i;
|
||||
|
||||
switch(bank) {
|
||||
case 0:
|
||||
regBase = 0x400e0800;
|
||||
flashBase = 0x80000;
|
||||
break;
|
||||
case 1:
|
||||
regBase = 0x400e0a00;
|
||||
flashBase = 0x100000;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "illegal flash bank");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(sam3uWrite32(fd, regBase + 0x04, 0x5a00000e) < 0)
|
||||
return -1;
|
||||
|
||||
do {
|
||||
if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0)
|
||||
return -1;
|
||||
} while((fsr & 1) != 0);
|
||||
|
||||
for(i = 0; i < 16; i++) {
|
||||
if(sam3uRead8(fd, flashBase + i, uniqueID + i) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(sam3uWrite32(fd, regBase + 0x04, 0x5a00000f) < 0)
|
||||
return -1;
|
||||
|
||||
do {
|
||||
if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0)
|
||||
return -1;
|
||||
} while((fsr & 1) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sam3uFlash(int fd, int bank, void* bin, size_t binSize)
|
||||
{
|
||||
uint32_t regBase;
|
||||
uint32_t flashBase;
|
||||
uint32_t fsr;
|
||||
uint32_t flID;
|
||||
uint32_t flSize;
|
||||
uint32_t flPageSize;
|
||||
uint32_t flNbPlane;
|
||||
uint8_t buf[8192];
|
||||
uint32_t ofs;
|
||||
uint32_t todo;
|
||||
uint32_t len;
|
||||
uint32_t idx;
|
||||
|
||||
switch(bank) {
|
||||
case 0:
|
||||
regBase = 0x400e0800;
|
||||
flashBase = 0x80000;
|
||||
break;
|
||||
case 1:
|
||||
regBase = 0x400e0a00;
|
||||
flashBase = 0x100000;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "illegal flash bank");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("reading flash descriptor");
|
||||
|
||||
if(sam3uWrite32(fd, regBase + 0x04, 0x5a000000) < 0)
|
||||
goto error;
|
||||
|
||||
do {
|
||||
if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0)
|
||||
goto error;
|
||||
} while((fsr & 1) == 0);
|
||||
|
||||
|
||||
if(sam3uRead32(fd, regBase + 0x0c, &flID) < 0)
|
||||
goto error;
|
||||
if(sam3uRead32(fd, regBase + 0x0c, &flSize) < 0)
|
||||
goto error;
|
||||
if(sam3uRead32(fd, regBase + 0x0c, &flPageSize) < 0)
|
||||
goto error;
|
||||
if(sam3uRead32(fd, regBase + 0x0c, &flNbPlane) < 0)
|
||||
goto error;
|
||||
|
||||
printf(" -- ok\n");
|
||||
printf("Flash ID: 0x%08x\n", flID);
|
||||
printf("Flash size: %d Bytes\n", flSize);
|
||||
printf("Page size: %d Bytes\n", flPageSize);
|
||||
printf("Number of planes: %d\n", flNbPlane);
|
||||
|
||||
#if 1
|
||||
printf("erasing flash"); fflush(stdout);
|
||||
|
||||
if(sam3uWrite32(fd, regBase + 0x04, 0x5a000005) < 0)
|
||||
goto error;
|
||||
|
||||
do {
|
||||
if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0)
|
||||
goto error;
|
||||
} while((fsr & 1) == 0);
|
||||
|
||||
printf(" -- ok\n");
|
||||
#endif
|
||||
|
||||
ofs = 0;
|
||||
for(todo = binSize; todo > 0; todo -= len) {
|
||||
printf("flashing @ 0x%08x", ofs); fflush(stdout);
|
||||
len = todo;
|
||||
if(len > flPageSize)
|
||||
len = flPageSize;
|
||||
memset(buf, 0xff, sizeof(buf));
|
||||
memcpy(buf, ((uint8_t*)bin) + ofs, len);
|
||||
for(idx = 0; idx < flPageSize / 4; idx++) {
|
||||
if(sam3uWrite32(fd, flashBase + ofs + (idx * 4), ((uint32_t*)buf)[idx]) < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(sam3uWrite32(fd, regBase + 0x04, 0x5a000000 | ((ofs / flPageSize) << 8) | 0x03) < 0)
|
||||
goto error;
|
||||
|
||||
do {
|
||||
if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0)
|
||||
goto error;
|
||||
} while((fsr & 1) == 0);
|
||||
|
||||
printf(" -- ok\n");
|
||||
|
||||
ofs += flPageSize;
|
||||
}
|
||||
|
||||
ofs = 0;
|
||||
for(todo = binSize; todo > 0; todo -= len) {
|
||||
printf("verifying @ 0x%08x", ofs); fflush(stdout);
|
||||
len = todo;
|
||||
if(len > flPageSize)
|
||||
len = flPageSize;
|
||||
|
||||
for(idx = 0; idx < flPageSize / 4; idx++) {
|
||||
if(sam3uRead32(fd, flashBase + ofs + (idx * 4), ((uint32_t*)buf) + idx) < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(memcmp(buf, ((uint8_t*)bin) + ofs, len) == 0)
|
||||
printf(" -- ok\n");
|
||||
else printf(" -- ERROR\n");
|
||||
|
||||
ofs += flPageSize;
|
||||
}
|
||||
|
||||
printf("disabling SAM-BA"); fflush(stdout);
|
||||
if(sam3uWrite32(fd, regBase + 0x04, 0x5a000000 | (1 << 8) | 0x0b) < 0)
|
||||
goto error;
|
||||
|
||||
do {
|
||||
if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0)
|
||||
goto error;
|
||||
} while((fsr & 1) == 0);
|
||||
|
||||
printf(" -- ok\n");
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
printf(" -- ERROR\n");
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef INCLUDE_SAM3U_H
|
||||
#define INCLUDE_SAM3U_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int sam3uRead32(int fd, uint32_t address, uint32_t* value);
|
||||
int sam3uRead16(int fd, uint32_t address, uint16_t* value);
|
||||
int sam3uRead8(int fd, uint32_t address, uint8_t* value);
|
||||
|
||||
int sam3uWrite32(int fd, uint32_t address, uint32_t value);
|
||||
int sam3uWrite16(int fd, uint32_t address, uint16_t value);
|
||||
int sam3uWrite8(int fd, uint32_t address, uint8_t value);
|
||||
|
||||
int sam3uRun(int fd, uint32_t address);
|
||||
int sam3uDetect(int fd, uint32_t* chipID);
|
||||
int sam3uReadUniqueID(int fd, int bank, uint8_t* uniqueID);
|
||||
int sam3uFlash(int fd, int bank, void* bin, size_t binSize);
|
||||
|
||||
#endif // INCLUDE_SAM3U_H
|
|
@ -0,0 +1,175 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <poll.h>
|
||||
#include "serial.h"
|
||||
#include "utils.h"
|
||||
|
||||
int serialOpen(const char* device)
|
||||
{
|
||||
int fd = -1;
|
||||
struct termios tios;
|
||||
|
||||
if((fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
|
||||
fprintf(stderr, "could not open %s: %s\n", device, strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
bzero(&tios, sizeof(tios));
|
||||
tios.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
|
||||
tios.c_iflag = IGNPAR;
|
||||
tios.c_oflag = 0;
|
||||
tios.c_lflag = ICANON;
|
||||
tios.c_cc[VMIN] = 1;
|
||||
cfmakeraw(&tios);
|
||||
if(tcflush(fd, TCIOFLUSH) < 0) {
|
||||
fprintf(stderr, "tcflush() failed: %s\n", strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
if(tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
|
||||
fprintf(stderr, "tcsetattr() failed: %s\n", strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
if(tcflush(fd, TCIOFLUSH) < 0) {
|
||||
fprintf(stderr, "tcflush() failed: %s\n", strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
||||
failed:
|
||||
if(fd >= 0)
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void serialClose(int fd)
|
||||
{
|
||||
if(fd >= 0)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int serialPutC(int fd, char c)
|
||||
{
|
||||
if(write(fd, &c, sizeof(char)) != sizeof(char)) {
|
||||
if(errno == EAGAIN) {
|
||||
struct pollfd pollfd;
|
||||
int res;
|
||||
pollfd.fd = fd;
|
||||
pollfd.events = POLLOUT;
|
||||
pollfd.revents = 0;
|
||||
do {
|
||||
res = poll(&pollfd, 1, 250);
|
||||
} while((res < 0) && (errno == EINTR));
|
||||
if(res > 0) {
|
||||
if(write(fd, &c, sizeof(char)) != sizeof(char)) {
|
||||
fprintf(stderr, "write failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if(res == 0) {
|
||||
fprintf(stderr, "write failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(stderr, "poll failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "write failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int serialPutS(int fd, const char* str)
|
||||
{
|
||||
while(*str != '\0') {
|
||||
if(serialPutC(fd, *str++) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int serialGetC(int fd, char* c, int timeout)
|
||||
{
|
||||
struct pollfd pollfd;
|
||||
int res;
|
||||
|
||||
pollfd.fd = fd;
|
||||
pollfd.events = POLLIN;
|
||||
pollfd.revents = 0;
|
||||
|
||||
do {
|
||||
res = poll(&pollfd, 1, timeout);
|
||||
} while((res < 0) && (errno == EINTR));
|
||||
|
||||
if(res > 0) {
|
||||
if(read(fd, c, sizeof(char)) != sizeof(char)) {
|
||||
fprintf(stderr, "read failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else if(res == 0) {
|
||||
// timeout
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "poll failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int serialGetS(int fd, char* str, int len, int timeout)
|
||||
{
|
||||
int todo = len;
|
||||
uint64_t endTime = getTickCount() + timeout;
|
||||
|
||||
while(todo > 0) {
|
||||
uint64_t now = getTickCount();
|
||||
|
||||
if(now < endTime) {
|
||||
char c;
|
||||
if(serialGetC(fd, &c, endTime - now) < 0)
|
||||
return -1;
|
||||
//printf("[%02x]", c);
|
||||
*str++ = c;
|
||||
todo--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (todo > 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
int serialExpect(int fd, const char* str, int timeout)
|
||||
{
|
||||
int todo = strlen(str);
|
||||
uint64_t endTime = getTickCount() + timeout;
|
||||
|
||||
while(todo > 0) {
|
||||
uint64_t now = getTickCount();
|
||||
|
||||
if(now < endTime) {
|
||||
char c;
|
||||
if(serialGetC(fd, &c, endTime - now) < 0)
|
||||
return -1;
|
||||
//printf("[%02x]", c);
|
||||
if(c == *str++) {
|
||||
todo--;
|
||||
continue;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (todo > 0) ? -1 : 0;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef INCLUDE_SERIAL_H
|
||||
#define INCLUDE_SERIAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int serialOpen(const char* device);
|
||||
void serialClose(int fd);
|
||||
int serialPutC(int fd, char c);
|
||||
int serialPutS(int fd, const char* str);
|
||||
int serialGetC(int fd, char* c, int timeout);
|
||||
int serialGetS(int fd, char* str, int len, int timeout);
|
||||
int serialExpect(int fd, const char* str, int timeout);
|
||||
|
||||
#endif // INCLUDE_SERIAL_H
|
|
@ -0,0 +1,49 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include "utils.h"
|
||||
|
||||
uint64_t getTickCount()
|
||||
{
|
||||
struct timespec t;
|
||||
|
||||
if(clock_gettime(CLOCK_MONOTONIC, &t) != 0)
|
||||
return 0;
|
||||
return (((uint64_t)t.tv_sec) * 1000) + (((uint64_t)t.tv_nsec) / 1000000);
|
||||
}
|
||||
|
||||
void* loadFile(const char* filename, size_t* size)
|
||||
{
|
||||
void* result = NULL;
|
||||
struct stat statbuf;
|
||||
FILE* f = NULL;
|
||||
|
||||
if(stat(filename, &statbuf) < 0) {
|
||||
fprintf(stderr, "could not stat() file %s: %s\n", filename, strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if((result = calloc(1, statbuf.st_size)) == NULL) {
|
||||
fprintf(stderr, "failed to allocate %zu bytes of memory\n", (size_t)statbuf.st_size);
|
||||
goto failed;
|
||||
}
|
||||
if((f = fopen(filename, "rb")) == NULL) {
|
||||
fprintf(stderr, "failed to open %s: %s\n", filename, strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
if(fread(result, 1, statbuf.st_size, f) != statbuf.st_size) {
|
||||
fprintf(stderr, "could not read all bytes: %s\n", strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
*size = (size_t)statbuf.st_size;
|
||||
return result;
|
||||
|
||||
failed:
|
||||
if(f != NULL)
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef INCLUDE_UTILS_H
|
||||
#define INCLUDE_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint64_t getTickCount();
|
||||
void* loadFile(const char* filename, size_t* size);
|
||||
|
||||
#endif // INCLUDE_UTILS_H
|
Reference in New Issue