Add accelerated SPI program, update ecflash

This commit is contained in:
Jeremy Soller 2020-01-03 15:00:20 -07:00
parent 77035a9797
commit 873be2d664
No known key found for this signature in database
GPG Key ID: E988B49EE78A7FB1
3 changed files with 153 additions and 28 deletions

@ -1 +1 @@
Subproject commit 9ea915cef48dbe3b8dd678f5c9bfbb8fe3a05087 Subproject commit 4f21f47e5aa0ede123355d67f8c3f7324b66c5f0

View File

@ -208,6 +208,101 @@ int parallel_transaction(struct Parallel * port, uint8_t * data, int length, boo
#define parallel_read(P, D, L) parallel_transaction(P, D, L, true, false) #define parallel_read(P, D, L) parallel_transaction(P, D, L, true, false)
#define parallel_write(P, D, L) parallel_transaction(P, D, L, false, false) #define parallel_write(P, D, L) parallel_transaction(P, D, L, false, false)
static uint8_t ADDRESS_INDAR1 = 0x05;
static uint8_t ADDRESS_INDDR = 0x08;
static uint8_t ZERO = 0x00;
static uint8_t SPI_ENABLE = 0xFE;
static uint8_t SPI_DATA = 0xFD;
// Disable chip
int parallel_spi_reset(struct Parallel *port) {
int res;
res = parallel_set_address(port, &ADDRESS_INDAR1, 1);
if (res < 0) return res;
res = parallel_write(port, &SPI_ENABLE, 1);
if (res < 0) return res;
res = parallel_set_address(port, &ADDRESS_INDDR, 1);
if (res < 0) return res;
return parallel_write(port, &ZERO, 1);
}
// Enable chip and read or write data
int parallel_spi_transaction(struct Parallel *port, uint8_t * data, int length, bool read) {
int res;
res = parallel_set_address(port, &ADDRESS_INDAR1, 1);
if (res < 0) return res;
res = parallel_write(port, &SPI_DATA, 1);
if (res < 0) return res;
res = parallel_set_address(port, &ADDRESS_INDDR, 1);
if (res < 0) return res;
return parallel_transaction(port, data, length, read, false);
}
#define parallel_spi_read(P, D, L) parallel_spi_transaction(P, D, L, true)
#define parallel_spi_write(P, D, L) parallel_spi_transaction(P, D, L, false)
// "Hardware" accelerated SPI programming, requires ECINDARs to be set
int parallel_spi_program(struct Parallel * port, uint8_t * data, int length, bool initialized) {
static uint8_t aai[6] = { 0xAD, 0, 0, 0, 0, 0 };
int res;
int i;
uint8_t status;
for(i = 0; (i + 1) < length; i+=2) {
// Disable chip to begin command
res = parallel_spi_reset(port);
if (res < 0) return res;
if (!initialized) {
// If not initialized, the start address must be sent
aai[1] = 0;
aai[2] = 0;
aai[3] = 0;
aai[4] = data[i];
aai[5] = data[i + 1];
res = parallel_spi_write(port, aai, 6);
if (res < 0) return res;
initialized = true;
} else {
aai[1] = data[i];
aai[2] = data[i + 1];
res = parallel_spi_write(port, aai, 3);
if (res < 0) return res;
}
// Wait for SPI busy flag to clear
for (;;) {
// Disable chip to begin command
res = parallel_spi_reset(port);
if (res < 0) return res;
status = 0x05;
res = parallel_spi_write(port, &status, 1);
if (res < 0) return res;
res = parallel_spi_read(port, &status, 1);
if (res < 0) return res;
if (!(status & 1)) break;
}
}
return i;
}
int serial_transaction(uint8_t * data, int length, bool read) { int serial_transaction(uint8_t * data, int length, bool read) {
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
@ -234,17 +329,29 @@ int parallel_main(void) {
char command; char command;
int length; int length;
int i; int i;
uint8_t address;
bool set_address = false;
bool program_aai = false;
for (;;) { for (;;) {
// Read command and length // Read command and length
res = serial_read(data, 3); res = serial_read(data, 2);
if (res < 0) goto err; if (res < 0) goto err;
// Command is a character // Command is a character
command = (char)data[0]; command = (char)data[0];
// Special address prefix
if (command == 'A') {
// Prepare to set address on next parallel cycle
address = data[1];
set_address = true;
continue;
} else if (command != 'P') {
// End accelerated programming
program_aai = false;
}
// Length is received data + 1 // Length is received data + 1
length = ( length = ((int)data[1]) + 1;
((int)data[1]) |
(((int)data[2]) << 8)
) + 1;
// Truncate length to size of data // Truncate length to size of data
if (length > sizeof(data)) length = sizeof(data); if (length > sizeof(data)) length = sizeof(data);
@ -253,10 +360,8 @@ int parallel_main(void) {
case 'B': case 'B':
// Fill buffer size - 1 // Fill buffer size - 1
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (i < 2) { if (i == 0) {
data[i] = (uint8_t)( data[i] = (uint8_t)(sizeof(data) - 1);
(sizeof(data) - 1) >> (i * 8)
);
} else { } else {
data[i] = 0; data[i] = 0;
} }
@ -280,20 +385,15 @@ int parallel_main(void) {
break; break;
// Set address
case 'A':
// Read data from serial
res = serial_read(data, length);
if (res < 0) goto err;
// Write address to parallel
res = parallel_set_address(port, data, length);
if (res < 0) goto err;
break;
// Read data // Read data
case 'R': case 'R':
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0) goto err;
set_address = false;
}
// Read data from parallel // Read data from parallel
res = parallel_read(port, data, length); res = parallel_read(port, data, length);
if (res < 0) goto err; if (res < 0) goto err;
@ -304,23 +404,48 @@ int parallel_main(void) {
break; break;
// Accelerated program function
case 'P':
// Read data from serial
res = serial_read(data, length);
if (res < 0) goto err;
// Run accelerated programming function
res = parallel_spi_program(port, data, length, program_aai);
if (res < 0) goto err;
program_aai = true;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0) goto err;
break;
// Write data // Write data
case 'W': case 'W':
// Read data from serial // Read data from serial
res = serial_read(data, length); res = serial_read(data, length);
if (res < 0) goto err; if (res < 0) goto err;
// Update parallel address if necessary
if (set_address) {
res = parallel_set_address(port, &address, 1);
if (res < 0) goto err;
set_address = false;
}
// Write data to parallel // Write data to parallel
res = parallel_write(port, data, length); res = parallel_write(port, data, length);
if (res < 0) goto err; if (res < 0) goto err;
// Send ACK of data length
data[0] = (uint8_t)(length - 1);
res = serial_write(data, 1);
if (res < 0) goto err;
break; break;
} }
// Send ACK
data[0] = '\r';
res = serial_write(data, 1);
if (res < 0) goto err;
} }
err: err:

View File

@ -2,7 +2,7 @@
#include <common/debug.h> #include <common/debug.h>
// Set the desired keymap here // Set the desired keymap here
#include "keymap/jeremy.h" #include "keymap/default.h"
uint16_t keymap(int output, int input, int layer) { uint16_t keymap(int output, int input, int layer) {
if (output < KM_OUT && input < KM_IN && layer < KM_LAY) { if (output < KM_OUT && input < KM_IN && layer < KM_LAY) {