forked from atmelcorp/micro-sam-ba
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
13 changed files
with
1,524 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* text |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
GPATH | ||
GRTAGS | ||
GTAGS | ||
*.o | ||
*~ |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
CFLAGS=-std=gnu99 -Wall | ||
|
||
BINARY=usamba | ||
SOURCES = usamba.c comm.c chipid.c eefc.c | ||
OBJS = $(SOURCES:.c=.o) | ||
|
||
$(BINARY): $(OBJS) | ||
|
||
clean: | ||
@rm -f $(OBJS) $(BINARY) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
Micro SAM-BA | ||
------------ | ||
|
||
# Description | ||
|
||
This simple tool can be used to program the internal flash of the following | ||
microcontrollers: | ||
|
||
- Atmel SAME70/S70/V70/V71 | ||
|
||
Communication with SAM-BA bootloader is only supported through USB. | ||
|
||
Before using the tool, the MCU must be put in "Boot from ROM" mode, either by | ||
fully erasing it using the ERASE pin or by clearing GPVNM1 (see datasheet for | ||
more information). When the device is in this mode, it will be enumerated as: | ||
|
||
03eb:6124 Atmel Corp. at91sam SAMBA bootloader | ||
|
||
# Usage | ||
|
||
Usage: ``./usamba <port> (read|write|verify|erase-all|gpnvm) [args]*`` | ||
|
||
- Read Flash: | ||
``./usamba <port> read <filename> <start-address> <size>`` | ||
|
||
- Write Flash: | ||
``./usamba <port> write <filename> <start-address>`` | ||
|
||
- Verify Flash: | ||
``./usamba <port> verify <filename> <start-address>`` | ||
|
||
- Erase Flash: | ||
``./usamba <port> erase-all`` | ||
|
||
- Get/Set/Clear GPNVM: | ||
``./usamba <port> gpnvm (get|set|clear) <gpnvm_number>`` | ||
|
||
for all commands: | ||
``<port>`` is the USB device node for the SAM-BA bootloader, for | ||
example ``/dev/ttyACM0``. | ||
``<start-address>`` and ``<size>`` can be specified in decimal, hexadecimal (if | ||
prefixed by ``0x``) or octal (if prefixed by ``0``). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* Copyright (c) 2015-2016, Atmel Corporation. | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope 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. | ||
*/ | ||
|
||
#include <string.h> | ||
#include "chipid.h" | ||
#include "comm.h" | ||
#include "utils.h" | ||
|
||
static const struct _chip _chips_samx7[] = { | ||
{ "SAME70Q21", 0xa1020e00, 0x00000002, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAME70Q20", 0xa1020c00, 0x00000002, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAME70Q19", 0xa10d0a00, 0x00000002, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAME70N21", 0xa1020e00, 0x00000001, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAME70N20", 0xa1020c00, 0x00000001, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAME70N19", 0xa10d0a00, 0x00000001, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAME70J21", 0xa1020e00, 0x00000000, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAME70J20", 0xa1020c00, 0x00000000, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAME70J19", 0xa10d0a00, 0x00000000, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMS70Q21", 0xa1120e00, 0x00000002, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAMS70Q20", 0xa1120c00, 0x00000002, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMS70Q19", 0xa11d0a00, 0x00000002, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMS70N21", 0xa1120e00, 0x00000001, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAMS70N20", 0xa1120c00, 0x00000001, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMS70N19", 0xa11d0a00, 0x00000001, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMS70J21", 0xa1120e00, 0x00000000, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAMS70J20", 0xa1120c00, 0x00000000, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMS70J19", 0xa11d0a00, 0x00000000, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMV71Q21", 0xa1220e00, 0x00000002, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAMV71Q20", 0xa1220c00, 0x00000002, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMV71Q19", 0xa12d0a00, 0x00000002, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMV71N21", 0xa1220e00, 0x00000001, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAMV71N20", 0xa1220c00, 0x00000001, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMV71N19", 0xa12d0a00, 0x00000001, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMV71J21", 0xa1220e00, 0x00000000, 0x400e0c00, 0x00400000, 2048, 9 }, | ||
{ "SAMV71J20", 0xa1220c00, 0x00000000, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMV71J19", 0xa12d0a00, 0x00000000, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMV70Q20", 0xa1320c00, 0x00000002, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMV70Q19", 0xa13d0a00, 0x00000002, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMV70N20", 0xa1320c00, 0x00000001, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMV70N19", 0xa13d0a00, 0x00000001, 0x400e0c00, 0x00400000, 512, 9 }, | ||
{ "SAMV70J20", 0xa1320c00, 0x00000000, 0x400e0c00, 0x00400000, 1024, 9 }, | ||
{ "SAMV70J19", 0xa13d0a00, 0x00000000, 0x400e0c00, 0x00400000, 512, 9 }, | ||
}; | ||
|
||
static const struct _chip_serie _chip_series[] = { | ||
{ | ||
.name = "samx7", | ||
.cidr_reg = 0x400e0940, | ||
.exid_reg = 0x400e0944, | ||
.nb_chips = ARRAY_SIZE(_chips_samx7), | ||
.chips = _chips_samx7, | ||
}, | ||
}; | ||
|
||
const struct _chip_serie* chipid_get_serie(const char* name) | ||
{ | ||
for (int i = 0; i < ARRAY_SIZE(_chip_series); i++) | ||
if (!strcmp(_chip_series[i].name, name)) | ||
return &_chip_series[i]; | ||
return NULL; | ||
} | ||
|
||
bool chipid_check_serie(int fd, const struct _chip_serie* serie, const struct _chip** chip) | ||
{ | ||
// Read chip identifiers (CIDR/EXID) | ||
uint32_t cidr, exid; | ||
if (!samba_read_word(fd, serie->cidr_reg, &cidr)) | ||
return false; | ||
if (!samba_read_word(fd, serie->exid_reg, &exid)) | ||
return false; | ||
|
||
// Identify chip and read its flash infos | ||
for (int i = 0; i < serie->nb_chips; i++) { | ||
if (serie->chips[i].cidr == cidr && serie->chips[i].exid == exid) { | ||
*chip = &serie->chips[i]; | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
const struct _chip_serie* chipid_identity_serie(int fd, const struct _chip** chip) | ||
{ | ||
for (int i = 0; i < ARRAY_SIZE(_chip_series); i++) | ||
if (chipid_check_serie(fd, &_chip_series[i], chip)) | ||
return &_chip_series[i]; | ||
return NULL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* Copyright (c) 2015-2016, Atmel Corporation. | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope 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. | ||
*/ | ||
|
||
#ifndef CHIPID_H_ | ||
#define CHIPID_H_ | ||
|
||
#include <stdbool.h> | ||
#include <stdint.h> | ||
|
||
struct _chip { | ||
const char* name; | ||
uint32_t cidr; | ||
uint32_t exid; | ||
uint32_t eefc_base; | ||
uint32_t flash_addr; | ||
uint32_t flash_size; | ||
uint8_t gpnvm; | ||
}; | ||
|
||
struct _chip_serie { | ||
const char* name; | ||
uint32_t cidr_reg; | ||
uint32_t exid_reg; | ||
uint32_t nb_chips; | ||
const struct _chip* chips; | ||
}; | ||
|
||
extern const struct _chip_serie* chipid_get_serie(const char* name); | ||
|
||
extern bool chipid_check_serie(int fd, const struct _chip_serie* serie, const struct _chip** chip); | ||
|
||
extern const struct _chip_serie* chipid_identity_serie(int fd, const struct _chip** chip); | ||
|
||
#endif /* CHIPID_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* Copyright (c) 2015-2016, Atmel Corporation. | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope 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. | ||
*/ | ||
|
||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <termios.h> | ||
#include <unistd.h> | ||
#include "comm.h" | ||
#include "utils.h" | ||
|
||
static bool configure_tty(int fd, int speed) | ||
{ | ||
struct termios tty; | ||
|
||
memset(&tty, 0, sizeof(tty)); | ||
|
||
if (tcgetattr(fd, &tty) != 0) { | ||
perror("error from tcgetattr: "); | ||
return false; | ||
} | ||
|
||
if (speed) { | ||
cfsetospeed(&tty, speed); | ||
cfsetispeed(&tty, speed); | ||
} | ||
|
||
tty.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB | CRTSCTS); | ||
tty.c_cflag |= CS8 | CLOCAL | CREAD; | ||
tty.c_lflag = 0; | ||
tty.c_oflag = 0; | ||
tty.c_cc[VMIN] = 1; | ||
tty.c_cc[VTIME] = 5; | ||
tty.c_iflag &= ~(ICRNL | IGNBRK | IXON | IXOFF | IXANY); | ||
|
||
if (tcsetattr(fd, TCSANOW, &tty) != 0) { | ||
perror("error from tcsetattr: "); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
static bool switch_to_binary(int fd) | ||
{ | ||
char cmd[] = "N#"; | ||
if (write(fd, cmd, strlen(cmd)) != strlen(cmd)) | ||
return false; | ||
return read(fd, cmd, 2) == 2; | ||
} | ||
|
||
int samba_open(const char* device) | ||
{ | ||
int fd = open(device, O_RDWR | O_NOCTTY | O_SYNC); | ||
if (fd < 0) { | ||
perror("Could not open device"); | ||
return -1; | ||
} | ||
|
||
if (!configure_tty(fd, B4000000)) { | ||
close(fd); | ||
return -1; | ||
} | ||
|
||
if (!switch_to_binary(fd)) { | ||
close(fd); | ||
return -1; | ||
} | ||
|
||
return fd; | ||
} | ||
|
||
void samba_close(int fd) | ||
{ | ||
close(fd); | ||
} | ||
|
||
bool samba_read_word(int fd, uint32_t addr, uint32_t* value) | ||
{ | ||
char cmd[12]; | ||
snprintf(cmd, sizeof(cmd), "w%08x,#", addr); | ||
if (write(fd, cmd, strlen(cmd)) != strlen(cmd)) | ||
return false; | ||
return read(fd, value, 4) == 4; | ||
} | ||
|
||
bool samba_write_word(int fd, uint32_t addr, uint32_t value) | ||
{ | ||
char cmd[20]; | ||
snprintf(cmd, sizeof(cmd), "W%08x,%08x#", addr, value); | ||
return write(fd, cmd, strlen(cmd)) == strlen(cmd); | ||
} | ||
|
||
bool samba_read(int fd, uint8_t* buffer, uint32_t addr, uint32_t size) | ||
{ | ||
char cmd[20]; | ||
while (size > 0) { | ||
uint32_t count = MIN(size, 1024); | ||
// workaround for bug when size is exactly 512 | ||
if (count == 512) | ||
count = 1; | ||
snprintf(cmd, sizeof(cmd), "R%08x,%08x#", addr, count); | ||
if (write(fd, cmd, strlen(cmd)) != strlen(cmd)) | ||
return false; | ||
if (read(fd, buffer, count) != count) | ||
return false; | ||
addr += count; | ||
buffer += count; | ||
size -= count; | ||
} | ||
return true; | ||
} | ||
|
||
bool samba_write(int fd, uint8_t* buffer, uint32_t addr, uint32_t size) | ||
{ | ||
char cmd[20]; | ||
while (size > 0) { | ||
uint32_t count = MIN(size, 1024); | ||
// workaround for bug when size is exactly 512 | ||
if (count == 512) | ||
count = 1; | ||
snprintf(cmd, sizeof(cmd), "S%08x,%08x#", addr, count); | ||
if (write(fd, cmd, strlen(cmd)) != strlen(cmd)) | ||
return false; | ||
if (write(fd, buffer, count) != count) | ||
return false; | ||
buffer += count; | ||
size -= count; | ||
} | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright (c) 2015-2016, Atmel Corporation. | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope 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. | ||
*/ | ||
|
||
#ifndef COMM_H_ | ||
#define COMM_H_ | ||
|
||
#include <stdbool.h> | ||
#include <stdint.h> | ||
|
||
extern int samba_open(const char* device); | ||
|
||
extern void samba_close(int fd); | ||
|
||
extern bool samba_read_word(int fd, uint32_t addr, uint32_t* value); | ||
|
||
extern bool samba_write_word(int fd, uint32_t addr, uint32_t value); | ||
|
||
extern bool samba_read(int fd, uint8_t* buffer, uint32_t addr, uint32_t size); | ||
|
||
extern bool samba_write(int fd, uint8_t* buffer, uint32_t addr, uint32_t size); | ||
|
||
#endif /* COMM_H_ */ |
Oops, something went wrong.