mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
more merging
This commit is contained in:
parent
274d9658bb
commit
8cf17c7fdf
11
.gdbinit
11
.gdbinit
@ -76,3 +76,14 @@ define execflags
|
||||
end
|
||||
end
|
||||
|
||||
define hook-stop
|
||||
set $primask=1
|
||||
end
|
||||
|
||||
define hook-run
|
||||
set $primask=0
|
||||
end
|
||||
|
||||
define hook-continue
|
||||
set $primask=0
|
||||
end
|
||||
|
||||
@ -133,7 +133,8 @@ This is a partial list of definitions that can be added in a `BOARD.py` file's `
|
||||
* `USE_NETWORK_JS=0` - Don't include JS networking lib used for handling AT commands (default is yes if networking is enabled)
|
||||
* `ESPR_DCDC_ENABLE` - On NRF52 use the built-in DCDC converter (requires external hardware)
|
||||
* `ESPR_LSE_ENABLE` - On NRF52 use an external 32kHz Low Speed External crystal on D0/D1
|
||||
|
||||
* `ESPR_NO_LOADING_SCREEN` - Bangle.js, don't show a 'loading' screen when loading a new app
|
||||
* `ESPR_BOOTLOADER_SPIFLASH` - Allow bootloader to flash direct from a file in SPI flash storage
|
||||
|
||||
### chip
|
||||
|
||||
|
||||
@ -21,3 +21,4 @@ void lcdSetPixel_ArrayBuffer_flat8(JsGraphics *gfx, int x, int y, unsigned int c
|
||||
unsigned int lcdGetPixel_ArrayBuffer_flat8(struct JsGraphics *gfx, int x, int y);
|
||||
void lcdFillRect_ArrayBuffer_flat8(JsGraphics *gfx, int x1, int y1, int x2, int y2, unsigned int col);
|
||||
void lcdScroll_ArrayBuffer_flat8(JsGraphics *gfx, int xdir, int ydir, int x1, int y1, int x2, int y2);
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
var PAGESIZE = 4096;
|
||||
var FLASH_OFFSET = 0x60300000;
|
||||
var VERSION = 0xDEADBEEF; // VERSION! Use this to test firmware in JS land
|
||||
var DEBUG = false;
|
||||
|
||||
if (process.argv.length!=3) {
|
||||
console.error("USAGE: hex_to_bootloader.js inputfile.hex");
|
||||
@ -16,16 +17,17 @@ if (process.argv.length!=3) {
|
||||
var inputFile = process.argv[2];
|
||||
|
||||
var hex = require("fs").readFileSync(inputFile).toString().split("\n");
|
||||
var addrHi = 0;
|
||||
function parseLines(dataCallback) {
|
||||
var addrHi = 0;
|
||||
hex.forEach(function(hexline) {
|
||||
var cmd = hexline.substr(1,2);
|
||||
if (cmd=="02") {
|
||||
var subcmd = hexline.substr(7,2);
|
||||
if (subcmd=="02") addrHi = parseInt(hexline.substr(9,4),16) << 4; // Extended Segment Address
|
||||
if (subcmd=="04") addrHi = parseInt(hexline.substr(9,4),16) << 16; // Extended Linear Address
|
||||
} else if (cmd=="10") {
|
||||
var addr = addrHi + parseInt(hexline.substr(3,4),16);
|
||||
if (DEBUG) console.log(hexline);
|
||||
var bytes = hexline.substr(1,2);
|
||||
var addrLo = parseInt(hexline.substr(3,4),16);
|
||||
var cmd = hexline.substr(7,2);
|
||||
if (cmd=="02") addrHi = parseInt(hexline.substr(9,4),16) << 4; // Extended Segment Address
|
||||
else if (cmd=="04") addrHi = parseInt(hexline.substr(9,4),16) << 16; // Extended Linear Address
|
||||
else if (cmd=="00") {
|
||||
var addr = addrHi + addrLo;
|
||||
var data = [];
|
||||
for (var i=0;i<16;i++) data.push(parseInt(hexline.substr(9+(i*2),2),16));
|
||||
dataCallback(addr,data);
|
||||
@ -89,14 +91,21 @@ console.log(`// Data from 0x${startAddress.toString(16)} to 0x${endAddress.toStr
|
||||
// Work out data
|
||||
var headerLen = 16;
|
||||
var binary = new Uint8Array(headerLen + endAddress-startAddress);
|
||||
binary.fill(0xFF);
|
||||
binary.fill(0); // actually seems to assume a block is filled with 0 if not complete
|
||||
var bin32 = new Uint32Array(binary.buffer);
|
||||
parseLines(function(addr, data) {
|
||||
var binAddr = headerLen + addr - startAddress;
|
||||
binary.set(data, binAddr);
|
||||
//console.log("i",binAddr, data);
|
||||
if (DEBUG) console.log("i",addr.toString(16).padStart(8,0), data.map(x=>x.toString(16).padStart(2,0)).join(" "));
|
||||
//console.log("o",new Uint8Array(binary.buffer, binAddr, data.length));
|
||||
});
|
||||
|
||||
if (DEBUG) {
|
||||
for (var i=0;i<binary.length;i+=16)
|
||||
console.log((i+startAddress-headerLen).toString(16).padStart(8,0), Array.from(new Uint8Array(binary.buffer, i, 16)).map(x=>x.toString(16).padStart(2,0)).join(" "));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
/* typedef struct {
|
||||
uint32_t address;
|
||||
uint32_t size;
|
||||
|
||||
@ -62,7 +62,7 @@ __attribute__( ( long_call, section(".data") ) ) static void spiFlashWriteCS(uns
|
||||
NRF_GPIO_PIN_SET_FAST((uint32_t)pinInfo[SPIFLASH_PIN_CS].pin);
|
||||
}
|
||||
|
||||
static unsigned char spiFlashStatus() {
|
||||
__attribute__( ( long_call, section(".data") ) ) static unsigned char spiFlashStatus() {
|
||||
unsigned char buf = 5;
|
||||
NRF_GPIO_PIN_CLEAR_FAST((uint32_t)pinInfo[SPIFLASH_PIN_CS].pin);
|
||||
spiFlashWrite(&buf, 1);
|
||||
@ -71,6 +71,13 @@ static unsigned char spiFlashStatus() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Wake up the SPI Flash from deep power-down mode
|
||||
static void flashWakeUp() {
|
||||
unsigned char buf = 0xAB; // SPI Flash release from deep power-down
|
||||
spiFlashWriteCS(&buf,1);
|
||||
nrf_delay_us(50); // Wait at least 20us for Flash IC to wake up from deep power-down
|
||||
}
|
||||
|
||||
void spiFlashInit() {
|
||||
#ifdef SPIFLASH_PIN_WP
|
||||
nrf_gpio_pin_write_output((uint32_t)pinInfo[SPIFLASH_PIN_WP].pin, 0);
|
||||
@ -85,6 +92,11 @@ void spiFlashInit() {
|
||||
nrf_gpio_pin_write((uint32_t)pinInfo[SPIFLASH_PIN_RST].pin, 1);
|
||||
#endif
|
||||
nrf_delay_us(100);
|
||||
#ifdef SPIFLASH_SLEEP_CMD
|
||||
// Release from deep power-down - might need a couple of attempts...?
|
||||
flashWakeUp();
|
||||
flashWakeUp();
|
||||
#endif
|
||||
// disable lock bits
|
||||
// wait for write enable
|
||||
unsigned char buf[2];
|
||||
@ -172,7 +184,7 @@ __attribute__( ( long_call, section(".data") ) ) void xlcd_wr(int data) {
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__( ( long_call, section(".data") ) ) void xlcd_rect(int x1,int y1, int x2, int y2) {
|
||||
__attribute__( ( long_call, section(".data") ) ) void xlcd_rect(int x1,int y1, int x2, int y2, bool white) {
|
||||
NRF_GPIO_PIN_WRITE_FAST(LCD_SPI_DC, 0); // command
|
||||
NRF_GPIO_PIN_WRITE_FAST(LCD_SPI_CS, 0);
|
||||
xlcd_wr(0x2A);
|
||||
@ -203,7 +215,7 @@ __attribute__( ( long_call, section(".data") ) ) void xlcd_rect(int x1,int y1, i
|
||||
NRF_GPIO_PIN_WRITE_FAST(LCD_SPI_CS, 0);
|
||||
int l = (x2+1-x1) * (y2+1-y1);
|
||||
for (int x=0;x<l*2;x++)
|
||||
xlcd_wr(0xFF);
|
||||
xlcd_wr(white ? 0xFF : 0);
|
||||
NRF_GPIO_PIN_WRITE_FAST(LCD_SPI_CS,1);
|
||||
}
|
||||
|
||||
@ -223,7 +235,7 @@ __attribute__( ( long_call, section(".data") ) ) void flashDoUpdate(FlashHeader
|
||||
size -= 4096;
|
||||
percent = (addr-header.address)*120/header.size;
|
||||
if (percent>120) percent=120;
|
||||
xlcd_rect(60,182,60+percent,188);
|
||||
xlcd_rect(60,182,60+percent,188,true);
|
||||
NRF_WDT->RR[0] = 0x6E524635; // kick watchdog
|
||||
}
|
||||
// Write
|
||||
@ -240,21 +252,28 @@ __attribute__( ( long_call, section(".data") ) ) void flashDoUpdate(FlashHeader
|
||||
size -= l;
|
||||
percent = (outaddr-header.address)*120/header.size;
|
||||
if (percent>120) percent=120;
|
||||
xlcd_rect(60,192,60+percent,198);
|
||||
xlcd_rect(60,192,60+percent,198,true);
|
||||
NRF_WDT->RR[0] = 0x6E524635; // kick watchdog
|
||||
}
|
||||
//flashEqual(header);
|
||||
// clear progress bar
|
||||
xlcd_rect(60,180,180,200,false);
|
||||
// re-read all data just to try and clear any caches
|
||||
size = header.size;
|
||||
outaddr = header.address;
|
||||
volatile int v;
|
||||
while (size--) {
|
||||
v = *(char*)outaddr;
|
||||
outaddr++;
|
||||
}
|
||||
// done!
|
||||
for (volatile int i=0;i<10000000;i++); // delay
|
||||
NVIC_SystemReset(); // reset!
|
||||
while (true) NVIC_SystemReset(); // reset!
|
||||
}
|
||||
|
||||
|
||||
void flashCheckAndRun() {
|
||||
spiFlashInit();
|
||||
FlashHeader header;
|
||||
spiFlashReadAddr((unsigned char *)&header, FLASH_HEADER_ADDRESS, sizeof(FlashHeader));
|
||||
if (header.address==0xFFFFFFFF) {
|
||||
if (header.address==0xFFFFFFFF || header.size==0) {
|
||||
// Not set - silently exit
|
||||
return;
|
||||
}
|
||||
@ -263,8 +282,9 @@ void flashCheckAndRun() {
|
||||
lcd_print_hex(header.size); lcd_println(" SIZE");
|
||||
lcd_print_hex(header.CRC); lcd_println(" CRC");
|
||||
lcd_print_hex(header.version); lcd_println(" VERSION");
|
||||
// if (header.address==0xf7000) return; // NO BOOTLOADER - FOR TESTINGs
|
||||
if (header.address==0xf7000) return; // NO BOOTLOADER - FOR TESTING
|
||||
// Calculate CRC
|
||||
lcd_println("CRC TEST...");
|
||||
unsigned char buf[256];
|
||||
int size = header.size;
|
||||
int inaddr = FLASH_HEADER_ADDRESS + sizeof(FlashHeader);
|
||||
@ -277,24 +297,68 @@ void flashCheckAndRun() {
|
||||
inaddr += l;
|
||||
size -= l;
|
||||
}
|
||||
bool isEqual = false;
|
||||
if (crc != header.CRC) {
|
||||
// CRC is wrong - exits
|
||||
lcd_println("CRC MISMATCH");
|
||||
lcd_print_hex(crc); lcd_println("");lcd_println("");
|
||||
nrf_delay_us(1000000);
|
||||
for (volatile int i=0;i<5000000;i++) NRF_WDT->RR[0] = 0x6E524635; // delay
|
||||
} else {
|
||||
// All ok - check we haven't already flashed this!
|
||||
lcd_println("TESTING...");
|
||||
isEqual = flashEqual(header);
|
||||
}
|
||||
lcd_println("REMOVE HEADER.");
|
||||
// Now erase the first page of flash so we don't get into a boot loop
|
||||
unsigned char b[20];
|
||||
b[0] = 0x06; // WREN
|
||||
spiFlashWriteCS(b,1);
|
||||
for (volatile int i=0;i<1000;i++);
|
||||
b[0] = 0x02; // Write
|
||||
b[1] = FLASH_HEADER_ADDRESS>>16;
|
||||
b[2] = FLASH_HEADER_ADDRESS>>8;
|
||||
b[3] = FLASH_HEADER_ADDRESS;
|
||||
memset(&b[4], 0, 16);
|
||||
spiFlashWriteCS(b,4+16); // write command plus 16 bytes of zeros
|
||||
// Check if flash busy
|
||||
while (spiFlashStatus()&1); // while 'Write in Progress'...
|
||||
FlashHeader header2;
|
||||
spiFlashReadAddr((unsigned char *)&header2, FLASH_HEADER_ADDRESS, sizeof(FlashHeader));
|
||||
// read a second time just in case
|
||||
spiFlashReadAddr((unsigned char *)&header2, FLASH_HEADER_ADDRESS, sizeof(FlashHeader));
|
||||
if (header2.address != 0) {
|
||||
lcd_println("ERASE FAIL. EXIT.");
|
||||
for (volatile int i=0;i<5000000;i++) NRF_WDT->RR[0] = 0x6E524635; // delay
|
||||
return;
|
||||
}
|
||||
// All ok - check we haven't already flashed this!
|
||||
if (!flashEqual(header)) {
|
||||
|
||||
if (!isEqual) {
|
||||
lcd_println("BINARY DIFF. FLASHING...");
|
||||
xlcd_rect(60,180,180,180);
|
||||
xlcd_rect(60,190,180,190);
|
||||
xlcd_rect(60,200,180,200);
|
||||
|
||||
xlcd_rect(60,180,180,180,true);
|
||||
xlcd_rect(60,190,180,190,true);
|
||||
xlcd_rect(60,200,180,200,true);
|
||||
|
||||
flashDoUpdate(header);
|
||||
|
||||
/*isEqual = flashEqual(header);
|
||||
if (isEqual) lcd_println("EQUAL");
|
||||
else lcd_println("NOT EQUAL");
|
||||
|
||||
for (volatile int i=0;i<5000000;i++) NRF_WDT->RR[0] = 0x6E524635; // delay
|
||||
while (true) NVIC_SystemReset(); */
|
||||
} else {
|
||||
lcd_println("BINARY MATCHES.");
|
||||
}
|
||||
}
|
||||
|
||||
// Put the SPI Flash into deep power-down mode
|
||||
void flashPowerDown() {
|
||||
spiFlashInit(); //
|
||||
unsigned char buf = 0xB9; // SPI Flash deep power-down
|
||||
spiFlashWriteCS(&buf,1);
|
||||
nrf_delay_us(2); // Wait at least 1us for Flash IC to enter deep power-down
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -14,4 +14,5 @@
|
||||
|
||||
#ifdef ESPR_BOOTLOADER_SPIFLASH
|
||||
void flashCheckAndRun();
|
||||
void flashPowerDown();
|
||||
#endif
|
||||
|
||||
@ -577,49 +577,75 @@ static const char SPILCD_INIT_CODE[] = {
|
||||
0x13, 10, 0,
|
||||
#endif
|
||||
#ifdef LCD_CONTROLLER_GC9A01
|
||||
// CMD,DELAY,DATA_LEN,D0,D1,D2...
|
||||
0xfe,0,0,
|
||||
0xef,0,0,
|
||||
0xeb,0,1, 0x14,
|
||||
0x84,0,1, 0x40,
|
||||
0x84,0,1, 0x60, // 0x40->0x60 0xb5 en 20200924 james
|
||||
0x85,0,1, 0xFF,
|
||||
0x86,0,1, 0xFF,
|
||||
0x87,0,1, 0xFF,
|
||||
0x8e,0,1, 0xFF,
|
||||
0x8f,0,1, 0xFF,
|
||||
0x88,0,1, 10,
|
||||
0x89,0,1, 0x21,
|
||||
0x89,0,1, 0x23, // 0x21->0x23 spi 2data reg en
|
||||
0x8a,0,1, 0,
|
||||
0x8b,0,1, 0x80,
|
||||
0x8c,0,1, 1,
|
||||
0x8d,0,1, 1,
|
||||
0xb6,0,1, 0x20,
|
||||
0x36,0,1, 0x88, // Memory Access Control (0x48 flips upside-down)
|
||||
0x8d,0,1, 3, // 1->3 99 en
|
||||
0xb5,0,4, 0x08, 0x09, 0x14, 0x08,
|
||||
0xb6,0,2, 0, 0, // Positive sweep 0x20->0 GS SS 0x20
|
||||
#ifdef LCD_ROTATION
|
||||
#if (LCD_ROTATION == 0)
|
||||
0x36,0,1, 0x88, // Memory Access Control (no rotation)
|
||||
#elif (LCD_ROTATION == 90)
|
||||
0x36,0,1, 0x78, // Memory Access Control (rotated 90 degrees)
|
||||
#elif (LCD_ROTATION == 180)
|
||||
0x36,0,1, 0x48, // Memory Access Control (rotated 180 degrees)
|
||||
#elif (LCD_ROTATION == 270)
|
||||
0x36,0,1, 0xB8, // Memory Access Control (rotated 270 degrees)
|
||||
#else
|
||||
#error "Unexpected value defined for LCD_ROTATION - should be 0, 90, 180 or 270"
|
||||
#endif
|
||||
#else
|
||||
0x36,0,1, 0x88, // Memory Access Control (no rotation)
|
||||
#endif
|
||||
0x3a,0,1, 5, // could be 16/12 bit?
|
||||
0x90,0,4, 8, 8, 8, 8,
|
||||
0xbd,0,1, 6,
|
||||
0xbc,0,1, 0,
|
||||
0xff,0,3, 0x60, 1, 4,
|
||||
0xc3,0,1, 0x13,
|
||||
0xc4,0,1, 0x13,
|
||||
0xc9,0,1, 0x22,
|
||||
0xc3,0,1, 0x1d, // Power control 2: 0x13->0x1d
|
||||
0xc4,0,1, 0x1d, // Power control 3: 0x13->0x1d
|
||||
0xc9,0,1, 0x25, // Power control 4: 0x22->0x25
|
||||
0xbe,0,1, 0x11,
|
||||
0xe1,0,2, 0x10, 0xe,
|
||||
0xdf,0,3, 0x21, 0xc, 2,
|
||||
0xf0,0,6, 0x45, 9, 8, 8, 0x26, 0x2a,
|
||||
0xf1,0,6, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6f,
|
||||
0xf2,0,6, 0x45, 9, 8, 8, 0x26, 0x2a,
|
||||
0xf3,0,6, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6f,
|
||||
0xf0,0,6, 0x45, 9, 8, 8, 0x26, 0x2a, // Gamma 1
|
||||
0xf1,0,6, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6f, // Gamma 2
|
||||
0xf2,0,6, 0x45, 9, 8, 8, 0x26, 0x2a, // Gamma 3
|
||||
0xf3,0,6, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6f, // Gamma 4
|
||||
0xed,0,2, 0x1b, 0xb,
|
||||
0xae,0,1, 0x74,
|
||||
0xae,0,1, 0x77, // 0x74->0x77
|
||||
0xcd,0,1, 99,
|
||||
0x70,0,9, 7, 9, 4, 0xe, 0xf, 9, 7, 8, 3,
|
||||
0x70,0,9, 7, 7, 4, 0xe, 0xf, 9, 7, 8, 3, // 7,9,4... -> 7,7,4...
|
||||
0xe8,0,1, 0x34,
|
||||
0x62,0,12, 0x18, 0xd, 0x71, 0xed, 0x70, 0x70, 0x18, 0xf, 0x71, 0xef, 0x70, 0x70,
|
||||
99,0,12, 0x18, 0x11, 0x71, 0xf1, 0x70, 0x70, 0x18, 0x13, 0x71, 0xf3, 0x70, 0x70,
|
||||
0x60,0,4, 0x38, 0x0b, 0x6d, 0x6d,
|
||||
0x39,0,3, 0xf0, 0x6d, 0x6d,
|
||||
0x61,0,4, 0x38, 0xf4, 0x6d, 0x6d,
|
||||
0x38,0,3, 0xf7, 0x6d, 0x6d,
|
||||
0x62,0,12, 0x38, 0xd, 0x71, 0xed, 0x70, 0x70, 0x38, 0xf, 0x71, 0xef, 0x70, 0x70,
|
||||
0x63,0,12, 0x38, 0x11, 0x71, 0xf1, 0x70, 0x70, 0x38, 0x13, 0x71, 0xf3, 0x70, 0x70,
|
||||
100,0,7, 0x28, 0x29, 0xf1, 1, 0xf1, 0, 7,
|
||||
0x66,0,10, 0x3c, 0, 0xcd, 0x67, 0x45, 0x45, 0x10, 0, 0, 0,
|
||||
0x67,0,10, 0, 0x3c, 0, 0, 0, 1, 0x54, 0x10, 0x32, 0x98,
|
||||
0x74,0,7, 0x10, 0x85, 0x80, 0, 0, 0x4e, 0,
|
||||
0x98,0,2, 0x3e, 7,
|
||||
0x35,0,0,
|
||||
0x21,10,0,
|
||||
0x11,20,0,
|
||||
0x29,10,0,
|
||||
0x99,0,2, 0x3e, 7, // bvee 2x
|
||||
0x35,0,1, 0,
|
||||
0x21,5,0,
|
||||
0x11,5,0,
|
||||
0x29,5,0,
|
||||
0x2c,0,0,
|
||||
#endif
|
||||
// End
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user