added v2.0
This commit is contained in:
14
tools/AsciiToBin.py
Executable file
14
tools/AsciiToBin.py
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/python3
|
||||
import sys
|
||||
|
||||
if (len(sys.argv)!=2):
|
||||
print('usage: {:s} <filename>'.format(sys.argv[0]));
|
||||
sys.exit(0)
|
||||
|
||||
fbin=open(sys.argv[1].replace('.hack','.bin'),'w+b')
|
||||
fhack=open(sys.argv[1],'r')
|
||||
lines=fhack.readlines()
|
||||
for line in lines:
|
||||
binary=int(line.strip(),2)
|
||||
byte=bytearray([(binary>>8),binary&0xff])
|
||||
fbin.write(byte)
|
BIN
tools/Assembler/assembler.pyc
Executable file
BIN
tools/Assembler/assembler.pyc
Executable file
Binary file not shown.
BIN
tools/Assembler/code.pyc
Normal file
BIN
tools/Assembler/code.pyc
Normal file
Binary file not shown.
BIN
tools/Assembler/parser.pyc
Normal file
BIN
tools/Assembler/parser.pyc
Normal file
Binary file not shown.
BIN
tools/Assembler/symbolTable.pyc
Normal file
BIN
tools/Assembler/symbolTable.pyc
Normal file
Binary file not shown.
BIN
tools/JackCompiler/CompilationEngine.pyc
Normal file
BIN
tools/JackCompiler/CompilationEngine.pyc
Normal file
Binary file not shown.
BIN
tools/JackCompiler/JackAnalyser.pyc
Executable file
BIN
tools/JackCompiler/JackAnalyser.pyc
Executable file
Binary file not shown.
BIN
tools/JackCompiler/JackCompiler.pyc
Executable file
BIN
tools/JackCompiler/JackCompiler.pyc
Executable file
Binary file not shown.
BIN
tools/JackCompiler/JackTokenizer.pyc
Normal file
BIN
tools/JackCompiler/JackTokenizer.pyc
Normal file
Binary file not shown.
BIN
tools/JackCompiler/SymbolTable.pyc
Normal file
BIN
tools/JackCompiler/SymbolTable.pyc
Normal file
Binary file not shown.
BIN
tools/JackCompiler/VMCodeWriter.pyc
Normal file
BIN
tools/JackCompiler/VMCodeWriter.pyc
Normal file
Binary file not shown.
55
tools/Readme.md
Normal file
55
tools/Readme.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# tools
|
||||
|
||||
This folder contains the toolchain for Hack/Jack development.
|
||||
|
||||
## vim
|
||||
|
||||
vim configuration file to highlight syntax of jack/hack-files, when editing with vim. Copy the content of the subfolders into the appropriate vim configuration directory situated in your home directory `~/.vim`.
|
||||
|
||||
```
|
||||
$ cp vim/syntax/* ~/.vim/syntax/
|
||||
$ cp vim/ftdetect/* ~/.vim/ftdetect/
|
||||
```
|
||||
|
||||
## Assembler
|
||||
|
||||
Assembler translates Hack-Assembly-files to Machnine-code. Outputs the machine code to filename.hack.
|
||||
|
||||
`usage: ./Assembler/assembler.pyc [filename.asm]`
|
||||
|
||||
## JackCompiler
|
||||
|
||||
Compiles Jack classes (single file or all *.jack files in directory) to virtualmachine code.
|
||||
|
||||
`usage: ./JackCompiler/JackCompiler.pyc [filename.jack] or [dir]`
|
||||
|
||||
## VMTranslator
|
||||
|
||||
Translates vm code (single file or all files with ending *.vm in directory)to Assembler.
|
||||
|
||||
`usage: ./VMTranslator/VMTranslator.pyc [filename.vm] or [dir]`
|
||||
|
||||
## AsciiToBin.py
|
||||
|
||||
Translates .hack files to binary files that can be uploaded with iecprogduino.
|
||||
|
||||
`usage: ./AsciiToBin.py [filename.hack]`
|
||||
|
||||
## iceprogduino
|
||||
|
||||
iceprogduino is the programmer to upload bitstream files to iCE40 boards of olimex over olimexino-32u4 (arduino like board).
|
||||
|
||||
For this you first have to upload firmware to olimexino-32u4.
|
||||
|
||||
iceprogduino is supportes from apio (fpgawars)
|
||||
|
||||
connect:
|
||||
|
||||
1. ice40-HX1/8K-EVB to olimexino-32u4 (over UEXT)
|
||||
2. olimexino-32u4 (with installed firmware) to PC over USB.
|
||||
|
||||
## olimexino-32u4-firmware
|
||||
|
||||
Firmware to run olimexino-32u4 as programmer/UART bridge.
|
||||
|
||||
#
|
BIN
tools/VMTranslator/VMTranslator.pyc
Executable file
BIN
tools/VMTranslator/VMTranslator.pyc
Executable file
Binary file not shown.
BIN
tools/VMTranslator/codeWriter.pyc
Normal file
BIN
tools/VMTranslator/codeWriter.pyc
Normal file
Binary file not shown.
BIN
tools/VMTranslator/parser.pyc
Normal file
BIN
tools/VMTranslator/parser.pyc
Normal file
Binary file not shown.
17
tools/iceprogduino/Makefile
Normal file
17
tools/iceprogduino/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
CC = gcc
|
||||
CFLAG = -c -Wall
|
||||
EXECUTE = iceprogduino
|
||||
NAME = iceprogduino
|
||||
|
||||
all: $(EXECUTE)
|
||||
|
||||
$(EXECUTE): $(NAME).o
|
||||
$(CC) $(NAME).o -o $(EXECUTE)
|
||||
|
||||
clean:
|
||||
rm -rf *.o $(EXECUTE)
|
||||
|
||||
install:
|
||||
cp $(EXECUTE) /usr/local/bin/$(EXECUTE)
|
||||
|
||||
|
BIN
tools/iceprogduino/iceprogduino
Executable file
BIN
tools/iceprogduino/iceprogduino
Executable file
Binary file not shown.
824
tools/iceprogduino/iceprogduino.c
Normal file
824
tools/iceprogduino/iceprogduino.c
Normal file
@@ -0,0 +1,824 @@
|
||||
/*
|
||||
* iceprogduino -- simple programming tool for FTDI-based Lattice iCE programmers
|
||||
* and Olinuxino based programmers for iCE40HX1K-EVB
|
||||
*
|
||||
* Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
|
||||
* Olimexino Nano edition by Chris B. <chris@protonic.co.uk> @ Olimex Ltd. <c> 2016
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Relevant Documents:
|
||||
* -------------------
|
||||
* http://www.latticesemi.com/~/media/Documents/UserManuals/EI/icestickusermanual.pdf
|
||||
* http://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/n25q/n25q_32mb_3v_65nm.pdf
|
||||
* https://www.olimex.com/ iCE40HX1K-EVB
|
||||
*/
|
||||
|
||||
//#define Olinuxino
|
||||
//#define FTDI
|
||||
#define Nano
|
||||
|
||||
#define READ_ID 0x9F
|
||||
#define PWR_UP 0xAB
|
||||
#define PWR_DOWN 0xB9
|
||||
#define WR_EN 0x06
|
||||
#define BULK_ERASE 0xC7
|
||||
#define SEC_ERASE 0xd8
|
||||
#define PROG 0x02
|
||||
#define READ 0x03
|
||||
#define READY 0x44
|
||||
#define READ_ALL 0x83
|
||||
#define EMPTY 0x45
|
||||
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void serial_read(int x);
|
||||
|
||||
#define FEND 0xc0
|
||||
#define FESC 0xdb
|
||||
#define TFEND 0xdc
|
||||
#define TFESC 0xdd
|
||||
bool newframe;
|
||||
bool timeout;
|
||||
bool escaped;
|
||||
#include <termios.h>
|
||||
#define SerialPort "/dev/ttyACM0"
|
||||
int fd;
|
||||
uint8_t rxframe[512], txframe[512], fcs, tfcs;
|
||||
uint16_t txp,rxp;
|
||||
uint8_t membuf[0x200000];
|
||||
uint8_t pages[0x2000];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool verbose = false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int set_interface_attribs (int fd, int speed, int parity)
|
||||
{
|
||||
struct termios tty;
|
||||
memset (&tty, 0, sizeof tty);
|
||||
if (tcgetattr (fd, &tty) != 0)
|
||||
{
|
||||
fprintf(stderr,"error %d from tcgetattr", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cfsetospeed (&tty, speed);
|
||||
cfsetispeed (&tty, speed);
|
||||
|
||||
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
|
||||
tty.c_iflag &= ~IGNBRK; // disable break processing
|
||||
tty.c_lflag = 0; // no signaling chars, no echo,
|
||||
// no canonical processing
|
||||
tty.c_oflag = 0; // no remapping, no delays
|
||||
tty.c_cc[VMIN] = 0; // read doesn't block
|
||||
tty.c_cc[VTIME] = 0; // no read timeout
|
||||
|
||||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
|
||||
|
||||
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
|
||||
// enable reading
|
||||
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
|
||||
tty.c_cflag |= parity;
|
||||
tty.c_cflag |= parity;
|
||||
tty.c_cflag &= ~CSTOPB;
|
||||
tty.c_cflag &= ~CRTSCTS;
|
||||
|
||||
if (tcsetattr (fd, TCSANOW, &tty) != 0)
|
||||
{
|
||||
fprintf(stderr,"error %d from tcsetattr", errno);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_blocking (int fd, int should_block)
|
||||
{
|
||||
struct termios tty;
|
||||
memset (&tty, 0, sizeof tty);
|
||||
if (tcgetattr (fd, &tty) != 0)
|
||||
{
|
||||
fprintf(stderr,"error %d from tggetattr", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
tty.c_cc[VMIN] = should_block ? 1 : 0;
|
||||
tty.c_cc[VTIME] = 0;
|
||||
|
||||
if (tcsetattr (fd, TCSANOW, &tty) != 0)
|
||||
fprintf(stderr,"error %d setting term attributes", errno);
|
||||
}
|
||||
|
||||
void startframe(uint8_t command){
|
||||
txframe[0]=FEND;
|
||||
txframe[1]=command;
|
||||
tfcs = command;
|
||||
txp = 2;
|
||||
}
|
||||
|
||||
void addbyte(uint8_t newbyte){
|
||||
tfcs+=newbyte;
|
||||
|
||||
switch(newbyte){
|
||||
case FEND:
|
||||
txframe[txp++] = FESC;
|
||||
txframe[txp++] = TFEND;
|
||||
break;
|
||||
case FESC:
|
||||
txframe[txp++] = FESC;
|
||||
txframe[txp++] = TFESC;
|
||||
break;
|
||||
|
||||
default:
|
||||
txframe[txp++] = newbyte;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sendframe(){
|
||||
tfcs=0xff-tfcs;
|
||||
addbyte(tfcs);
|
||||
txframe[txp++] = FEND;
|
||||
#ifdef frdebug
|
||||
printf("%02X-L:%04X/%02X\n",txframe[txp-1],txp,tfcs);
|
||||
#endif
|
||||
if (fd>=0)
|
||||
write(fd,txframe,txp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void error()
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool waitframe(uint8_t cmd)
|
||||
{
|
||||
rxp = 0;
|
||||
newframe = false;
|
||||
fcs = 0;
|
||||
|
||||
uint32_t addr;
|
||||
|
||||
for (uint32_t to=0;to<5000;to++)
|
||||
{
|
||||
serial_read(0);
|
||||
usleep(50);
|
||||
|
||||
if (newframe){
|
||||
// int rxpp = rxp;
|
||||
rxp = 0;
|
||||
newframe = false;
|
||||
usleep(10);
|
||||
|
||||
|
||||
if ((rxframe[0]==READ_ID) && (cmd == READ_ID)){
|
||||
|
||||
if (rxframe[1]==0xef) fprintf(stderr, "Winbond Serial Flash ");
|
||||
else fprintf(stderr, "Manufacturer ID: 0x%02X",rxframe[1]);
|
||||
if ((rxframe[2]==0x40) && (rxframe[3]==0x15)) fprintf(stderr, "- W25Q16BV\n");
|
||||
else fprintf(stderr, " / Device ID: 0x%02X%02X\n",rxframe[2],rxframe[3]);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (rxframe[0]==READ)
|
||||
|
||||
{
|
||||
|
||||
addr = (rxframe[1]<<16) | (rxframe[2]<<8);
|
||||
pages[addr>>8]=0;
|
||||
|
||||
for (int x=3; x < 259;x++)
|
||||
{
|
||||
|
||||
membuf[addr++]=rxframe[x];
|
||||
}
|
||||
}
|
||||
|
||||
if (rxframe[0]==READY) if (cmd==READY) return true; else to = 0;
|
||||
|
||||
if (rxframe[0]==EMPTY) pages[(rxframe[1]<<8) | rxframe[2]]=0;
|
||||
|
||||
if ((rxframe[0]==READ)||(rxframe[0]==EMPTY)) if (cmd==READ) return true; else to = 0;
|
||||
rxframe[0]=0;
|
||||
fcs = 0;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void flash_read_id()
|
||||
{
|
||||
startframe(READ_ID);
|
||||
sendframe();
|
||||
waitframe(READ_ID);
|
||||
return;
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
void flash_bulk_erase()
|
||||
{
|
||||
fprintf(stderr, "\nbulk erase..");
|
||||
|
||||
|
||||
startframe(BULK_ERASE);
|
||||
sendframe();
|
||||
waitframe(BULK_ERASE);
|
||||
fprintf(stderr, "\rbulk erased\n");
|
||||
|
||||
}
|
||||
|
||||
void flash_64kB_sector_erase(int addr)
|
||||
{
|
||||
fprintf(stderr, "erase 64kB sector at 0x%06X..", addr);
|
||||
|
||||
startframe(SEC_ERASE);
|
||||
addbyte(addr>>16);
|
||||
addbyte(addr>>8);
|
||||
sendframe();
|
||||
waitframe(READY);
|
||||
fprintf(stderr, "erased\n");
|
||||
|
||||
}
|
||||
|
||||
void flash_read_all(void){
|
||||
|
||||
fprintf(stderr, "read 0x%06X +0x%06X..\n", 0, 0x200000);
|
||||
memset(&membuf,0xff,sizeof(membuf));
|
||||
memset(&pages,0xff,sizeof(pages));
|
||||
startframe(READ_ALL);
|
||||
sendframe();
|
||||
if (!waitframe(READY))
|
||||
{
|
||||
error();
|
||||
|
||||
}
|
||||
|
||||
fprintf(stderr, "Requesting missmatched frames...");
|
||||
bool notready=false;
|
||||
while (1){
|
||||
notready = false;
|
||||
int s = 0;
|
||||
for(int x = 0; x < 0x2000;x++)
|
||||
{
|
||||
|
||||
if (pages[x]>0){
|
||||
if (s++ > 25)
|
||||
{
|
||||
fprintf(stderr, "ERROR Reading..\n");
|
||||
notready = false;
|
||||
break;
|
||||
}
|
||||
notready=true;
|
||||
fprintf(stderr, ".");
|
||||
startframe(READ);
|
||||
addbyte(x >> 8);
|
||||
addbyte(x >> 0);
|
||||
sendframe();
|
||||
waitframe(READ);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!notready) break;
|
||||
|
||||
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
uint32_t i;
|
||||
if (verbose)
|
||||
for (i = 0; i < 1024; i++)
|
||||
fprintf(stderr, "%02x%c", membuf[i], i == 0 || i % 32 == 31 ? '\n' : ' ');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void help(const char *progname)
|
||||
{
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "iceprog -- simple programming tool for Olinuxino Nano-based Lattice iCE programmers\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Usage: %s [options] <filename>\n", progname);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -e\n");
|
||||
fprintf(stderr, " bulk erase entire flash only\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -w\n");
|
||||
fprintf(stderr, " write only, do not verify\n\n");
|
||||
fprintf(stderr, " -f\n");
|
||||
fprintf(stderr, " write all data, including 0xFF's pages\n\n");
|
||||
fprintf(stderr, " -I<serialport>\n");
|
||||
fprintf(stderr, " port to connect Arduino (default /dev/ttyACM0)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -r\n");
|
||||
fprintf(stderr, " read entire flash (2MB) and write to file\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
|
||||
fprintf(stderr, " -c\n");
|
||||
fprintf(stderr, " do not write flash, only verify (check)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -b\n");
|
||||
fprintf(stderr, " bulk erase entire flash before writing\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -n\n");
|
||||
fprintf(stderr, " do not erase flash before writing\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -o <offset in bytes> start address for write [default: 0]\n");
|
||||
fprintf(stderr, " (append 'k' to the argument for size in kilobytes,\n");
|
||||
fprintf(stderr, " or 'M' for size in megabytes)\n");
|
||||
fprintf(stderr, " this feature works not with all options.\n");
|
||||
fprintf(stderr, " tested with -b, -v\n");
|
||||
fprintf(stderr, " -t\n");
|
||||
fprintf(stderr, " just read the flash ID sequence\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -v\n");
|
||||
fprintf(stderr, " verbose output\n");
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void serial_read(int x)
|
||||
{
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (rxp>512)
|
||||
{
|
||||
newframe = 0;
|
||||
rxp = 0;
|
||||
escaped = false;
|
||||
fcs = 0;
|
||||
break;
|
||||
}
|
||||
usleep(5);
|
||||
uint8_t buf[1];
|
||||
int n;
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
printf(".");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
n=read(fd, buf, 1);
|
||||
if (n==1){
|
||||
|
||||
switch(buf[0]){
|
||||
case FEND:
|
||||
if (fcs==0xff)
|
||||
{
|
||||
newframe = 1;
|
||||
return;
|
||||
}
|
||||
newframe = 0;
|
||||
rxp = 0;
|
||||
escaped = false;
|
||||
fcs = 0;
|
||||
|
||||
break;
|
||||
|
||||
case FESC:
|
||||
escaped = true;
|
||||
break;
|
||||
|
||||
case TFESC:
|
||||
if (escaped)
|
||||
{
|
||||
rxframe[rxp++]=FESC;
|
||||
fcs+=FESC;
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rxframe[rxp++]=TFESC;
|
||||
fcs += TFESC;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TFEND:
|
||||
if (escaped)
|
||||
{
|
||||
rxframe[rxp++]=FEND;
|
||||
fcs += FEND;
|
||||
escaped=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rxframe[rxp++]=TFEND;
|
||||
fcs += TFEND;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
escaped=false;
|
||||
rxframe[rxp++]=buf[0];
|
||||
fcs+=buf[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int addr;
|
||||
int max_read_size = 0x200000;
|
||||
bool read_mode = false;
|
||||
bool check_mode = false;
|
||||
bool bulk_erase = false;
|
||||
bool dont_erase = false;
|
||||
bool prog_sram = false;
|
||||
bool test_mode = false;
|
||||
|
||||
bool noverify = true; // verify performs by arduino board
|
||||
bool ff_mode = false;
|
||||
bool bulk_erase_only = false;
|
||||
const char *filename = NULL;
|
||||
const char *devstr = NULL;
|
||||
int rw_offset = 0;
|
||||
|
||||
int opt;
|
||||
char *endptr;
|
||||
|
||||
|
||||
char *portname = SerialPort;
|
||||
while ((opt = getopt(argc, argv, "I:o:rcbntvwfeh")) != -1)
|
||||
|
||||
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'd':
|
||||
devstr = optarg;
|
||||
break;
|
||||
|
||||
|
||||
case 'I':
|
||||
portname = optarg;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
read_mode = true;
|
||||
noverify=false;
|
||||
break;
|
||||
case 'e':
|
||||
bulk_erase_only = true;
|
||||
break;
|
||||
case 'f':
|
||||
ff_mode = true;
|
||||
break;
|
||||
case 'R':
|
||||
read_mode = true;
|
||||
max_read_size = 256 * 1024;
|
||||
break;
|
||||
case 'c':
|
||||
check_mode = true;
|
||||
noverify=false;
|
||||
break;
|
||||
case 'b':
|
||||
bulk_erase = true;
|
||||
break;
|
||||
case 'n':
|
||||
|
||||
dont_erase = true;
|
||||
break;
|
||||
case 'S':
|
||||
prog_sram = true;
|
||||
break;
|
||||
case 't':
|
||||
test_mode = true;
|
||||
printf("\nTest mode\n");
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'w':
|
||||
noverify = true;
|
||||
break;
|
||||
case 'o': /* set address offset */
|
||||
rw_offset = strtol(optarg, &endptr, 0);
|
||||
if (*endptr == '\0')
|
||||
/* ok */;
|
||||
else if (!strcmp(endptr, "k"))
|
||||
rw_offset *= 1024;
|
||||
else if (!strcmp(endptr, "M"))
|
||||
rw_offset *= 1024 * 1024;
|
||||
else {
|
||||
fprintf(stderr, "'%s' is not a valid offset\n", optarg);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
help(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (read_mode + check_mode + prog_sram + test_mode > 1)
|
||||
help(argv[0]);
|
||||
|
||||
if (bulk_erase && dont_erase)
|
||||
help(argv[0]);
|
||||
|
||||
if (optind+1 != argc && !test_mode && !bulk_erase_only)
|
||||
help(argv[0]);
|
||||
|
||||
filename = argv[optind];
|
||||
|
||||
//bulk_erase = true; // comment this line if you do not want to bulk erase by default
|
||||
|
||||
|
||||
|
||||
|
||||
/* open serial port */
|
||||
fd = open(portname, O_RDWR | O_NOCTTY);
|
||||
// fd = open(portname, O_RDWR | O_ASYNC | O_NDELAY);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr,"error %d opening %s: %s\n", errno, portname, strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_interface_attribs (fd, B57600, 0); // set speed to 57600 bps, 8n1 (no parity)
|
||||
set_blocking (fd, 0); // set no blocking
|
||||
|
||||
|
||||
|
||||
fprintf(stderr,"Serial: %s: %s\n", portname, strerror (errno));
|
||||
|
||||
|
||||
|
||||
|
||||
rxp = 0;
|
||||
|
||||
if (test_mode)
|
||||
{
|
||||
|
||||
|
||||
flash_read_id();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if (prog_sram)
|
||||
{
|
||||
fprintf(stderr, "\nprogramming SRAM is not supported!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Program
|
||||
// ---------------------------------------------------------
|
||||
|
||||
if (!read_mode && !check_mode && !bulk_erase_only)
|
||||
{
|
||||
|
||||
FILE *f = (strcmp(filename, "-") == 0) ? stdin :
|
||||
fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "Error: Can't open '%s' for reading: %s\n", filename, strerror(errno));
|
||||
error();
|
||||
}
|
||||
|
||||
if (!dont_erase)
|
||||
{
|
||||
if (bulk_erase)
|
||||
{
|
||||
|
||||
flash_bulk_erase();
|
||||
sleep(1);
|
||||
flash_read_id();
|
||||
usleep(10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stat st_buf;
|
||||
if (stat(filename, &st_buf)) {
|
||||
fprintf(stderr, "Error: Can't stat '%s': %s\n", filename, strerror(errno));
|
||||
error();
|
||||
}
|
||||
|
||||
fprintf(stderr, "file size: %d\n", (int)st_buf.st_size);
|
||||
/* 64 k */
|
||||
int begin_addr = rw_offset & ~0xffff;
|
||||
int end_addr = (rw_offset + st_buf.st_size + 0xffff) & ~0xffff;
|
||||
for (addr = begin_addr; addr < end_addr; addr += 0x10000) {
|
||||
|
||||
flash_64kB_sector_erase(addr);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "\nprogramming..\n");
|
||||
int ccc;
|
||||
|
||||
flash_read_id();
|
||||
|
||||
|
||||
/* page is 256 */
|
||||
for (int rc, addr = 0; true; addr += rc) {
|
||||
uint8_t buffer[256];
|
||||
int page_size = 256 - (rw_offset + addr) % 256;
|
||||
rc = fread(buffer, 1, page_size, f);
|
||||
|
||||
int offset_addr = addr + rw_offset;
|
||||
if (rc <= 0) break;
|
||||
if (verbose)
|
||||
fprintf(stderr, "prog 0x%06X +0x%03X..\n", offset_addr, rc);
|
||||
else
|
||||
fprintf(stderr, "\rprog 0x%06X +0x%03X..", offset_addr, rc);
|
||||
for (ccc=0;ccc<rc;ccc++){
|
||||
if ((buffer[ccc] != 0xFF) || (ff_mode))
|
||||
{
|
||||
int x;
|
||||
|
||||
|
||||
while(1){
|
||||
|
||||
startframe(PROG);
|
||||
addbyte(offset_addr>>16);
|
||||
addbyte(offset_addr>>8);
|
||||
for (x=0;x<rc;x++)
|
||||
addbyte(buffer[x]);
|
||||
|
||||
sendframe();
|
||||
|
||||
//if (verbose)
|
||||
fprintf(stderr, ".");
|
||||
|
||||
//usleep(1000);
|
||||
if (waitframe(READY)) break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
|
||||
if (f != stdin)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if (!noverify && !bulk_erase_only)
|
||||
{
|
||||
// ---------------------------------------------------------
|
||||
// Read/Verify
|
||||
// ---------------------------------------------------------
|
||||
|
||||
if (read_mode)
|
||||
{
|
||||
FILE *f = (strcmp(filename, "-") == 0) ? stdout :
|
||||
fopen(filename, "w");
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "Error: Can't open '%s' for writing: %s\n", filename, strerror(errno));
|
||||
error();
|
||||
}
|
||||
|
||||
fprintf(stderr, "\nreading..\n");
|
||||
|
||||
|
||||
|
||||
flash_read_id();
|
||||
flash_read_all();
|
||||
printf("\nWriting data to file %s\n",filename);
|
||||
fwrite(membuf, 0x200000, 1, f);
|
||||
|
||||
if (f != stdout)
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *f = (strcmp(filename, "-") == 0) ? stdin :
|
||||
fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "Error: Can't open '%s' for reading: %s\n", filename, strerror(errno));
|
||||
error();
|
||||
}
|
||||
|
||||
fprintf(stderr, "\nreading..\n");
|
||||
|
||||
flash_read_id();
|
||||
flash_read_all();
|
||||
uint8_t buffer_file[0x200000];
|
||||
int rc = fread(buffer_file, 1, 0x200000, f);
|
||||
|
||||
if (memcmp(buffer_file, membuf, rc))
|
||||
{
|
||||
fprintf(stderr, "Found difference between flash and file!\n");
|
||||
error();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fprintf(stderr, "\nVERIFY OK\n");
|
||||
|
||||
if (f != stdin)
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
if (bulk_erase_only)
|
||||
{
|
||||
|
||||
|
||||
flash_bulk_erase();
|
||||
|
||||
fprintf(stderr, "Flash erased!\n");
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
// Reset
|
||||
// ---------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Exit
|
||||
// ---------------------------------------------------------
|
||||
|
||||
fprintf(stderr, "Bye.\n");
|
||||
|
||||
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
BIN
tools/iceprogduino/iceprogduino.o
Normal file
BIN
tools/iceprogduino/iceprogduino.o
Normal file
Binary file not shown.
43
tools/jack.vim
Normal file
43
tools/jack.vim
Normal file
@@ -0,0 +1,43 @@
|
||||
" Vim syntax file
|
||||
setlocal iskeyword+=:
|
||||
" Language: Jack
|
||||
" Maintainer: Michael Schroeder
|
||||
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
setlocal iskeyword+=-
|
||||
setlocal iskeyword+=?
|
||||
setlocal iskeyword+=!
|
||||
|
||||
set tabstop=4
|
||||
|
||||
let b:current_syntax = "jack"
|
||||
|
||||
syn keyword jackTodo class method constructor function
|
||||
syn region jackComment start="\/\*" end="\*\/"
|
||||
syn region jackComment start="\/\/" end="\n"
|
||||
syn keyword jackConstant null
|
||||
syn keyword jackBoolean true false
|
||||
syn region jackString start=+"+ end=+"+ skip=+\\\\\|\\"+ contains=jackSpecial,@Spell
|
||||
syn match jackNumber "\<0\>"
|
||||
syn match jackNumber "\<[1-9][0-9]*\>"
|
||||
syn keyword jackType void int boolean String char Array
|
||||
syn keyword jackConditional if else
|
||||
syn keyword jackRepeat while
|
||||
syn keyword jackKeyword var field static
|
||||
syn keyword jackFunction return let do
|
||||
|
||||
|
||||
highlight link jackTodo Todo
|
||||
highlight link jackComment Comment
|
||||
highlight link jackConstant Constant
|
||||
highlight link jackBoolean Boolean
|
||||
highlight link jackString String
|
||||
highlight link jackNumber Number
|
||||
highlight link jackType Type
|
||||
highlight link jackConditional Conditional
|
||||
highlight link jackRepeat Repeat
|
||||
highlight link jackKeyword Keyword
|
||||
highlight link jackFunction Function
|
26
tools/olimexino-32u4 firmware/README.md
Normal file
26
tools/olimexino-32u4 firmware/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
This firmware has to be uploaded to OLIMEXINO-32u4 in order to use it as an iCE40 programmer.
|
||||
|
||||
|
||||
### Using Arduino IDE ###
|
||||
|
||||
This firmware can be uploaded via Arduino IDE. Just go to iceprog folder and load iceprog.ino.
|
||||
|
||||
We used SPIFlash 2.2.0 library for Winbond Flash Memory by Prajwal Bhattaram - Marzogh (the
|
||||
project is now called "SPIMemory". The files we used are already inside the project, no need to
|
||||
install it separately. But our advice is to the check the full project. It is availalbe here:
|
||||
|
||||
https://github.com/Marzogh/SPIMemory/tree/v2.2.0
|
||||
|
||||
|
||||
### Using PlatformIO ###
|
||||
|
||||
Install PlatformIO, use this guide for details http://docs.platformio.org/en/stable/installation.html
|
||||
|
||||
Build & Upload:
|
||||
|
||||
platformio run
|
||||
platformio run --target upload
|
||||
|
||||
Alternatively you can use SPI programmer to burn firmware into OLIMEXINO-32u4, e.g.:
|
||||
|
||||
avrdude -p atmega32u4 -P /dev/ttyUSB0 -c buspirate -b115200 -D -Uflash:w:[.pioenvs/leonardo/firmware.hex]:i
|
1961
tools/olimexino-32u4 firmware/iceprog-nano/SPIFlash.cpp
Normal file
1961
tools/olimexino-32u4 firmware/iceprog-nano/SPIFlash.cpp
Normal file
File diff suppressed because it is too large
Load Diff
267
tools/olimexino-32u4 firmware/iceprog-nano/SPIFlash.h
Normal file
267
tools/olimexino-32u4 firmware/iceprog-nano/SPIFlash.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/* Arduino SPIFlash Library v.2.2.0
|
||||
* Copyright (C) 2015 by Prajwal Bhattaram
|
||||
* Modified by Prajwal Bhattaram - 24/11/2015
|
||||
*
|
||||
* This file is part of the Arduino SPIFlash Library. This library is for
|
||||
* Winbond NOR flash memory modules. In its current form it enables reading
|
||||
* and writing individual data variables, structs and arrays from and to various locations;
|
||||
* reading and writing pages; continuous read functions; sector, block and chip erase;
|
||||
* suspending and resuming programming/erase and powering down for low power operation.
|
||||
*
|
||||
* This Library 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This Library 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 v3.0
|
||||
* along with the Arduino SPIFlash Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SPIFLASH_H
|
||||
#define SPIFLASH_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class SPIFlash {
|
||||
public:
|
||||
//----------------------------------------------Constructor-----------------------------------------------//
|
||||
SPIFlash(uint8_t cs = 10, bool overflow = true);
|
||||
//----------------------------------------Initial / Chip Functions----------------------------------------//
|
||||
void begin();
|
||||
uint16_t getManID();
|
||||
uint32_t getJEDECID();
|
||||
bool getAddress(uint16_t size, uint16_t &page_number, uint8_t &offset);
|
||||
uint32_t getAddress(uint16_t size);
|
||||
uint16_t getChipName();
|
||||
uint16_t sizeofStr(String &inputStr);
|
||||
uint32_t getCapacity();
|
||||
uint32_t getMaxPage();
|
||||
//-------------------------------------------Write / Read Bytes-------------------------------------------//
|
||||
bool writeByte(uint32_t address, uint8_t data, bool errorCheck = true);
|
||||
bool writeByte(uint16_t page_number, uint8_t offset, uint8_t data, bool errorCheck = true);
|
||||
uint8_t readByte(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
uint8_t readByte(uint32_t address, bool fastRead = false);
|
||||
//----------------------------------------Write / Read Byte Arrays----------------------------------------//
|
||||
bool writeByteArray(uint32_t address, uint8_t *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
bool writeByteArray(uint16_t page_number, uint8_t offset, uint8_t *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
uint8_t readByteArray(uint32_t address, uint8_t *data_buffer, uint16_t bufferSize, bool fastRead = false);
|
||||
uint8_t readByteArray(uint16_t page_number, uint8_t offset, uint8_t *data_buffer, uint16_t bufferSize, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Chars-------------------------------------------//
|
||||
bool writeChar(uint32_t address, int8_t data, bool errorCheck = true);
|
||||
bool writeChar(uint16_t page_number, uint8_t offset, int8_t data, bool errorCheck = true);
|
||||
int8_t readChar(uint32_t address, bool fastRead = false);
|
||||
int8_t readChar(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//----------------------------------------Write / Read Char Arrays----------------------------------------//
|
||||
bool writeCharArray(uint32_t address, char *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
bool writeCharArray(uint16_t page_number, uint8_t offset, char *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
uint8_t readCharArray(uint32_t address, char *data_buffer, uint16_t buffer_size, bool fastRead = false);
|
||||
uint8_t readCharArray(uint16_t page_number, uint8_t offset, char *data_buffer, uint16_t buffer_size, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Shorts------------------------------------------//
|
||||
bool writeShort(uint32_t address, int16_t data, bool errorCheck = true);
|
||||
bool writeShort(uint16_t page_number, uint8_t offset, int16_t data, bool errorCheck = true);
|
||||
int16_t readShort(uint32_t address, bool fastRead = false);
|
||||
int16_t readShort(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Words-------------------------------------------//
|
||||
bool writeWord(uint32_t address, uint16_t data, bool errorCheck = true);
|
||||
bool writeWord(uint16_t page_number, uint8_t offset, uint16_t data, bool errorCheck = true);
|
||||
uint16_t readWord(uint32_t address, bool fastRead = false);
|
||||
uint16_t readWord(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Longs-------------------------------------------//
|
||||
bool writeLong(uint32_t address, int32_t data, bool errorCheck = true);
|
||||
bool writeLong(uint16_t page_number, uint8_t offset, int32_t data, bool errorCheck = true);
|
||||
int32_t readLong(uint32_t address, bool fastRead = false);
|
||||
int32_t readLong(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//--------------------------------------Write / Read Unsigned Longs---------------------------------------//
|
||||
bool writeULong(uint32_t address, uint32_t data, bool errorCheck = true);
|
||||
bool writeULong(uint16_t page_number, uint8_t offset, uint32_t data, bool errorCheck = true);
|
||||
uint32_t readULong(uint32_t address, bool fastRead = false);
|
||||
uint32_t readULong(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Floats------------------------------------------//
|
||||
bool writeFloat(uint32_t address, float data, bool errorCheck = true);
|
||||
bool writeFloat(uint16_t page_number, uint8_t offset, float data, bool errorCheck = true);
|
||||
float readFloat(uint32_t address, bool fastRead = false);
|
||||
float readFloat(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Strings------------------------------------------//
|
||||
bool writeStr(uint32_t address, String &inputStr, bool errorCheck = true);
|
||||
bool writeStr(uint16_t page_number, uint8_t offset, String &inputStr, bool errorCheck = true);
|
||||
bool readStr(uint32_t address, String &outStr, bool fastRead = false);
|
||||
bool readStr(uint16_t page_number, uint8_t offset, String &outStr, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Pages-------------------------------------------//
|
||||
bool writePage(uint16_t page_number, uint8_t *data_buffer, bool errorCheck = true);
|
||||
bool readPage(uint16_t page_number, uint8_t *data_buffer, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Anything-----------------------------------------//
|
||||
template <class T> bool writeAnything(uint32_t address, const T& value, bool errorCheck = true);
|
||||
template <class T> bool writeAnything(uint16_t page_number, uint8_t offset, const T& value, bool errorCheck = true);
|
||||
template <class T> bool readAnything(uint32_t address, T& value, bool fastRead = false);
|
||||
template <class T> bool readAnything(uint16_t page_number, uint8_t offset, T& value, bool fastRead = false);
|
||||
//--------------------------------------------Erase functions---------------------------------------------//
|
||||
bool eraseSector(uint32_t address);
|
||||
bool eraseSector(uint16_t page_number, uint8_t offset);
|
||||
bool eraseBlock32K(uint32_t address);
|
||||
bool eraseBlock32K(uint16_t page_number, uint8_t offset);
|
||||
bool eraseBlock64K(uint32_t address);
|
||||
bool eraseBlock64K(uint16_t page_number, uint8_t offset);
|
||||
bool eraseChip(void);
|
||||
//---------------------------------------------Power functions--------------------------------------------//
|
||||
bool suspendProg(void);
|
||||
bool resumeProg(void);
|
||||
bool powerDown(void);
|
||||
bool powerUp(void);
|
||||
//--------------------------------------------Private functions-------------------------------------------//
|
||||
private:
|
||||
void _troubleshoot(uint8_t error);
|
||||
void _cmd(uint8_t cmd, bool _continue = true, uint8_t cs = 0);
|
||||
void _endProcess(void);
|
||||
void _errorCodeCheck(void);
|
||||
void _beginRead(uint32_t address);
|
||||
void _beginFastRead(uint32_t address);
|
||||
bool _noSuspend(void);
|
||||
bool _notBusy(uint32_t timeout = 10L);
|
||||
bool _notPrevWritten(uint32_t address, uint8_t size = 1);
|
||||
bool _addressCheck(uint32_t address);
|
||||
bool _beginWrite(uint32_t address);
|
||||
bool _writeNextByte(uint8_t c, bool _continue = true);
|
||||
bool _writeEnable(void);
|
||||
bool _writeDisable(void);
|
||||
bool _getJedecId(uint8_t *b1, uint8_t *b2, uint8_t *b3);
|
||||
bool _getManId(uint8_t *b1, uint8_t *b2);
|
||||
bool _chipID(void);
|
||||
uint8_t _readStat1(void);
|
||||
uint8_t _readNextByte(bool _continue = true);
|
||||
uint32_t _getAddress(uint16_t page_number, uint8_t offset = 0);
|
||||
uint32_t _prepRead(uint32_t address);
|
||||
uint32_t _prepRead(uint16_t page_number, uint8_t offset = 0);
|
||||
uint32_t _prepWrite(uint32_t address);
|
||||
uint32_t _prepWrite(uint16_t page_number, uint8_t offset = 0);
|
||||
template <class T> bool _writeErrorCheck(uint32_t address, const T& value);
|
||||
//-------------------------------------------Private variables------------------------------------------//
|
||||
bool pageOverflow;
|
||||
volatile uint8_t *cs_port;
|
||||
uint8_t cs_mask, csPin, errorcode;
|
||||
uint16_t name;
|
||||
uint32_t capacity, maxPage;
|
||||
uint32_t currentAddress = 1;
|
||||
const uint8_t devType[10] = {0x5, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
|
||||
const uint32_t memSize[10] = {64L * 1024L, 128L * 1024L, 256L * 1024L, 512L * 1024L, 1L * 1024L * 1024L,
|
||||
2L * 1024L * 1024L, 4L * 1024L * 1024L, 8L * 1024L * 1024L, 16L * 1024L * 1024L};
|
||||
const uint16_t chipName[10] = {05, 10, 20, 40, 80, 16, 32, 64, 128, 256};
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------Templates-------------------------------------------//
|
||||
|
||||
// Writes any type of data to a specific location in the flash memory.
|
||||
// Has two variants:
|
||||
// A. Takes two arguments -
|
||||
// 1. address --> Any address from 0 to maxAddress
|
||||
// 2. T& value --> Variable to return data into
|
||||
// 4. errorCheck --> Turned on by default. Checks for writing errors
|
||||
// B. Takes three arguments -
|
||||
// 1. page --> Any page number from 0 to maxPage
|
||||
// 2. offset --> Any offset within the page - from 0 to 255
|
||||
// 3. const T& value --> Variable with the data to be written
|
||||
// 4. errorCheck --> Turned on by default. Checks for writing errors
|
||||
// WARNING: You can only write to previously erased memory locations (see datasheet).
|
||||
// Use the eraseSector()/eraseBlock32K/eraseBlock64K commands to first clear memory (write 0xFFs)
|
||||
// Variant A
|
||||
template <class T> bool SPIFlash::writeAnything(uint32_t address, const T& value, bool errorCheck) {
|
||||
if (!_prepWrite(address))
|
||||
return false;
|
||||
else {
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
_beginWrite(address);
|
||||
for (uint16_t i = 0; i < sizeof(value); i++) {
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1)
|
||||
_writeNextByte(*p++, false);
|
||||
#endif
|
||||
_writeNextByte(*p++);
|
||||
}
|
||||
_endProcess();
|
||||
}
|
||||
|
||||
if (!errorCheck)
|
||||
return true;
|
||||
else
|
||||
return _writeErrorCheck(address, value);
|
||||
}
|
||||
// Variant B
|
||||
template <class T> bool SPIFlash::writeAnything(uint16_t page_number, uint8_t offset, const T& value, bool errorCheck) {
|
||||
uint32_t address = _getAddress(page_number, offset);
|
||||
return writeAnything(address, value, errorCheck);
|
||||
}
|
||||
|
||||
// Reads any type of data from a specific location in the flash memory.
|
||||
// Has two variants:
|
||||
// A. Takes two arguments -
|
||||
// 1. address --> Any address from 0 to maxAddress
|
||||
// 2. T& value --> Variable to return data into
|
||||
// 2. fastRead --> defaults to false - executes _beginFastRead() if set to true
|
||||
// B. Takes three arguments -
|
||||
// 1. page --> Any page number from 0 to maxPage
|
||||
// 2. offset --> Any offset within the page - from 0 to 255
|
||||
// 3. T& value --> Variable to return data into
|
||||
// 3. fastRead --> defaults to false - executes _beginFastRead() if set to true
|
||||
// Variant A
|
||||
template <class T> bool SPIFlash::readAnything(uint32_t address, T& value, bool fastRead) {
|
||||
if (!_prepRead(address))
|
||||
return false;
|
||||
|
||||
byte* p = (byte*)(void*)&value;
|
||||
if(!fastRead)
|
||||
_beginRead(address);
|
||||
else
|
||||
_beginFastRead(address);
|
||||
for (uint16_t i = 0; i < sizeof(value); i++) {
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1)
|
||||
*p++ = _readNextByte(false);
|
||||
#endif
|
||||
*p++ =_readNextByte();
|
||||
}
|
||||
_endProcess();
|
||||
return true;
|
||||
}
|
||||
// Variant B
|
||||
template <class T> bool SPIFlash::readAnything(uint16_t page_number, uint8_t offset, T& value, bool fastRead)
|
||||
{
|
||||
uint32_t address = _getAddress(page_number, offset);
|
||||
return readAnything(address, value, fastRead);
|
||||
}
|
||||
|
||||
// Private template to check for errors in writing to flash memory
|
||||
template <class T> bool SPIFlash::_writeErrorCheck(uint32_t address, const T& value) {
|
||||
if (!_prepRead(address))
|
||||
return false;
|
||||
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
_beginRead(address);
|
||||
for(uint16_t i = 0; i < sizeof(value);i++)
|
||||
{
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1) {
|
||||
if (*p++ != _readNextByte(false))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (*p++ != _readNextByte())
|
||||
return false;
|
||||
#elif defined (__AVR__)
|
||||
if (*p++ != _readNextByte())
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
_endProcess();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif // _SPIFLASH_H_
|
399
tools/olimexino-32u4 firmware/iceprog-nano/iceprog-nano.ino
Normal file
399
tools/olimexino-32u4 firmware/iceprog-nano/iceprog-nano.ino
Normal file
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
* iceprog -- firmware scetch for Arduino based Lattice iCE programmers
|
||||
*
|
||||
* Chris B. <chris@protonic.co.uk> @ Olimex Ltd. <c> 2017
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Relevant Documents:
|
||||
* -------------------
|
||||
* http://www.latticesemi.com/~/media/Documents/UserManuals/EI/icestickusermanual.pdf
|
||||
* http://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/n25q/n25q_32mb_3v_65nm.pdf
|
||||
* http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf
|
||||
* https://www.olimex.com/Products/FPGA/iCE40/iCE40HX1K-EVB/
|
||||
* https://github.com/Marzogh/SPIFlash
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
// The demo uses SPIFlash v2.2.0, its files are included in the project folders the author is Prajwal Bhattaram - Marzogh
|
||||
|
||||
#include "SPIFlash.h"
|
||||
|
||||
#define LED 17
|
||||
#define CDONE 3
|
||||
#define RESET 2
|
||||
#define UEXT_POWER 8
|
||||
#define CS 13
|
||||
|
||||
//commands list
|
||||
#define READ_ID 0x9F
|
||||
#define PWR_UP 0xAB
|
||||
#define PWR_DOWN 0xB9
|
||||
#define WR_EN 0x06
|
||||
#define BULK_ERASE 0xC7
|
||||
#define SEC_ERASE 0xd8
|
||||
#define PROG 0x02
|
||||
#define READ 0x03
|
||||
#define READ_ALL 0x83
|
||||
#define CMD_ERROR 0xee
|
||||
#define READY 0x44
|
||||
#define EMPTY 0x45
|
||||
|
||||
#define FEND 0xc0
|
||||
#define FESC 0xdb
|
||||
#define TFEND 0xdc
|
||||
#define TFESC 0xdd
|
||||
|
||||
#define cselect digitalWrite(CS,LOW)
|
||||
#define deselect digitalWrite(CS,HIGH)
|
||||
|
||||
//Toggle iceprogduino with serial bridge by pressing the HWB button
|
||||
#define HWB (PINE & B00000100)==0 // Check if the button has been pressed
|
||||
#define HWB_INPUT DDRE &= B11111011 // Initialize the port
|
||||
#define HWB_PULL_UP PORTE |= B00000100 // Initialize the port
|
||||
|
||||
boolean isProg;
|
||||
|
||||
uint8_t rxframe[512], txframe[512], fcs,rfcs;
|
||||
uint8_t membuf[256];
|
||||
uint8_t data_buffer[256];
|
||||
uint16_t txp;
|
||||
uint32_t maxPage;
|
||||
bool escaped;
|
||||
SPIFlash flash(CS);
|
||||
|
||||
void secerase(uint32_t sector);
|
||||
void decodeFrame(void);
|
||||
void writepage(int pagenr);
|
||||
bool readSerialFrame(void);
|
||||
void flash_bulk_erase(void);
|
||||
void SendID(void);
|
||||
void sendframe();
|
||||
void startframe(uint8_t command);
|
||||
void addbyte(uint8_t newbyte);
|
||||
void readAllPages(void);
|
||||
void readpage(uint16_t adr);
|
||||
|
||||
// FRAME: <FEND><CMD>{data if any}<FCS(sume of all bytes = 0xFF)><FEND>
|
||||
// if FEND, FESC in data - <FEND>=<FESC><TFEND>; <FESC>=<FESC><TFESC>
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
// Power Up UEXT
|
||||
pinMode(CDONE,INPUT);
|
||||
pinMode(RESET,OUTPUT);
|
||||
pinMode(LED,OUTPUT);
|
||||
digitalWrite(LED,0);
|
||||
pinMode(CS,OUTPUT);
|
||||
digitalWrite(CS,HIGH);
|
||||
pinMode(UEXT_POWER, OUTPUT);
|
||||
digitalWrite(UEXT_POWER, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(UEXT_POWER, LOW);
|
||||
delay(500);
|
||||
digitalWrite(RESET, HIGH);
|
||||
Serial.begin(230400);
|
||||
while (!Serial);
|
||||
|
||||
isProg=true;
|
||||
HWB_INPUT; // Initialize HWB
|
||||
HWB_PULL_UP;
|
||||
Serial1.begin(115200);
|
||||
digitalWrite(LED,!isProg); //Yellow LED is Prog
|
||||
}
|
||||
|
||||
void loop(){
|
||||
if (isProg) loopProg();
|
||||
else loopBridge();
|
||||
if (HWB) {
|
||||
isProg = !isProg;
|
||||
digitalWrite(LED,!isProg);
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void loopBridge(){
|
||||
// read from port 1, send to port 0:
|
||||
if (Serial1.available()) {
|
||||
int inByte = Serial1.read();
|
||||
Serial.write(inByte);
|
||||
}
|
||||
|
||||
// read from port 0, send to port 1:
|
||||
if (Serial.available()) {
|
||||
int inByte = Serial.read();
|
||||
Serial1.write(inByte);
|
||||
}
|
||||
}
|
||||
|
||||
void loopProg() {
|
||||
|
||||
if (readSerialFrame())
|
||||
{
|
||||
decodeFrame();
|
||||
if (rfcs==0xff)
|
||||
{
|
||||
digitalWrite(RESET, LOW);
|
||||
|
||||
switch (rxframe[0]){
|
||||
|
||||
case FEND:
|
||||
break;
|
||||
|
||||
case READ_ID:
|
||||
SendID();
|
||||
break;
|
||||
|
||||
case BULK_ERASE:
|
||||
flash_bulk_erase();
|
||||
break;
|
||||
|
||||
case SEC_ERASE:
|
||||
flash.powerUp();
|
||||
secerase((rxframe[1]<<8) | rxframe[2]);
|
||||
flash.powerDown();
|
||||
|
||||
break;
|
||||
|
||||
case READ:
|
||||
flash.powerUp();
|
||||
readpage((rxframe[1]<<8) | rxframe[2]);
|
||||
flash.powerDown();
|
||||
break;
|
||||
|
||||
case READ_ALL:
|
||||
readAllPages();
|
||||
break;
|
||||
|
||||
case PROG:
|
||||
writepage((rxframe[1]<<8) | rxframe[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}//switch
|
||||
digitalWrite(RESET, HIGH);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void secerase(uint32_t sector){
|
||||
flash.eraseBlock64K(sector<<8);
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
|
||||
}
|
||||
void decodeFrame(void){
|
||||
int x,y;
|
||||
escaped = false;
|
||||
y = 1;
|
||||
rfcs = rxframe[1];
|
||||
rxframe[0]=rxframe[1];
|
||||
for (x=2;x<512;x++)
|
||||
{
|
||||
switch (rxframe[x]){
|
||||
|
||||
case FEND:
|
||||
x = 513;
|
||||
break;
|
||||
|
||||
case FESC:
|
||||
escaped = true;
|
||||
break;
|
||||
|
||||
case TFEND:
|
||||
if (escaped)
|
||||
{
|
||||
rxframe[y++] = FEND;
|
||||
rfcs+=FEND;
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rxframe[y++]=TFEND;
|
||||
rfcs+=TFEND;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TFESC:
|
||||
if (escaped)
|
||||
{
|
||||
rxframe[y++]=FESC;
|
||||
rfcs+=FESC;
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rxframe[y++]=TFESC;
|
||||
rfcs+=TFESC;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
escaped = false;
|
||||
rxframe[y++] = rxframe[x];
|
||||
rfcs+=rxframe[x];
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void writepage(int pagenr){
|
||||
int x;
|
||||
flash.powerUp();
|
||||
|
||||
for (x=0; x<256;x++)
|
||||
membuf[x]=rxframe[x+3];
|
||||
|
||||
flash.writePage(pagenr,membuf);
|
||||
flash.readPage(pagenr,data_buffer);
|
||||
flash.powerDown();
|
||||
|
||||
for (int a = 0; a < 256; a++)
|
||||
if (data_buffer[a] != membuf[a])
|
||||
return;
|
||||
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Reads a frame from Serial
|
||||
bool readSerialFrame(void)
|
||||
{
|
||||
Serial.setTimeout(50);
|
||||
|
||||
if (!Serial)
|
||||
Serial.begin(230400);
|
||||
// Serial.begin(1000000);
|
||||
while (Serial.available()) {
|
||||
Serial.readBytesUntil(FEND,rxframe,512);
|
||||
//if (rxframe[0]!=FEND)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void flash_bulk_erase(void)
|
||||
{
|
||||
flash.powerUp();
|
||||
flash.eraseChip();
|
||||
flash.powerDown();
|
||||
startframe(READY);
|
||||
addbyte(BULK_ERASE);
|
||||
sendframe();
|
||||
}
|
||||
|
||||
void SendID(void)
|
||||
{
|
||||
|
||||
flash.powerUp();
|
||||
uint32_t JEDEC = flash.getJEDECID();
|
||||
flash.powerDown();
|
||||
startframe(READ_ID);
|
||||
addbyte(JEDEC >> 16);
|
||||
addbyte(JEDEC >> 8);
|
||||
addbyte(JEDEC >> 0);
|
||||
sendframe();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sendframe(){
|
||||
fcs = 0xff - fcs;
|
||||
addbyte(fcs);
|
||||
txframe[txp++] = FEND;
|
||||
Serial.write(txframe,txp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void startframe(uint8_t command){
|
||||
txframe[0]=FEND;
|
||||
txframe[1]=command;
|
||||
txp = 2;
|
||||
fcs = command;
|
||||
}
|
||||
void addbyte(uint8_t newbyte)
|
||||
{
|
||||
fcs+=newbyte;
|
||||
if (newbyte == FEND)
|
||||
{
|
||||
txframe[txp++] = FESC;
|
||||
txframe[txp++] = TFEND;
|
||||
} else
|
||||
if (newbyte == FESC)
|
||||
{
|
||||
txframe[txp++] = FESC;
|
||||
txframe[txp++] = TFESC;
|
||||
} else
|
||||
txframe[txp++] = newbyte;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void readAllPages(void){
|
||||
flash.powerUp();
|
||||
maxPage=0x2000;
|
||||
delay(10);
|
||||
int p;
|
||||
for (p=0;p<maxPage;p++)
|
||||
readpage(p);
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
//
|
||||
flash.powerDown();
|
||||
}
|
||||
|
||||
|
||||
void readpage(uint16_t adr){
|
||||
|
||||
bool sendempty = true;
|
||||
//delay(5);
|
||||
|
||||
flash.readPage(adr,data_buffer);
|
||||
|
||||
for (int a = 0; a < 256; a++){
|
||||
if (data_buffer[a] != 0xff){
|
||||
startframe(READ);
|
||||
addbyte(adr >> 8);
|
||||
addbyte(adr >> 0);
|
||||
for (int b = 0;b<256;b++)
|
||||
addbyte(data_buffer[b]);
|
||||
sendframe();
|
||||
sendempty=false;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (sendempty){
|
||||
startframe(EMPTY);
|
||||
addbyte(adr >> 8);
|
||||
addbyte(adr >> 0);
|
||||
sendframe();
|
||||
}
|
||||
}
|
406
tools/olimexino-32u4 firmware/iceprog.ino
Normal file
406
tools/olimexino-32u4 firmware/iceprog.ino
Normal file
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* iceprog -- firmware scetch for Arduino based Lattice iCE programmers
|
||||
*
|
||||
* Chris B. <chris@protonic.co.uk> @ Olimex Ltd. <c> 2017
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Relevant Documents:
|
||||
* -------------------
|
||||
* http://www.latticesemi.com/~/media/Documents/UserManuals/EI/icestickusermanual.pdf
|
||||
* http://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/n25q/n25q_32mb_3v_65nm.pdf
|
||||
* http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf
|
||||
* https://www.olimex.com/Products/FPGA/iCE40/iCE40HX1K-EVB/
|
||||
* https://github.com/Marzogh/SPIFlash
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
// The demo uses SPIFlash v2.2.0, its files are included in the project folders the author is Prajwal Bhattaram - Marzogh
|
||||
|
||||
#include "SPIFlash.h"
|
||||
|
||||
#define LED 17
|
||||
#define CDONE 3
|
||||
#define RESET 2
|
||||
#define UEXT_POWER 8
|
||||
#define CS 13
|
||||
|
||||
//commands list
|
||||
#define READ_ID 0x9F
|
||||
#define PWR_UP 0xAB
|
||||
#define PWR_DOWN 0xB9
|
||||
#define WR_EN 0x06
|
||||
#define BULK_ERASE 0xC7
|
||||
#define SEC_ERASE 0xd8
|
||||
#define PROG 0x02
|
||||
#define READ 0x03
|
||||
#define READ_ALL 0x83
|
||||
#define CMD_ERROR 0xee
|
||||
#define READY 0x44
|
||||
#define EMPTY 0x45
|
||||
|
||||
#define FEND 0xc0
|
||||
#define FESC 0xdb
|
||||
#define TFEND 0xdc
|
||||
#define TFESC 0xdd
|
||||
|
||||
#define cselect digitalWrite(CS,LOW)
|
||||
#define deselect digitalWrite(CS,HIGH)
|
||||
|
||||
//Toggle iceprogduino with serial bridge by pressing the HWB button
|
||||
#define HWB (PINE & B00000100)==0 // Check if the button has been pressed
|
||||
#define HWB_INPUT DDRE &= B11111011 // Initialize the port
|
||||
#define LED_G 7 // The GREEN LED is on Pin 7
|
||||
#define LED_Y 9 // The YELLOW LED is on Pin 9
|
||||
boolean isProg;
|
||||
|
||||
uint8_t rxframe[512], txframe[512], fcs,rfcs;
|
||||
uint8_t membuf[256];
|
||||
uint8_t data_buffer[256];
|
||||
uint16_t txp;
|
||||
uint32_t maxPage;
|
||||
bool escaped;
|
||||
SPIFlash flash(CS);
|
||||
|
||||
void secerase(uint32_t sector);
|
||||
void decodeFrame(void);
|
||||
void writepage(int pagenr);
|
||||
bool readSerialFrame(void);
|
||||
void flash_bulk_erase(void);
|
||||
void SendID(void);
|
||||
void sendframe();
|
||||
void startframe(uint8_t command);
|
||||
void addbyte(uint8_t newbyte);
|
||||
void readAllPages(void);
|
||||
void readpage(uint16_t adr);
|
||||
void loopProg(void);
|
||||
void loopBridge(void);
|
||||
|
||||
|
||||
// FRAME: <FEND><CMD>{data if any}<FCS(sume of all bytes = 0xFF)><FEND>
|
||||
// if FEND, FESC in data - <FEND>=<FESC><TFEND>; <FESC>=<FESC><TFESC>
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
// Power Up UEXT
|
||||
pinMode(CDONE,INPUT);
|
||||
pinMode(RESET,OUTPUT);
|
||||
pinMode(LED,OUTPUT);
|
||||
digitalWrite(LED,0);
|
||||
pinMode(CS,OUTPUT);
|
||||
digitalWrite(CS,HIGH);
|
||||
pinMode(UEXT_POWER, OUTPUT);
|
||||
digitalWrite(UEXT_POWER, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(UEXT_POWER, LOW);
|
||||
delay(500);
|
||||
digitalWrite(RESET, HIGH);
|
||||
Serial.begin(230400);
|
||||
while (!Serial);
|
||||
|
||||
isProg=true;
|
||||
HWB_INPUT; // Initialize HWB
|
||||
Serial1.begin(115200);
|
||||
pinMode(LED_Y,OUTPUT);
|
||||
digitalWrite(LED_Y,isProg); //Yellow LED is Prog
|
||||
pinMode(LED_G,OUTPUT);
|
||||
digitalWrite(LED_G,!isProg); //Green LED is Bridge
|
||||
|
||||
}
|
||||
|
||||
void loop(){
|
||||
if (isProg) loopProg();
|
||||
else loopBridge();
|
||||
if (HWB) {
|
||||
isProg = !isProg;
|
||||
digitalWrite(LED_Y,isProg);
|
||||
digitalWrite(LED_G,!isProg);
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void loopBridge(){
|
||||
// read from port 1, send to port 0:
|
||||
if (Serial1.available()) {
|
||||
int inByte = Serial1.read();
|
||||
Serial.write(inByte);
|
||||
}
|
||||
|
||||
// read from port 0, send to port 1:
|
||||
if (Serial.available()) {
|
||||
int inByte = Serial.read();
|
||||
Serial1.write(inByte);
|
||||
}
|
||||
}
|
||||
|
||||
void loopProg() {
|
||||
|
||||
if (readSerialFrame())
|
||||
{
|
||||
decodeFrame();
|
||||
if (rfcs==0xff)
|
||||
{
|
||||
digitalWrite(RESET, LOW);
|
||||
|
||||
switch (rxframe[0]){
|
||||
|
||||
case FEND:
|
||||
break;
|
||||
|
||||
case READ_ID:
|
||||
SendID();
|
||||
break;
|
||||
|
||||
case BULK_ERASE:
|
||||
flash_bulk_erase();
|
||||
break;
|
||||
|
||||
case SEC_ERASE:
|
||||
flash.powerUp();
|
||||
secerase((rxframe[1]<<8) | rxframe[2]);
|
||||
flash.powerDown();
|
||||
|
||||
break;
|
||||
|
||||
case READ:
|
||||
flash.powerUp();
|
||||
readpage((rxframe[1]<<8) | rxframe[2]);
|
||||
flash.powerDown();
|
||||
break;
|
||||
|
||||
case READ_ALL:
|
||||
readAllPages();
|
||||
break;
|
||||
|
||||
case PROG:
|
||||
writepage((rxframe[1]<<8) | rxframe[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}//switch
|
||||
digitalWrite(RESET, HIGH);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void secerase(uint32_t sector){
|
||||
flash.eraseBlock64K(sector<<8);
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
|
||||
}
|
||||
void decodeFrame(void){
|
||||
int x,y;
|
||||
escaped = false;
|
||||
y = 1;
|
||||
rfcs = rxframe[1];
|
||||
rxframe[0]=rxframe[1];
|
||||
for (x=2;x<512;x++)
|
||||
{
|
||||
switch (rxframe[x]){
|
||||
|
||||
case FEND:
|
||||
x = 513;
|
||||
break;
|
||||
|
||||
case FESC:
|
||||
escaped = true;
|
||||
break;
|
||||
|
||||
case TFEND:
|
||||
if (escaped)
|
||||
{
|
||||
rxframe[y++] = FEND;
|
||||
rfcs+=FEND;
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rxframe[y++]=TFEND;
|
||||
rfcs+=TFEND;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TFESC:
|
||||
if (escaped)
|
||||
{
|
||||
rxframe[y++]=FESC;
|
||||
rfcs+=FESC;
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rxframe[y++]=TFESC;
|
||||
rfcs+=TFESC;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
escaped = false;
|
||||
rxframe[y++] = rxframe[x];
|
||||
rfcs+=rxframe[x];
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void writepage(int pagenr){
|
||||
int x;
|
||||
flash.powerUp();
|
||||
|
||||
for (x=0; x<256;x++)
|
||||
membuf[x]=rxframe[x+3];
|
||||
|
||||
flash.writePage(pagenr,membuf);
|
||||
flash.readPage(pagenr,data_buffer);
|
||||
flash.powerDown();
|
||||
|
||||
for (int a = 0; a < 256; a++)
|
||||
if (data_buffer[a] != membuf[a])
|
||||
return;
|
||||
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Reads a frame from Serial
|
||||
bool readSerialFrame(void)
|
||||
{
|
||||
Serial.setTimeout(50);
|
||||
|
||||
if (!Serial)
|
||||
Serial.begin(230400);
|
||||
// Serial.begin(1000000);
|
||||
while (Serial.available()) {
|
||||
Serial.readBytesUntil(FEND,rxframe,512);
|
||||
//if (rxframe[0]!=FEND)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void flash_bulk_erase(void)
|
||||
{
|
||||
flash.powerUp();
|
||||
flash.eraseChip();
|
||||
flash.powerDown();
|
||||
startframe(READY);
|
||||
addbyte(BULK_ERASE);
|
||||
sendframe();
|
||||
}
|
||||
|
||||
void SendID(void)
|
||||
{
|
||||
|
||||
flash.powerUp();
|
||||
uint32_t JEDEC = flash.getJEDECID();
|
||||
flash.powerDown();
|
||||
startframe(READ_ID);
|
||||
addbyte(JEDEC >> 16);
|
||||
addbyte(JEDEC >> 8);
|
||||
addbyte(JEDEC >> 0);
|
||||
sendframe();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sendframe(){
|
||||
fcs = 0xff - fcs;
|
||||
addbyte(fcs);
|
||||
txframe[txp++] = FEND;
|
||||
Serial.write(txframe,txp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void startframe(uint8_t command){
|
||||
txframe[0]=FEND;
|
||||
txframe[1]=command;
|
||||
txp = 2;
|
||||
fcs = command;
|
||||
}
|
||||
void addbyte(uint8_t newbyte)
|
||||
{
|
||||
fcs+=newbyte;
|
||||
if (newbyte == FEND)
|
||||
{
|
||||
txframe[txp++] = FESC;
|
||||
txframe[txp++] = TFEND;
|
||||
} else
|
||||
if (newbyte == FESC)
|
||||
{
|
||||
txframe[txp++] = FESC;
|
||||
txframe[txp++] = TFESC;
|
||||
} else
|
||||
txframe[txp++] = newbyte;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void readAllPages(void){
|
||||
flash.powerUp();
|
||||
maxPage=0x2000;
|
||||
delay(10);
|
||||
int p;
|
||||
for (p=0;p<maxPage;p++)
|
||||
readpage(p);
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
//
|
||||
flash.powerDown();
|
||||
}
|
||||
|
||||
|
||||
void readpage(uint16_t adr){
|
||||
|
||||
bool sendempty = true;
|
||||
//delay(5);
|
||||
|
||||
flash.readPage(adr,data_buffer);
|
||||
|
||||
for (int a = 0; a < 256; a++){
|
||||
if (data_buffer[a] != 0xff){
|
||||
startframe(READ);
|
||||
addbyte(adr >> 8);
|
||||
addbyte(adr >> 0);
|
||||
for (int b = 0;b<256;b++)
|
||||
addbyte(data_buffer[b]);
|
||||
sendframe();
|
||||
sendempty=false;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (sendempty){
|
||||
startframe(EMPTY);
|
||||
addbyte(adr >> 8);
|
||||
addbyte(adr >> 0);
|
||||
sendframe();
|
||||
}
|
||||
}
|
1961
tools/olimexino-32u4 firmware/iceprog/SPIFlash.cpp
Normal file
1961
tools/olimexino-32u4 firmware/iceprog/SPIFlash.cpp
Normal file
File diff suppressed because it is too large
Load Diff
267
tools/olimexino-32u4 firmware/iceprog/SPIFlash.h
Normal file
267
tools/olimexino-32u4 firmware/iceprog/SPIFlash.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/* Arduino SPIFlash Library v.2.2.0
|
||||
* Copyright (C) 2015 by Prajwal Bhattaram
|
||||
* Modified by Prajwal Bhattaram - 24/11/2015
|
||||
*
|
||||
* This file is part of the Arduino SPIFlash Library. This library is for
|
||||
* Winbond NOR flash memory modules. In its current form it enables reading
|
||||
* and writing individual data variables, structs and arrays from and to various locations;
|
||||
* reading and writing pages; continuous read functions; sector, block and chip erase;
|
||||
* suspending and resuming programming/erase and powering down for low power operation.
|
||||
*
|
||||
* This Library 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This Library 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 v3.0
|
||||
* along with the Arduino SPIFlash Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SPIFLASH_H
|
||||
#define SPIFLASH_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class SPIFlash {
|
||||
public:
|
||||
//----------------------------------------------Constructor-----------------------------------------------//
|
||||
SPIFlash(uint8_t cs = 10, bool overflow = true);
|
||||
//----------------------------------------Initial / Chip Functions----------------------------------------//
|
||||
void begin();
|
||||
uint16_t getManID();
|
||||
uint32_t getJEDECID();
|
||||
bool getAddress(uint16_t size, uint16_t &page_number, uint8_t &offset);
|
||||
uint32_t getAddress(uint16_t size);
|
||||
uint16_t getChipName();
|
||||
uint16_t sizeofStr(String &inputStr);
|
||||
uint32_t getCapacity();
|
||||
uint32_t getMaxPage();
|
||||
//-------------------------------------------Write / Read Bytes-------------------------------------------//
|
||||
bool writeByte(uint32_t address, uint8_t data, bool errorCheck = true);
|
||||
bool writeByte(uint16_t page_number, uint8_t offset, uint8_t data, bool errorCheck = true);
|
||||
uint8_t readByte(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
uint8_t readByte(uint32_t address, bool fastRead = false);
|
||||
//----------------------------------------Write / Read Byte Arrays----------------------------------------//
|
||||
bool writeByteArray(uint32_t address, uint8_t *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
bool writeByteArray(uint16_t page_number, uint8_t offset, uint8_t *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
uint8_t readByteArray(uint32_t address, uint8_t *data_buffer, uint16_t bufferSize, bool fastRead = false);
|
||||
uint8_t readByteArray(uint16_t page_number, uint8_t offset, uint8_t *data_buffer, uint16_t bufferSize, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Chars-------------------------------------------//
|
||||
bool writeChar(uint32_t address, int8_t data, bool errorCheck = true);
|
||||
bool writeChar(uint16_t page_number, uint8_t offset, int8_t data, bool errorCheck = true);
|
||||
int8_t readChar(uint32_t address, bool fastRead = false);
|
||||
int8_t readChar(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//----------------------------------------Write / Read Char Arrays----------------------------------------//
|
||||
bool writeCharArray(uint32_t address, char *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
bool writeCharArray(uint16_t page_number, uint8_t offset, char *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
uint8_t readCharArray(uint32_t address, char *data_buffer, uint16_t buffer_size, bool fastRead = false);
|
||||
uint8_t readCharArray(uint16_t page_number, uint8_t offset, char *data_buffer, uint16_t buffer_size, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Shorts------------------------------------------//
|
||||
bool writeShort(uint32_t address, int16_t data, bool errorCheck = true);
|
||||
bool writeShort(uint16_t page_number, uint8_t offset, int16_t data, bool errorCheck = true);
|
||||
int16_t readShort(uint32_t address, bool fastRead = false);
|
||||
int16_t readShort(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Words-------------------------------------------//
|
||||
bool writeWord(uint32_t address, uint16_t data, bool errorCheck = true);
|
||||
bool writeWord(uint16_t page_number, uint8_t offset, uint16_t data, bool errorCheck = true);
|
||||
uint16_t readWord(uint32_t address, bool fastRead = false);
|
||||
uint16_t readWord(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Longs-------------------------------------------//
|
||||
bool writeLong(uint32_t address, int32_t data, bool errorCheck = true);
|
||||
bool writeLong(uint16_t page_number, uint8_t offset, int32_t data, bool errorCheck = true);
|
||||
int32_t readLong(uint32_t address, bool fastRead = false);
|
||||
int32_t readLong(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//--------------------------------------Write / Read Unsigned Longs---------------------------------------//
|
||||
bool writeULong(uint32_t address, uint32_t data, bool errorCheck = true);
|
||||
bool writeULong(uint16_t page_number, uint8_t offset, uint32_t data, bool errorCheck = true);
|
||||
uint32_t readULong(uint32_t address, bool fastRead = false);
|
||||
uint32_t readULong(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Floats------------------------------------------//
|
||||
bool writeFloat(uint32_t address, float data, bool errorCheck = true);
|
||||
bool writeFloat(uint16_t page_number, uint8_t offset, float data, bool errorCheck = true);
|
||||
float readFloat(uint32_t address, bool fastRead = false);
|
||||
float readFloat(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Strings------------------------------------------//
|
||||
bool writeStr(uint32_t address, String &inputStr, bool errorCheck = true);
|
||||
bool writeStr(uint16_t page_number, uint8_t offset, String &inputStr, bool errorCheck = true);
|
||||
bool readStr(uint32_t address, String &outStr, bool fastRead = false);
|
||||
bool readStr(uint16_t page_number, uint8_t offset, String &outStr, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Pages-------------------------------------------//
|
||||
bool writePage(uint16_t page_number, uint8_t *data_buffer, bool errorCheck = true);
|
||||
bool readPage(uint16_t page_number, uint8_t *data_buffer, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Anything-----------------------------------------//
|
||||
template <class T> bool writeAnything(uint32_t address, const T& value, bool errorCheck = true);
|
||||
template <class T> bool writeAnything(uint16_t page_number, uint8_t offset, const T& value, bool errorCheck = true);
|
||||
template <class T> bool readAnything(uint32_t address, T& value, bool fastRead = false);
|
||||
template <class T> bool readAnything(uint16_t page_number, uint8_t offset, T& value, bool fastRead = false);
|
||||
//--------------------------------------------Erase functions---------------------------------------------//
|
||||
bool eraseSector(uint32_t address);
|
||||
bool eraseSector(uint16_t page_number, uint8_t offset);
|
||||
bool eraseBlock32K(uint32_t address);
|
||||
bool eraseBlock32K(uint16_t page_number, uint8_t offset);
|
||||
bool eraseBlock64K(uint32_t address);
|
||||
bool eraseBlock64K(uint16_t page_number, uint8_t offset);
|
||||
bool eraseChip(void);
|
||||
//---------------------------------------------Power functions--------------------------------------------//
|
||||
bool suspendProg(void);
|
||||
bool resumeProg(void);
|
||||
bool powerDown(void);
|
||||
bool powerUp(void);
|
||||
//--------------------------------------------Private functions-------------------------------------------//
|
||||
private:
|
||||
void _troubleshoot(uint8_t error);
|
||||
void _cmd(uint8_t cmd, bool _continue = true, uint8_t cs = 0);
|
||||
void _endProcess(void);
|
||||
void _errorCodeCheck(void);
|
||||
void _beginRead(uint32_t address);
|
||||
void _beginFastRead(uint32_t address);
|
||||
bool _noSuspend(void);
|
||||
bool _notBusy(uint32_t timeout = 10L);
|
||||
bool _notPrevWritten(uint32_t address, uint8_t size = 1);
|
||||
bool _addressCheck(uint32_t address);
|
||||
bool _beginWrite(uint32_t address);
|
||||
bool _writeNextByte(uint8_t c, bool _continue = true);
|
||||
bool _writeEnable(void);
|
||||
bool _writeDisable(void);
|
||||
bool _getJedecId(uint8_t *b1, uint8_t *b2, uint8_t *b3);
|
||||
bool _getManId(uint8_t *b1, uint8_t *b2);
|
||||
bool _chipID(void);
|
||||
uint8_t _readStat1(void);
|
||||
uint8_t _readNextByte(bool _continue = true);
|
||||
uint32_t _getAddress(uint16_t page_number, uint8_t offset = 0);
|
||||
uint32_t _prepRead(uint32_t address);
|
||||
uint32_t _prepRead(uint16_t page_number, uint8_t offset = 0);
|
||||
uint32_t _prepWrite(uint32_t address);
|
||||
uint32_t _prepWrite(uint16_t page_number, uint8_t offset = 0);
|
||||
template <class T> bool _writeErrorCheck(uint32_t address, const T& value);
|
||||
//-------------------------------------------Private variables------------------------------------------//
|
||||
bool pageOverflow;
|
||||
volatile uint8_t *cs_port;
|
||||
uint8_t cs_mask, csPin, errorcode;
|
||||
uint16_t name;
|
||||
uint32_t capacity, maxPage;
|
||||
uint32_t currentAddress = 1;
|
||||
const uint8_t devType[10] = {0x5, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
|
||||
const uint32_t memSize[10] = {64L * 1024L, 128L * 1024L, 256L * 1024L, 512L * 1024L, 1L * 1024L * 1024L,
|
||||
2L * 1024L * 1024L, 4L * 1024L * 1024L, 8L * 1024L * 1024L, 16L * 1024L * 1024L};
|
||||
const uint16_t chipName[10] = {05, 10, 20, 40, 80, 16, 32, 64, 128, 256};
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------Templates-------------------------------------------//
|
||||
|
||||
// Writes any type of data to a specific location in the flash memory.
|
||||
// Has two variants:
|
||||
// A. Takes two arguments -
|
||||
// 1. address --> Any address from 0 to maxAddress
|
||||
// 2. T& value --> Variable to return data into
|
||||
// 4. errorCheck --> Turned on by default. Checks for writing errors
|
||||
// B. Takes three arguments -
|
||||
// 1. page --> Any page number from 0 to maxPage
|
||||
// 2. offset --> Any offset within the page - from 0 to 255
|
||||
// 3. const T& value --> Variable with the data to be written
|
||||
// 4. errorCheck --> Turned on by default. Checks for writing errors
|
||||
// WARNING: You can only write to previously erased memory locations (see datasheet).
|
||||
// Use the eraseSector()/eraseBlock32K/eraseBlock64K commands to first clear memory (write 0xFFs)
|
||||
// Variant A
|
||||
template <class T> bool SPIFlash::writeAnything(uint32_t address, const T& value, bool errorCheck) {
|
||||
if (!_prepWrite(address))
|
||||
return false;
|
||||
else {
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
_beginWrite(address);
|
||||
for (uint16_t i = 0; i < sizeof(value); i++) {
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1)
|
||||
_writeNextByte(*p++, false);
|
||||
#endif
|
||||
_writeNextByte(*p++);
|
||||
}
|
||||
_endProcess();
|
||||
}
|
||||
|
||||
if (!errorCheck)
|
||||
return true;
|
||||
else
|
||||
return _writeErrorCheck(address, value);
|
||||
}
|
||||
// Variant B
|
||||
template <class T> bool SPIFlash::writeAnything(uint16_t page_number, uint8_t offset, const T& value, bool errorCheck) {
|
||||
uint32_t address = _getAddress(page_number, offset);
|
||||
return writeAnything(address, value, errorCheck);
|
||||
}
|
||||
|
||||
// Reads any type of data from a specific location in the flash memory.
|
||||
// Has two variants:
|
||||
// A. Takes two arguments -
|
||||
// 1. address --> Any address from 0 to maxAddress
|
||||
// 2. T& value --> Variable to return data into
|
||||
// 2. fastRead --> defaults to false - executes _beginFastRead() if set to true
|
||||
// B. Takes three arguments -
|
||||
// 1. page --> Any page number from 0 to maxPage
|
||||
// 2. offset --> Any offset within the page - from 0 to 255
|
||||
// 3. T& value --> Variable to return data into
|
||||
// 3. fastRead --> defaults to false - executes _beginFastRead() if set to true
|
||||
// Variant A
|
||||
template <class T> bool SPIFlash::readAnything(uint32_t address, T& value, bool fastRead) {
|
||||
if (!_prepRead(address))
|
||||
return false;
|
||||
|
||||
byte* p = (byte*)(void*)&value;
|
||||
if(!fastRead)
|
||||
_beginRead(address);
|
||||
else
|
||||
_beginFastRead(address);
|
||||
for (uint16_t i = 0; i < sizeof(value); i++) {
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1)
|
||||
*p++ = _readNextByte(false);
|
||||
#endif
|
||||
*p++ =_readNextByte();
|
||||
}
|
||||
_endProcess();
|
||||
return true;
|
||||
}
|
||||
// Variant B
|
||||
template <class T> bool SPIFlash::readAnything(uint16_t page_number, uint8_t offset, T& value, bool fastRead)
|
||||
{
|
||||
uint32_t address = _getAddress(page_number, offset);
|
||||
return readAnything(address, value, fastRead);
|
||||
}
|
||||
|
||||
// Private template to check for errors in writing to flash memory
|
||||
template <class T> bool SPIFlash::_writeErrorCheck(uint32_t address, const T& value) {
|
||||
if (!_prepRead(address))
|
||||
return false;
|
||||
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
_beginRead(address);
|
||||
for(uint16_t i = 0; i < sizeof(value);i++)
|
||||
{
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1) {
|
||||
if (*p++ != _readNextByte(false))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (*p++ != _readNextByte())
|
||||
return false;
|
||||
#elif defined (__AVR__)
|
||||
if (*p++ != _readNextByte())
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
_endProcess();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif // _SPIFLASH_H_
|
403
tools/olimexino-32u4 firmware/iceprog/iceprog.ino
Normal file
403
tools/olimexino-32u4 firmware/iceprog/iceprog.ino
Normal file
@@ -0,0 +1,403 @@
|
||||
/*
|
||||
* iceprog -- firmware scetch for Arduino based Lattice iCE programmers
|
||||
*
|
||||
* Chris B. <chris@protonic.co.uk> @ Olimex Ltd. <c> 2017
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Relevant Documents:
|
||||
* -------------------
|
||||
* http://www.latticesemi.com/~/media/Documents/UserManuals/EI/icestickusermanual.pdf
|
||||
* http://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/n25q/n25q_32mb_3v_65nm.pdf
|
||||
* http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf
|
||||
* https://www.olimex.com/Products/FPGA/iCE40/iCE40HX1K-EVB/
|
||||
* https://github.com/Marzogh/SPIFlash
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
// The demo uses SPIFlash v2.2.0, its files are included in the project folders the author is Prajwal Bhattaram - Marzogh
|
||||
|
||||
#include "SPIFlash.h"
|
||||
|
||||
#define LED 17
|
||||
#define CDONE 3
|
||||
#define RESET 2
|
||||
#define UEXT_POWER 8
|
||||
#define CS 13
|
||||
|
||||
//commands list
|
||||
#define READ_ID 0x9F
|
||||
#define PWR_UP 0xAB
|
||||
#define PWR_DOWN 0xB9
|
||||
#define WR_EN 0x06
|
||||
#define BULK_ERASE 0xC7
|
||||
#define SEC_ERASE 0xd8
|
||||
#define PROG 0x02
|
||||
#define READ 0x03
|
||||
#define READ_ALL 0x83
|
||||
#define CMD_ERROR 0xee
|
||||
#define READY 0x44
|
||||
#define EMPTY 0x45
|
||||
|
||||
#define FEND 0xc0
|
||||
#define FESC 0xdb
|
||||
#define TFEND 0xdc
|
||||
#define TFESC 0xdd
|
||||
|
||||
#define cselect digitalWrite(CS,LOW)
|
||||
#define deselect digitalWrite(CS,HIGH)
|
||||
|
||||
//Toggle iceprogduino with serial bridge by pressing the HWB button
|
||||
#define HWB (PINE & B00000100)==0 // Check if the button has been pressed
|
||||
#define HWB_INPUT DDRE &= B11111011 // Initialize the port
|
||||
#define LED_G 7 // The GREEN LED is on Pin 7
|
||||
#define LED_Y 9 // The YELLOW LED is on Pin 9
|
||||
boolean isProg;
|
||||
|
||||
uint8_t rxframe[512], txframe[512], fcs,rfcs;
|
||||
uint8_t membuf[256];
|
||||
uint8_t data_buffer[256];
|
||||
uint16_t txp;
|
||||
uint32_t maxPage;
|
||||
bool escaped;
|
||||
SPIFlash flash(CS);
|
||||
|
||||
void secerase(uint32_t sector);
|
||||
void decodeFrame(void);
|
||||
void writepage(int pagenr);
|
||||
bool readSerialFrame(void);
|
||||
void flash_bulk_erase(void);
|
||||
void SendID(void);
|
||||
void sendframe();
|
||||
void startframe(uint8_t command);
|
||||
void addbyte(uint8_t newbyte);
|
||||
void readAllPages(void);
|
||||
void readpage(uint16_t adr);
|
||||
|
||||
// FRAME: <FEND><CMD>{data if any}<FCS(sume of all bytes = 0xFF)><FEND>
|
||||
// if FEND, FESC in data - <FEND>=<FESC><TFEND>; <FESC>=<FESC><TFESC>
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
// Power Up UEXT
|
||||
pinMode(CDONE,INPUT);
|
||||
pinMode(RESET,OUTPUT);
|
||||
pinMode(LED,OUTPUT);
|
||||
digitalWrite(LED,0);
|
||||
pinMode(CS,OUTPUT);
|
||||
digitalWrite(CS,HIGH);
|
||||
pinMode(UEXT_POWER, OUTPUT);
|
||||
digitalWrite(UEXT_POWER, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(UEXT_POWER, LOW);
|
||||
delay(500);
|
||||
digitalWrite(RESET, HIGH);
|
||||
Serial.begin(230400);
|
||||
while (!Serial);
|
||||
|
||||
isProg=true;
|
||||
HWB_INPUT; // Initialize HWB
|
||||
Serial1.begin(115200);
|
||||
pinMode(LED_Y,OUTPUT);
|
||||
digitalWrite(LED_Y,isProg); //Yellow LED is Prog
|
||||
pinMode(LED_G,OUTPUT);
|
||||
digitalWrite(LED_G,!isProg); //Green LED is Bridge
|
||||
|
||||
}
|
||||
|
||||
void loop(){
|
||||
if (isProg) loopProg();
|
||||
else loopBridge();
|
||||
if (HWB) {
|
||||
isProg = !isProg;
|
||||
digitalWrite(LED_Y,isProg);
|
||||
digitalWrite(LED_G,!isProg);
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void loopBridge(){
|
||||
// read from port 1, send to port 0:
|
||||
if (Serial1.available()) {
|
||||
int inByte = Serial1.read();
|
||||
Serial.write(inByte);
|
||||
}
|
||||
|
||||
// read from port 0, send to port 1:
|
||||
if (Serial.available()) {
|
||||
int inByte = Serial.read();
|
||||
Serial1.write(inByte);
|
||||
}
|
||||
}
|
||||
|
||||
void loopProg() {
|
||||
|
||||
if (readSerialFrame())
|
||||
{
|
||||
decodeFrame();
|
||||
if (rfcs==0xff)
|
||||
{
|
||||
digitalWrite(RESET, LOW);
|
||||
|
||||
switch (rxframe[0]){
|
||||
|
||||
case FEND:
|
||||
break;
|
||||
|
||||
case READ_ID:
|
||||
SendID();
|
||||
break;
|
||||
|
||||
case BULK_ERASE:
|
||||
flash_bulk_erase();
|
||||
break;
|
||||
|
||||
case SEC_ERASE:
|
||||
flash.powerUp();
|
||||
secerase((rxframe[1]<<8) | rxframe[2]);
|
||||
flash.powerDown();
|
||||
|
||||
break;
|
||||
|
||||
case READ:
|
||||
flash.powerUp();
|
||||
readpage((rxframe[1]<<8) | rxframe[2]);
|
||||
flash.powerDown();
|
||||
break;
|
||||
|
||||
case READ_ALL:
|
||||
readAllPages();
|
||||
break;
|
||||
|
||||
case PROG:
|
||||
writepage((rxframe[1]<<8) | rxframe[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}//switch
|
||||
digitalWrite(RESET, HIGH);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void secerase(uint32_t sector){
|
||||
flash.eraseBlock64K(sector<<8);
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
|
||||
}
|
||||
void decodeFrame(void){
|
||||
int x,y;
|
||||
escaped = false;
|
||||
y = 1;
|
||||
rfcs = rxframe[1];
|
||||
rxframe[0]=rxframe[1];
|
||||
for (x=2;x<512;x++)
|
||||
{
|
||||
switch (rxframe[x]){
|
||||
|
||||
case FEND:
|
||||
x = 513;
|
||||
break;
|
||||
|
||||
case FESC:
|
||||
escaped = true;
|
||||
break;
|
||||
|
||||
case TFEND:
|
||||
if (escaped)
|
||||
{
|
||||
rxframe[y++] = FEND;
|
||||
rfcs+=FEND;
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rxframe[y++]=TFEND;
|
||||
rfcs+=TFEND;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TFESC:
|
||||
if (escaped)
|
||||
{
|
||||
rxframe[y++]=FESC;
|
||||
rfcs+=FESC;
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rxframe[y++]=TFESC;
|
||||
rfcs+=TFESC;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
escaped = false;
|
||||
rxframe[y++] = rxframe[x];
|
||||
rfcs+=rxframe[x];
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void writepage(int pagenr){
|
||||
int x;
|
||||
flash.powerUp();
|
||||
|
||||
for (x=0; x<256;x++)
|
||||
membuf[x]=rxframe[x+3];
|
||||
|
||||
flash.writePage(pagenr,membuf);
|
||||
flash.readPage(pagenr,data_buffer);
|
||||
flash.powerDown();
|
||||
|
||||
for (int a = 0; a < 256; a++)
|
||||
if (data_buffer[a] != membuf[a])
|
||||
return;
|
||||
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Reads a frame from Serial
|
||||
bool readSerialFrame(void)
|
||||
{
|
||||
Serial.setTimeout(50);
|
||||
|
||||
if (!Serial)
|
||||
Serial.begin(230400);
|
||||
// Serial.begin(1000000);
|
||||
while (Serial.available()) {
|
||||
Serial.readBytesUntil(FEND,rxframe,512);
|
||||
//if (rxframe[0]!=FEND)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void flash_bulk_erase(void)
|
||||
{
|
||||
flash.powerUp();
|
||||
flash.eraseChip();
|
||||
flash.powerDown();
|
||||
startframe(READY);
|
||||
addbyte(BULK_ERASE);
|
||||
sendframe();
|
||||
}
|
||||
|
||||
void SendID(void)
|
||||
{
|
||||
|
||||
flash.powerUp();
|
||||
uint32_t JEDEC = flash.getJEDECID();
|
||||
flash.powerDown();
|
||||
startframe(READ_ID);
|
||||
addbyte(JEDEC >> 16);
|
||||
addbyte(JEDEC >> 8);
|
||||
addbyte(JEDEC >> 0);
|
||||
sendframe();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sendframe(){
|
||||
fcs = 0xff - fcs;
|
||||
addbyte(fcs);
|
||||
txframe[txp++] = FEND;
|
||||
Serial.write(txframe,txp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void startframe(uint8_t command){
|
||||
txframe[0]=FEND;
|
||||
txframe[1]=command;
|
||||
txp = 2;
|
||||
fcs = command;
|
||||
}
|
||||
void addbyte(uint8_t newbyte)
|
||||
{
|
||||
fcs+=newbyte;
|
||||
if (newbyte == FEND)
|
||||
{
|
||||
txframe[txp++] = FESC;
|
||||
txframe[txp++] = TFEND;
|
||||
} else
|
||||
if (newbyte == FESC)
|
||||
{
|
||||
txframe[txp++] = FESC;
|
||||
txframe[txp++] = TFESC;
|
||||
} else
|
||||
txframe[txp++] = newbyte;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void readAllPages(void){
|
||||
flash.powerUp();
|
||||
maxPage=0x2000;
|
||||
delay(10);
|
||||
int p;
|
||||
for (p=0;p<maxPage;p++)
|
||||
readpage(p);
|
||||
startframe(READY);
|
||||
sendframe();
|
||||
//
|
||||
flash.powerDown();
|
||||
}
|
||||
|
||||
|
||||
void readpage(uint16_t adr){
|
||||
|
||||
bool sendempty = true;
|
||||
//delay(5);
|
||||
|
||||
flash.readPage(adr,data_buffer);
|
||||
|
||||
for (int a = 0; a < 256; a++){
|
||||
if (data_buffer[a] != 0xff){
|
||||
startframe(READ);
|
||||
addbyte(adr >> 8);
|
||||
addbyte(adr >> 0);
|
||||
for (int b = 0;b<256;b++)
|
||||
addbyte(data_buffer[b]);
|
||||
sendframe();
|
||||
sendempty=false;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (sendempty){
|
||||
startframe(EMPTY);
|
||||
addbyte(adr >> 8);
|
||||
addbyte(adr >> 0);
|
||||
sendframe();
|
||||
}
|
||||
}
|
14
tools/olimexino-32u4 firmware/platformio.ini
Normal file
14
tools/olimexino-32u4 firmware/platformio.ini
Normal file
@@ -0,0 +1,14 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
env_default = leonardo
|
||||
|
||||
[env:leonardo]
|
||||
platform = atmelavr
|
||||
framework = arduino
|
||||
board = leonardo
|
||||
board_build.mcu = atmega32u4
|
||||
board_build.f_cpu = 16000000L
|
1961
tools/olimexino-32u4 firmware/src/SPIFlash.cpp
Normal file
1961
tools/olimexino-32u4 firmware/src/SPIFlash.cpp
Normal file
File diff suppressed because it is too large
Load Diff
267
tools/olimexino-32u4 firmware/src/SPIFlash.h
Normal file
267
tools/olimexino-32u4 firmware/src/SPIFlash.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/* Arduino SPIFlash Library v.2.2.0
|
||||
* Copyright (C) 2015 by Prajwal Bhattaram
|
||||
* Modified by Prajwal Bhattaram - 24/11/2015
|
||||
*
|
||||
* This file is part of the Arduino SPIFlash Library. This library is for
|
||||
* Winbond NOR flash memory modules. In its current form it enables reading
|
||||
* and writing individual data variables, structs and arrays from and to various locations;
|
||||
* reading and writing pages; continuous read functions; sector, block and chip erase;
|
||||
* suspending and resuming programming/erase and powering down for low power operation.
|
||||
*
|
||||
* This Library 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This Library 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 v3.0
|
||||
* along with the Arduino SPIFlash Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SPIFLASH_H
|
||||
#define SPIFLASH_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class SPIFlash {
|
||||
public:
|
||||
//----------------------------------------------Constructor-----------------------------------------------//
|
||||
SPIFlash(uint8_t cs = 10, bool overflow = true);
|
||||
//----------------------------------------Initial / Chip Functions----------------------------------------//
|
||||
void begin();
|
||||
uint16_t getManID();
|
||||
uint32_t getJEDECID();
|
||||
bool getAddress(uint16_t size, uint16_t &page_number, uint8_t &offset);
|
||||
uint32_t getAddress(uint16_t size);
|
||||
uint16_t getChipName();
|
||||
uint16_t sizeofStr(String &inputStr);
|
||||
uint32_t getCapacity();
|
||||
uint32_t getMaxPage();
|
||||
//-------------------------------------------Write / Read Bytes-------------------------------------------//
|
||||
bool writeByte(uint32_t address, uint8_t data, bool errorCheck = true);
|
||||
bool writeByte(uint16_t page_number, uint8_t offset, uint8_t data, bool errorCheck = true);
|
||||
uint8_t readByte(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
uint8_t readByte(uint32_t address, bool fastRead = false);
|
||||
//----------------------------------------Write / Read Byte Arrays----------------------------------------//
|
||||
bool writeByteArray(uint32_t address, uint8_t *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
bool writeByteArray(uint16_t page_number, uint8_t offset, uint8_t *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
uint8_t readByteArray(uint32_t address, uint8_t *data_buffer, uint16_t bufferSize, bool fastRead = false);
|
||||
uint8_t readByteArray(uint16_t page_number, uint8_t offset, uint8_t *data_buffer, uint16_t bufferSize, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Chars-------------------------------------------//
|
||||
bool writeChar(uint32_t address, int8_t data, bool errorCheck = true);
|
||||
bool writeChar(uint16_t page_number, uint8_t offset, int8_t data, bool errorCheck = true);
|
||||
int8_t readChar(uint32_t address, bool fastRead = false);
|
||||
int8_t readChar(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//----------------------------------------Write / Read Char Arrays----------------------------------------//
|
||||
bool writeCharArray(uint32_t address, char *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
bool writeCharArray(uint16_t page_number, uint8_t offset, char *data_buffer, uint16_t bufferSize, bool errorCheck = true);
|
||||
uint8_t readCharArray(uint32_t address, char *data_buffer, uint16_t buffer_size, bool fastRead = false);
|
||||
uint8_t readCharArray(uint16_t page_number, uint8_t offset, char *data_buffer, uint16_t buffer_size, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Shorts------------------------------------------//
|
||||
bool writeShort(uint32_t address, int16_t data, bool errorCheck = true);
|
||||
bool writeShort(uint16_t page_number, uint8_t offset, int16_t data, bool errorCheck = true);
|
||||
int16_t readShort(uint32_t address, bool fastRead = false);
|
||||
int16_t readShort(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Words-------------------------------------------//
|
||||
bool writeWord(uint32_t address, uint16_t data, bool errorCheck = true);
|
||||
bool writeWord(uint16_t page_number, uint8_t offset, uint16_t data, bool errorCheck = true);
|
||||
uint16_t readWord(uint32_t address, bool fastRead = false);
|
||||
uint16_t readWord(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Longs-------------------------------------------//
|
||||
bool writeLong(uint32_t address, int32_t data, bool errorCheck = true);
|
||||
bool writeLong(uint16_t page_number, uint8_t offset, int32_t data, bool errorCheck = true);
|
||||
int32_t readLong(uint32_t address, bool fastRead = false);
|
||||
int32_t readLong(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//--------------------------------------Write / Read Unsigned Longs---------------------------------------//
|
||||
bool writeULong(uint32_t address, uint32_t data, bool errorCheck = true);
|
||||
bool writeULong(uint16_t page_number, uint8_t offset, uint32_t data, bool errorCheck = true);
|
||||
uint32_t readULong(uint32_t address, bool fastRead = false);
|
||||
uint32_t readULong(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Floats------------------------------------------//
|
||||
bool writeFloat(uint32_t address, float data, bool errorCheck = true);
|
||||
bool writeFloat(uint16_t page_number, uint8_t offset, float data, bool errorCheck = true);
|
||||
float readFloat(uint32_t address, bool fastRead = false);
|
||||
float readFloat(uint16_t page_number, uint8_t offset, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Strings------------------------------------------//
|
||||
bool writeStr(uint32_t address, String &inputStr, bool errorCheck = true);
|
||||
bool writeStr(uint16_t page_number, uint8_t offset, String &inputStr, bool errorCheck = true);
|
||||
bool readStr(uint32_t address, String &outStr, bool fastRead = false);
|
||||
bool readStr(uint16_t page_number, uint8_t offset, String &outStr, bool fastRead = false);
|
||||
//-------------------------------------------Write / Read Pages-------------------------------------------//
|
||||
bool writePage(uint16_t page_number, uint8_t *data_buffer, bool errorCheck = true);
|
||||
bool readPage(uint16_t page_number, uint8_t *data_buffer, bool fastRead = false);
|
||||
//------------------------------------------Write / Read Anything-----------------------------------------//
|
||||
template <class T> bool writeAnything(uint32_t address, const T& value, bool errorCheck = true);
|
||||
template <class T> bool writeAnything(uint16_t page_number, uint8_t offset, const T& value, bool errorCheck = true);
|
||||
template <class T> bool readAnything(uint32_t address, T& value, bool fastRead = false);
|
||||
template <class T> bool readAnything(uint16_t page_number, uint8_t offset, T& value, bool fastRead = false);
|
||||
//--------------------------------------------Erase functions---------------------------------------------//
|
||||
bool eraseSector(uint32_t address);
|
||||
bool eraseSector(uint16_t page_number, uint8_t offset);
|
||||
bool eraseBlock32K(uint32_t address);
|
||||
bool eraseBlock32K(uint16_t page_number, uint8_t offset);
|
||||
bool eraseBlock64K(uint32_t address);
|
||||
bool eraseBlock64K(uint16_t page_number, uint8_t offset);
|
||||
bool eraseChip(void);
|
||||
//---------------------------------------------Power functions--------------------------------------------//
|
||||
bool suspendProg(void);
|
||||
bool resumeProg(void);
|
||||
bool powerDown(void);
|
||||
bool powerUp(void);
|
||||
//--------------------------------------------Private functions-------------------------------------------//
|
||||
private:
|
||||
void _troubleshoot(uint8_t error);
|
||||
void _cmd(uint8_t cmd, bool _continue = true, uint8_t cs = 0);
|
||||
void _endProcess(void);
|
||||
void _errorCodeCheck(void);
|
||||
void _beginRead(uint32_t address);
|
||||
void _beginFastRead(uint32_t address);
|
||||
bool _noSuspend(void);
|
||||
bool _notBusy(uint32_t timeout = 10L);
|
||||
bool _notPrevWritten(uint32_t address, uint8_t size = 1);
|
||||
bool _addressCheck(uint32_t address);
|
||||
bool _beginWrite(uint32_t address);
|
||||
bool _writeNextByte(uint8_t c, bool _continue = true);
|
||||
bool _writeEnable(void);
|
||||
bool _writeDisable(void);
|
||||
bool _getJedecId(uint8_t *b1, uint8_t *b2, uint8_t *b3);
|
||||
bool _getManId(uint8_t *b1, uint8_t *b2);
|
||||
bool _chipID(void);
|
||||
uint8_t _readStat1(void);
|
||||
uint8_t _readNextByte(bool _continue = true);
|
||||
uint32_t _getAddress(uint16_t page_number, uint8_t offset = 0);
|
||||
uint32_t _prepRead(uint32_t address);
|
||||
uint32_t _prepRead(uint16_t page_number, uint8_t offset = 0);
|
||||
uint32_t _prepWrite(uint32_t address);
|
||||
uint32_t _prepWrite(uint16_t page_number, uint8_t offset = 0);
|
||||
template <class T> bool _writeErrorCheck(uint32_t address, const T& value);
|
||||
//-------------------------------------------Private variables------------------------------------------//
|
||||
bool pageOverflow;
|
||||
volatile uint8_t *cs_port;
|
||||
uint8_t cs_mask, csPin, errorcode;
|
||||
uint16_t name;
|
||||
uint32_t capacity, maxPage;
|
||||
uint32_t currentAddress = 1;
|
||||
const uint8_t devType[10] = {0x5, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
|
||||
const uint32_t memSize[10] = {64L * 1024L, 128L * 1024L, 256L * 1024L, 512L * 1024L, 1L * 1024L * 1024L,
|
||||
2L * 1024L * 1024L, 4L * 1024L * 1024L, 8L * 1024L * 1024L, 16L * 1024L * 1024L};
|
||||
const uint16_t chipName[10] = {05, 10, 20, 40, 80, 16, 32, 64, 128, 256};
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------Templates-------------------------------------------//
|
||||
|
||||
// Writes any type of data to a specific location in the flash memory.
|
||||
// Has two variants:
|
||||
// A. Takes two arguments -
|
||||
// 1. address --> Any address from 0 to maxAddress
|
||||
// 2. T& value --> Variable to return data into
|
||||
// 4. errorCheck --> Turned on by default. Checks for writing errors
|
||||
// B. Takes three arguments -
|
||||
// 1. page --> Any page number from 0 to maxPage
|
||||
// 2. offset --> Any offset within the page - from 0 to 255
|
||||
// 3. const T& value --> Variable with the data to be written
|
||||
// 4. errorCheck --> Turned on by default. Checks for writing errors
|
||||
// WARNING: You can only write to previously erased memory locations (see datasheet).
|
||||
// Use the eraseSector()/eraseBlock32K/eraseBlock64K commands to first clear memory (write 0xFFs)
|
||||
// Variant A
|
||||
template <class T> bool SPIFlash::writeAnything(uint32_t address, const T& value, bool errorCheck) {
|
||||
if (!_prepWrite(address))
|
||||
return false;
|
||||
else {
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
_beginWrite(address);
|
||||
for (uint16_t i = 0; i < sizeof(value); i++) {
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1)
|
||||
_writeNextByte(*p++, false);
|
||||
#endif
|
||||
_writeNextByte(*p++);
|
||||
}
|
||||
_endProcess();
|
||||
}
|
||||
|
||||
if (!errorCheck)
|
||||
return true;
|
||||
else
|
||||
return _writeErrorCheck(address, value);
|
||||
}
|
||||
// Variant B
|
||||
template <class T> bool SPIFlash::writeAnything(uint16_t page_number, uint8_t offset, const T& value, bool errorCheck) {
|
||||
uint32_t address = _getAddress(page_number, offset);
|
||||
return writeAnything(address, value, errorCheck);
|
||||
}
|
||||
|
||||
// Reads any type of data from a specific location in the flash memory.
|
||||
// Has two variants:
|
||||
// A. Takes two arguments -
|
||||
// 1. address --> Any address from 0 to maxAddress
|
||||
// 2. T& value --> Variable to return data into
|
||||
// 2. fastRead --> defaults to false - executes _beginFastRead() if set to true
|
||||
// B. Takes three arguments -
|
||||
// 1. page --> Any page number from 0 to maxPage
|
||||
// 2. offset --> Any offset within the page - from 0 to 255
|
||||
// 3. T& value --> Variable to return data into
|
||||
// 3. fastRead --> defaults to false - executes _beginFastRead() if set to true
|
||||
// Variant A
|
||||
template <class T> bool SPIFlash::readAnything(uint32_t address, T& value, bool fastRead) {
|
||||
if (!_prepRead(address))
|
||||
return false;
|
||||
|
||||
byte* p = (byte*)(void*)&value;
|
||||
if(!fastRead)
|
||||
_beginRead(address);
|
||||
else
|
||||
_beginFastRead(address);
|
||||
for (uint16_t i = 0; i < sizeof(value); i++) {
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1)
|
||||
*p++ = _readNextByte(false);
|
||||
#endif
|
||||
*p++ =_readNextByte();
|
||||
}
|
||||
_endProcess();
|
||||
return true;
|
||||
}
|
||||
// Variant B
|
||||
template <class T> bool SPIFlash::readAnything(uint16_t page_number, uint8_t offset, T& value, bool fastRead)
|
||||
{
|
||||
uint32_t address = _getAddress(page_number, offset);
|
||||
return readAnything(address, value, fastRead);
|
||||
}
|
||||
|
||||
// Private template to check for errors in writing to flash memory
|
||||
template <class T> bool SPIFlash::_writeErrorCheck(uint32_t address, const T& value) {
|
||||
if (!_prepRead(address))
|
||||
return false;
|
||||
|
||||
const byte* p = (const byte*)(const void*)&value;
|
||||
_beginRead(address);
|
||||
for(uint16_t i = 0; i < sizeof(value);i++)
|
||||
{
|
||||
#if defined (__arm__) && defined (__SAM3X8E__)
|
||||
if (i == sizeof(value)-1) {
|
||||
if (*p++ != _readNextByte(false))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (*p++ != _readNextByte())
|
||||
return false;
|
||||
#elif defined (__AVR__)
|
||||
if (*p++ != _readNextByte())
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
_endProcess();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif // _SPIFLASH_H_
|
1
tools/olimexino-32u4 firmware/src/iceprog.cpp
Symbolic link
1
tools/olimexino-32u4 firmware/src/iceprog.cpp
Symbolic link
@@ -0,0 +1 @@
|
||||
../iceprog.ino
|
23
tools/removeCode.sh
Executable file
23
tools/removeCode.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
for filename in ../*/*.v
|
||||
do
|
||||
sed -i '1,/Put your code here:/!d' ${filename}
|
||||
echo "\nendmodule" >> ${filename}
|
||||
done
|
||||
sed -i '1,/endmodule/!d' ../01_Boolean_Logic/Nand.v
|
||||
sed -i '1,/endmodule/!d' ../03_Sequential_Logic/DFF.v
|
||||
sed -i '1,/endmodule/!d' ../03_Sequential_Logic/RAM256.v
|
||||
sed -i '1,/endmodule/!d' ../05_Computer_Architecture/ROM.v
|
||||
sed -i '1,/endmodule/!d' ../06_IO_Devices/InOut.v
|
||||
|
||||
sed -i '/[\t]/d' ../07_Operating_System/*.jack
|
||||
|
||||
sed -i '/[\t]/d' ../04_Machine_Language/*.asm
|
||||
for filename in ../06_IO_Devices/*/*.asm
|
||||
do
|
||||
sed -i '1,/Put your code here:/!d' ${filename}
|
||||
done
|
||||
sed -i '/REMOVE CODE/d' ../07_Operating_System/12_Tetris/Main.jack
|
||||
#rm -r ../tools/Assembler/src
|
||||
#rm -r ../tools/VMTranslator/src
|
||||
#rm -r ../tools/JackCompiler/src
|
1
tools/vim/ftdetect/hack_asm.vim
Normal file
1
tools/vim/ftdetect/hack_asm.vim
Normal file
@@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.asm set filetype=hack_asm
|
1
tools/vim/ftdetect/hack_vm.vim
Normal file
1
tools/vim/ftdetect/hack_vm.vim
Normal file
@@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.vm set filetype=hack_vm
|
1
tools/vim/ftdetect/hdl.vim
Normal file
1
tools/vim/ftdetect/hdl.vim
Normal file
@@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.hdl set filetype=hdl
|
1
tools/vim/ftdetect/jack.vim
Normal file
1
tools/vim/ftdetect/jack.vim
Normal file
@@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead *.jack set filetype=jack
|
2
tools/vim/syntax/c.vim
Normal file
2
tools/vim/syntax/c.vim
Normal file
@@ -0,0 +1,2 @@
|
||||
syn match cType "pair "
|
||||
syn match cType "number "
|
32
tools/vim/syntax/hack_asm.vim
Normal file
32
tools/vim/syntax/hack_asm.vim
Normal file
@@ -0,0 +1,32 @@
|
||||
" Vim syntax file
|
||||
" Language: Hack Assembly
|
||||
" Maintainer: Severyn Kozak
|
||||
" Latest Revision: 15 November 2014
|
||||
|
||||
if version < 600
|
||||
syntax clear
|
||||
endif
|
||||
|
||||
setl iskeyword+=.,$,:
|
||||
|
||||
syn keyword hackAsmDestination A M D AM MD AD AMD null
|
||||
syn keyword hackAsmJump JGT JEQ JGE JLT JNE JLE JMP
|
||||
|
||||
syn match hackAsmComment "\/\/.*$"
|
||||
syn match hackAsmLabel "(\k\+)"
|
||||
syn match hackAsmMathOp "[+-]"
|
||||
syn match hackAsmBitwiseOp "[&|]"
|
||||
syn match hackAsmAInstruction "@\k\+"
|
||||
syn match hackAsmCInstruction "[=;]"
|
||||
syn match hackAsmConstant "-1\|0\|1"
|
||||
|
||||
hi link hackAsmDestination Identifier
|
||||
hi link hackAsmJump Function
|
||||
hi link hackAsmConstant Constant
|
||||
|
||||
hi link hackAsmComment Comment
|
||||
hi link hackAsmLabel Label
|
||||
hi link hackAsmMathOp Operator
|
||||
hi link hackAsmBitwiseOp Operator
|
||||
hi link hackAsmAInstruction PreProc
|
||||
hi link hackAsmCInstruction Operator
|
29
tools/vim/syntax/hack_vm.vim
Normal file
29
tools/vim/syntax/hack_vm.vim
Normal file
@@ -0,0 +1,29 @@
|
||||
" Vim syntax file
|
||||
" Language: Hack Virtual Machine
|
||||
" Maintainer: Severyn Kozak
|
||||
" Latest Revision: 02 December 2014
|
||||
|
||||
if version < 600
|
||||
syntax clear
|
||||
endif
|
||||
|
||||
setl iskeyword+=.,:
|
||||
setl iskeyword+=-
|
||||
|
||||
syn keyword hackVmMathLogicOp add sub neg eq gt lt or not
|
||||
syn keyword hackVmMemoryOp push pop
|
||||
syn keyword hackVmMemorySegments argument local static constant this that
|
||||
\ pointer temp
|
||||
syn keyword hackVmProgramFlowOp label goto if-goto
|
||||
syn keyword hackVmFunctionCallOp function call return
|
||||
|
||||
syn match hackVmComment "\/\/.*$"
|
||||
syn match hackVmNumber "\v(\w)@<!\d+"
|
||||
|
||||
hi link hackVmComment Comment
|
||||
hi link hackVmMathLogicOp Operator
|
||||
hi link hackVmMemoryOp Statement
|
||||
hi link hackVmMemorySegments Identifier
|
||||
hi link hackVmProgramFlowOp Conditional
|
||||
hi link hackVmFunctionCallOp Function
|
||||
hi link hackVmNumber Number
|
49
tools/vim/syntax/hdl.vim
Normal file
49
tools/vim/syntax/hdl.vim
Normal file
@@ -0,0 +1,49 @@
|
||||
" Vim syntax file
|
||||
" Language: HDL
|
||||
" Maintainer: Severyn Kozak
|
||||
" Latest Revision: 11 November 2014
|
||||
|
||||
if version < 600
|
||||
syntax clear
|
||||
endif
|
||||
|
||||
" The `.hdl` extension is reserved for the `vhdl` filetype, and, by the time
|
||||
" this plugin is sourced, Vim has already loaded the `vhdl` ftplugin files,
|
||||
" which contain some undesired settings. The fullproof way to ignore them is to
|
||||
" prevent Vim from ever setting the `vhdl` filetype, which can only be done by
|
||||
" having the user specify the following:
|
||||
"
|
||||
" au BufNewFile,BufRead *.hdl setfiletype hdl
|
||||
"
|
||||
" in their vimrc, which is messy. Best to let the plugin do the work just by
|
||||
" explicitly overriding the settings that we don't want, like the following.
|
||||
setl indentexpr=
|
||||
setl formatoptions+=or
|
||||
let b:current_syntax = "hdl"
|
||||
let did_load_filetypes = 1
|
||||
|
||||
syn match _hdl_comment_inline "\/\/.*"
|
||||
syn match _hdl_delimiter "[,;:.]"
|
||||
syn match _hdl_assignment "="
|
||||
syn match _hdl_number "\v(\w)@<!\d+"
|
||||
syn match _hdl_surrounding "[[\](){}]"
|
||||
syn match _hdl_pin_name "\a[a-zA-Z0-9]*\ze=" contains=ALL
|
||||
syn region _hdl_comment_block start="/\*" end="*/"
|
||||
syn keyword _hdl_builtin_chip Add16 ALU And And16 ARegister Bit DFF DMux
|
||||
\ DMux4Way DMux8Way DRegister Mux4Way16 Mux8Way16 FullAdder HalfAdder Inc16
|
||||
\ Keyboard Mux Mux16 Or Or16 Or8Way PC RAM RAM16K RAM4K RAM512 RAM64 ROM32K
|
||||
\ Screen Xor RAM8 Register RegisterWithGUI Nand Not Not16
|
||||
syn keyword _hdl_section CHIP PARTS IN OUT
|
||||
|
||||
syn keyword _hdl_constant true false
|
||||
|
||||
hi link _hdl_comment_block Comment
|
||||
hi link _hdl_comment_inline Comment
|
||||
hi link _hdl_builtin_chip Constant
|
||||
hi link _hdl_section Label
|
||||
hi link _hdl_delimiter Comment
|
||||
hi link _hdl_surrounding Delimiter
|
||||
hi link _hdl_number Number
|
||||
hi link _hdl_constant Constant
|
||||
hi link _hdl_assignment Operator
|
||||
hi link _hdl_pin_name Identifier
|
33
tools/vim/syntax/jack.vim
Normal file
33
tools/vim/syntax/jack.vim
Normal file
@@ -0,0 +1,33 @@
|
||||
" Vim syntax file
|
||||
" Language: Jack
|
||||
" Maintainer: Severyn Kozak
|
||||
" Latest Revision: 01 January 2015
|
||||
|
||||
if version < 600
|
||||
syntax clear
|
||||
endif
|
||||
|
||||
syn keyword jackDeclaration var static field class
|
||||
syn keyword jackStatement let if else while do return
|
||||
syn keyword jackVarType int char boolean void
|
||||
syn keyword jackFuncType constructor function method
|
||||
syn keyword jackConstant true false null this
|
||||
syn match jackOp "[-+*/&|<>=~]"
|
||||
syn match jackString '"[^"\n]*"'
|
||||
syn match jackNumber "\d\+"
|
||||
syn match jackDelimiter "[.,;]"
|
||||
syn match jackSurroundingElement "[{}()\[\]]"
|
||||
syn match jackCommentInline "\/\/.*"
|
||||
syn region jackCommentBlock start="/\*" end="*/"
|
||||
|
||||
hi link jackOp Operator
|
||||
hi link jackSurroundingElement Delimiter
|
||||
hi link jackVarType Type
|
||||
hi link jackFuncType Function
|
||||
hi link jackDeclaration Statement
|
||||
hi link jackStatement Statement
|
||||
hi link jackConstant Constant
|
||||
hi link jackNumber Number
|
||||
hi link jackCommentInline Comment
|
||||
hi link jackCommentBlock Comment
|
||||
hi link jackDelimiter Comment
|
49
tools/vim/syntax/nandhdl.vim
Normal file
49
tools/vim/syntax/nandhdl.vim
Normal file
@@ -0,0 +1,49 @@
|
||||
"Vim syntax file
|
||||
"Language: nand2tetris Hardware Description Language
|
||||
"Maintainer: Christopher Noussis
|
||||
"Latest Revision: 14 January 2015
|
||||
"TODO: Fix syntax names to work with accepted style convention
|
||||
"syn keyword [languageName][SyntaxElementName]
|
||||
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
"Comments.
|
||||
syn match hdlComment "\/\/.*$"
|
||||
syn region hdlComment start='\/\*' end='\*\/'
|
||||
syn region hdlComment start='\/\*\*' end='\*\/'
|
||||
|
||||
"The all-caps basic language keywords.
|
||||
syn keyword basicKeywords CHIP PARTS IN OUT BUILTIN CLOCKED
|
||||
|
||||
"Builtin chips.
|
||||
syn keyword builtInChips Nand Not And Or Xor Mux DMux
|
||||
syn keyword builtInChips Not16 And16 Or16 Mux16
|
||||
syn keyword builtInChips Or8Way Mux4Way16 Mux8Way16 DMux4Way DMux8Way
|
||||
syn keyword builtInChips HalfAdder FullAdder Add16 ALU Inc16
|
||||
syn keyword builtInChips DFF Bit Register ARegister DRegister
|
||||
syn keyword builtInChips RAM8 RAM64 RAM512 RAM4K RAM16K
|
||||
syn keyword builtInChips PC ROM32K Screen Keyboard
|
||||
|
||||
"External
|
||||
syn keyword extPin in out nextgroup=busNumber
|
||||
syn match busNumber '\[\d*\]' "TODO: Make it so the braces are not matched.
|
||||
syn region hdlInterface start='{' end='}' fold transparent
|
||||
|
||||
"Internal
|
||||
syn region hdlImplementation start=':' end='}' fold transparent
|
||||
syn region partInterface start='(' end=')' contains=connection, extPin
|
||||
"syn match connection '\w\+(\[\d+\])\*=\w\+(\[\d+\])\*'
|
||||
syn match connection '\w\+=\@=' contained
|
||||
syn match connection '=\@<=\w\+' contained
|
||||
|
||||
let b:current_syntax = 'chip'
|
||||
"Syntax Highlighting
|
||||
hi def link hdlComment Comment
|
||||
hi def link basicKeywords Statement
|
||||
hi def link builtInChips Special
|
||||
hi def link extPin Type
|
||||
hi def link busNumber Constant
|
||||
hi def link connection Identifier
|
||||
|
Reference in New Issue
Block a user