Skip to content

Performance #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion spi_flash_programmer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
#define COMMAND_HELP '?'
#define COMMAND_BUFFER_CRC 'h'
#define COMMAND_BUFFER_LOAD 'l'
#define COMMAND_BUFFER_LOAD_BINARY 'L'
#define COMMAND_BUFFER_STORE 's'
#define COMMAND_BUFFER_STORE_BINARY 'S'
#define COMMAND_FLASH_READ 'r'
#define COMMAND_FLASH_WRITE 'w'
#define COMMAND_FLASH_ERASE_SECTOR 'k'
Expand Down Expand Up @@ -39,8 +41,10 @@
#define PAGE_SIZE 256

void dump_buffer(void);
void dump_buffer_binary(void);
void dump_buffer_crc(void);
int8_t read_into_buffer(void);
int8_t read_into_buffer_binary(void);

void erase_all(void);
void erase_sector(uint32_t address);
Expand Down Expand Up @@ -158,6 +162,12 @@ void loop()
Serial.println();
break;

case COMMAND_BUFFER_LOAD_BINARY:
Serial.print(COMMAND_BUFFER_LOAD_BINARY); // Echo OK
dump_buffer_binary();
Serial.println();
break;

case COMMAND_BUFFER_CRC:
Serial.print(COMMAND_BUFFER_CRC); // Echo OK
dump_buffer_crc();
Expand All @@ -174,6 +184,16 @@ void loop()
dump_buffer_crc();
break;

case COMMAND_BUFFER_STORE_BINARY:
if (!read_into_buffer_binary()) {
Serial.print(COMMAND_ERROR); // Echo Error
break;
}

Serial.print(COMMAND_BUFFER_STORE_BINARY); // Echo OK
dump_buffer_crc();
break;

case COMMAND_WRITE_PROTECTION_CHECK:
Serial.print(COMMAND_WRITE_PROTECTION_CHECK); // Echo OK
impl_write_protection_check();
Expand Down Expand Up @@ -326,6 +346,15 @@ void dump_buffer(void)
}
}

void dump_buffer_binary(void)
{
uint16_t counter;

for(counter = 0; counter < PAGE_SIZE; counter++) {
Serial.write(buffer[counter]);
}
}

void dump_buffer_crc(void)
{
uint32_t crc = crc_buffer();
Expand All @@ -349,6 +378,22 @@ int8_t read_into_buffer(void)
return 1;
}

int8_t read_into_buffer_binary(void)
{
uint16_t counter;
int16_t c;

for(counter = 0; counter < PAGE_SIZE; counter++) {
do {
c = Serial.read();
} while(c == -1);

buffer[counter] = (uint8_t) c;
}

return 1;
}

int8_t read_nibble(void)
{
int16_t c;
Expand Down Expand Up @@ -762,4 +807,3 @@ void impl_jedec_id_read(void)
write_hex_u8(SPI.transfer(0x0));
digitalWrite(nCsIo, HIGH);
}

91 changes: 86 additions & 5 deletions spi_flash_programmer_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

COMMAND_BUFFER_CRC = 'h'
COMMAND_BUFFER_LOAD = 'l'
COMMAND_BUFFER_LOAD_BINARY = 'L'
COMMAND_BUFFER_STORE = 's'
COMMAND_BUFFER_STORE_BINARY = 'S'

COMMAND_FLASH_READ = 'r'
COMMAND_FLASH_WRITE = 'w'
Expand Down Expand Up @@ -85,8 +87,6 @@ def __init__(self, port, baud_rate, debug='off', sector_size=DEFAULT_SECTOR_SIZE
self.sock = serial.Serial(port, baud_rate, timeout=1)
self._debug('Serial connection opened successfully')

time.sleep(2) # Wait for the Arduino bootloader

def _debug(self, message, level=DEBUG_NORMAL):
if self.debug >= level:
logDebug(message, level)
Expand Down Expand Up @@ -295,6 +295,43 @@ def _readPage(self, page, tries=3):
self._debug('Page read tries exceeded')
return None

def _readPageBinary(self, page, tries=3):
"""Read a page from the flash and receive it's contents"""
self._debug('Command: FLASH_READ_PAGE %d' % page)

# Load page into the buffer
crc = self._loadPageMultiple(page, tries)

for _ in range(tries):
# Dump the buffer
self._sendCommand(COMMAND_BUFFER_LOAD_BINARY)

# Wait for data start
if not self._waitForMessage(COMMAND_BUFFER_LOAD_BINARY):
self._debug('Invalid / no response for BUFFER_LOAD_BINARY command')
continue

# Load successful -> read sector
data = self._readExactly(self.page_size)
if data is None:
self._debug('Invalid / no response for page data')
continue

try:
if crc == binascii.crc32(data):
self._debug('CRC did match with read data')
return data
else:
self._debug('CRC did not match with read data')
continue

except TypeError:
self._debug('CRC could not be parsed')
continue

self._debug('Page read tries exceeded')
return None

def _writePage(self, page, data):
"""Write a page into the buffer and instruct a page write operation

Expand Down Expand Up @@ -326,7 +363,51 @@ def _writePage(self, page, data):

# Write page
self._sendCommand('%s%08x' % (COMMAND_FLASH_WRITE, page))
time.sleep(.2) # Sleep 200 ms

if not self._waitForMessage(COMMAND_FLASH_WRITE):
self._debug('Invalid / no response for FLASH_WRITE command')
return False

# Read back page
# Fail if we can't read what we wrote
read_crc = self._loadPageMultiple(page)
if read_crc is None:
self._debug('Invalid / no CRC response for flash write')
return False

return (read_crc == expected_crc)

def _writePageBinary(self, page, data):
"""Write a page into the buffer and instruct a page write operation

This operation checks the written data with a generated checksum.
"""
assert len(data) == self.page_size, (len(data), data)

# Write the page and verify that it was written correctly.
expected_crc = binascii.crc32(data)

self.sock.write(bytes(COMMAND_BUFFER_STORE_BINARY,ENCODING) + data)
self.sock.flush()
if not self._waitForMessage(COMMAND_BUFFER_STORE_BINARY):
self._debug('Invalid / no response for BUFFER_STORE_BINARY command')
return False

# This shouldn't fail if we're using a reliable connection.
crc = self._readExactly(8).decode(ENCODING)
if crc is None:
self._debug('Invalid / no CRC response for buffer write')
return None

try:
if int(crc, 16) != expected_crc:
return None
except ValueError:
self._debug('Could not decode CRC')
return None

# Write page
self._sendCommand('%s%08x' % (COMMAND_FLASH_WRITE, page))

if not self._waitForMessage(COMMAND_FLASH_WRITE):
self._debug('Invalid / no response for FLASH_WRITE command')
Expand Down Expand Up @@ -376,7 +457,7 @@ def _writeSectors(self, offset, data, tries=3):
data_index = page_data_index * self.page_size
page_index = pages_offset + page_data_index

if self._writePage(page_index, data[data_index: data_index + self.page_size]):
if self._writePageBinary(page_index, data[data_index: data_index + self.page_size]):
bar.show(page_data_index + 1)
continue

Expand Down Expand Up @@ -560,7 +641,7 @@ def readToFile(self, filename, flash_offset=0, length=DEFAULT_FLASH_SIZE):
bar.show(page)

page_index = pages_offset + page
data = self._readPage(page_index)
data = self._readPageBinary(page_index)
if data is not None:
file.write(data)
continue
Expand Down