Skip to content

Commit

Permalink
Merge branch 'sst39sf'
Browse files Browse the repository at this point in the history
  • Loading branch information
henols committed Nov 22, 2024
2 parents 8fed34b + bf688e5 commit a93b814
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 10 deletions.
10 changes: 8 additions & 2 deletions include/firestarter.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,20 @@ typedef struct firestarter_handle {
bus_config_t bus_config;

void (*firestarter_set_data)(struct firestarter_handle*, uint32_t, uint8_t);
uint8_t(*firestarter_get_data)(struct firestarter_handle*, uint32_t);

void (*firestarter_write_init)(struct firestarter_handle*);
void (*firestarter_write_data)(struct firestarter_handle*);
uint8_t(*firestarter_get_data)(struct firestarter_handle*, uint32_t);

void (*firestarter_read_init)(struct firestarter_handle*);
void(*firestarter_read_data)(struct firestarter_handle*);
void (*firestarter_read_data)(struct firestarter_handle*);

void (*firestarter_erase)(struct firestarter_handle*);

void (*firestarter_blank_check)(struct firestarter_handle*);

void (*firestarter_set_address)(struct firestarter_handle*, uint32_t);

void (*firestarter_set_control_register)(struct firestarter_handle*, register_t, bool);
bool (*firestarter_get_control_register)(struct firestarter_handle*, register_t);

Expand Down
22 changes: 22 additions & 0 deletions include/flash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Project Name: Firestarter
* Copyright (c) 2024 Henrik Olsson
*
* Permission is hereby granted under MIT license.
*/

#ifndef FALSH_H
#define FLASH_H

#ifdef __cplusplus
extern "C" {
#endif
#include "firestarter.h"

void configure_flash(firestarter_handle_t* handle);

#ifdef __cplusplus
}
#endif

#endif // FLASH_H
2 changes: 1 addition & 1 deletion include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@



#define VERSION "1.1.7"
#define VERSION "1.2.0"

#endif // VERSION_H
227 changes: 227 additions & 0 deletions src/flash.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/*
* Project Name: Firestarter
* Copyright (c) 2024 Henrik Olsson
*
* Permission is hereby granted under MIT license.
*/

#include <Arduino.h>
#include "flash.h"
#include "firestarter.h"
#include "rurp_shield.h"
#include "logging.h"
#include <stdio.h>
#include "debug.h"


typedef struct byte_flip
{
uint32_t address;
uint8_t byte;
} byte_flip_t;


void flash_erase(firestarter_handle_t* handle);
void flash_blank_check(firestarter_handle_t* handle);
void flash_read_init(firestarter_handle_t* handle);
void flash_write_init(firestarter_handle_t* handle);
void flash_write_data(firestarter_handle_t* handle);
uint16_t flash_get_chip_id(firestarter_handle_t* handle);
void flash_check_chip_id(firestarter_handle_t* handle);

void enable_write(firestarter_handle_t* handle);
void internal_erase(firestarter_handle_t* handle);
void flip_data(firestarter_handle_t* handle, uint32_t address, uint8_t data);
void fast_address(firestarter_handle_t* handle, uint32_t address);
void verify_operation(firestarter_handle_t* handle, uint8_t expected_data);


void configure_flash(firestarter_handle_t* handle) {
debug("Configuring Flash");
handle->firestarter_read_init = flash_read_init;
handle->firestarter_write_init = flash_write_init;
handle->firestarter_erase = flash_erase;
handle->firestarter_blank_check = flash_blank_check;
handle->firestarter_write_data = flash_write_data;
}

void flash_read_init(firestarter_handle_t* handle) {
if (handle->chip_id > 0) {
flash_check_chip_id(handle);
if (handle->response_code == RESPONSE_CODE_ERROR) {
return;
}
}
}

void flash_write_init(firestarter_handle_t* handle) {
if (handle->chip_id > 0) {
flash_check_chip_id(handle);
if (handle->response_code == RESPONSE_CODE_ERROR) {
return;
}
}

if (handle->can_erase && !handle->skip_erase) {
internal_erase(handle);
delay(101);
}
else {
copyToBuffer(handle->response_msg, "Skipping erase of memory");
}
#ifdef EPROM_BLANK_CHECK
if (handle->blank_check) {
flash_blank_check(handle);
if (handle->response_code == RESPONSE_CODE_ERROR) {
return;
}
}
#endif
}

void flash_write_data(firestarter_handle_t* handle) {
for (uint32_t i = 0; i < handle->data_size; i++) {
enable_write(handle);
handle->firestarter_set_data(handle, handle->address + i, handle->data_buffer[i]);

verify_operation(handle, handle->data_buffer[i]);
if (handle->response_code == RESPONSE_CODE_ERROR) {
return;
}
}
handle->response_code = RESPONSE_CODE_OK;
}

void flash_erase(firestarter_handle_t* handle) {
if (handle->chip_id > 0) {
flash_check_chip_id(handle);
if (handle->response_code == RESPONSE_CODE_ERROR) {
return;
}
}
if (handle->can_erase) {
internal_erase(handle);
}
else {
copyToBuffer(handle->response_msg, "Erase not supported");
handle->response_code = RESPONSE_CODE_ERROR;
}
}

void flash_blank_check(firestarter_handle_t* handle) {
for (uint32_t i = 0; i < handle->mem_size; i++) {
uint8_t val = handle->firestarter_get_data(handle, i);
if (val != 0xFF) {
handle->response_code = RESPONSE_CODE_ERROR;
format(handle->response_msg, "Memory is not blank, at 0x%06x, value: 0x%02x", i, val);
return;
}
}
}

void flash_check_chip_id(firestarter_handle_t* handle) {
uint16_t chip_id = flash_get_chip_id(handle);
if (chip_id != handle->chip_id) {
handle->response_code = handle->force ? RESPONSE_CODE_WARNING : RESPONSE_CODE_ERROR;
format(handle->response_msg, "Chip ID %#x dont match expected ID %#x", chip_id, handle->chip_id);
}
}

void byte_flipping(firestarter_handle_t* handle, byte_flip_t* byte_flips, size_t size) {
handle->firestarter_set_control_register(handle, RW, 0);
for (size_t i = 0; i < size; i++) {
flip_data(handle, byte_flips[i].address, byte_flips[i].byte);
}
handle->firestarter_set_control_register(handle, RW, 0);
}

void enable_write(firestarter_handle_t* handle) {
byte_flip_t byte_flips[] = {
{0x5555, 0xAA},
{0x2AAA, 0x55},
{0x5555, 0xA0},
};
byte_flipping(handle, byte_flips, sizeof(byte_flips) / sizeof(byte_flips[0]));
}


void internal_erase(firestarter_handle_t* handle) {
byte_flip_t byte_flips[] = {
{0x5555, 0xAA},
{0x2AAA, 0x55},
{0x5555, 0x80},
{0x5555, 0xAA},
{0x2AAA, 0x55},
{0x5555, 0x10},
};
byte_flipping(handle, byte_flips, sizeof(byte_flips) / sizeof(byte_flips[0]));
handle->firestarter_set_address(handle, 0x0000);
verify_operation(handle, 0xFF);
}

uint16_t flash_get_chip_id(firestarter_handle_t* handle) {
byte_flip_t enable_id[] = {
{0x5555, 0xAA},
{0x2AAA, 0x55},
{0x5555, 0x90},
};
byte_flip disable_id[] = {
{0x5555, 0xAA},
{0x2AAA, 0x55},
{0x5555, 0xF0},
};

byte_flipping(handle, enable_id, sizeof(enable_id) / sizeof(enable_id[0]));
uint16_t chip_id = handle->firestarter_get_data(handle, 0x0000) << 8;
chip_id |= (handle->firestarter_get_data(handle, 0x0001));
byte_flipping(handle, disable_id, sizeof(disable_id) / sizeof(enable_id[0]));
return chip_id;
}

uint8_t data_poll() {
rurp_set_data_as_input();
rurp_set_control_pin(CHIP_ENABLE, 0);
rurp_set_control_pin(OUTPUT_ENABLE, 0);
uint8_t data = rurp_read_data_buffer();
rurp_set_control_pin(CHIP_ENABLE, 1);
rurp_set_control_pin(OUTPUT_ENABLE, 1);
return data;
}

void verify_operation(firestarter_handle_t* handle, uint8_t expected_data) {

handle->firestarter_set_control_register(handle, RW, 1);

unsigned long now = millis();
while (millis() - now <= 150) {

// Check Data# Polling (DQ7)
if ((data_poll() & 0x80) == (expected_data & 0x80)) { //Only check if bit 7 has flipped
// Verify completion with an additional read
if ((data_poll() & 0x80) == (data_poll() & 0x80)) { //No assuming other bits
rurp_set_data_as_output();
rurp_set_control_pin(CHIP_ENABLE, 1);
rurp_set_control_pin(OUTPUT_ENABLE, 1);
return; // Operation completed successfully
}
}
}
handle->response_code = RESPONSE_CODE_ERROR;
copyToBuffer(handle->response_msg, "Operation timed out");
return;
}

void flip_data(firestarter_handle_t* handle, uint32_t address, uint8_t data) {
rurp_set_data_as_output();
fast_address(handle, address);
rurp_write_data_buffer(data);
rurp_set_control_pin(CHIP_ENABLE, 0);
rurp_set_control_pin(CHIP_ENABLE, 1);
}

void fast_address(firestarter_handle_t* handle, uint32_t address) {
uint8_t lsb = address & 0xFF;
rurp_write_to_register(LEAST_SIGNIFICANT_BYTE, lsb);
uint8_t msb = ((address >> 8) & 0xFF);
rurp_write_to_register(MOST_SIGNIFICANT_BYTE, msb);
}
14 changes: 10 additions & 4 deletions src/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
#include "config.h"
#include "eprom.h"
#include "sram.h"
#include "flash.h"
#include "rurp_shield.h"
#include "logging.h"
#include "debug.h"

#define TYPE_EPROM 1
#define TYPE_FLASH 3
#define TYPE_SRAM 4

uint8_t programming = 0;

void configure_memory(firestarter_handle_t* handle) {
debug("Configuring memory");
Expand Down Expand Up @@ -47,7 +50,11 @@ void configure_memory(firestarter_handle_t* handle) {
configure_sram(handle);
return;
}
copyToBuffer(handle->response_msg, "Memory type not supported");
else if (handle->mem_type == TYPE_FLASH) {
configure_flash(handle);
return;
}
format(handle->response_msg, "Memory type 0x%02x not supported", handle->mem_type);
handle->response_code = RESPONSE_CODE_ERROR;
return;
}
Expand Down Expand Up @@ -134,13 +141,12 @@ uint8_t memory_get_data(firestarter_handle_t* handle, uint32_t address) {
delayMicroseconds(3);
uint8_t data = rurp_read_data_buffer();
rurp_set_control_pin(CHIP_ENABLE | OUTPUT_ENABLE, 1);
rurp_set_data_as_output();
// rurp_set_data_as_output();

return data;
}

void memory_write_data(firestarter_handle_t* handle) {

for (uint32_t i = 0; i < handle->data_size; i++) {
handle->firestarter_set_data(handle, handle->address + i, handle->data_buffer[i]);
}
Expand All @@ -154,7 +160,7 @@ void memory_set_data(firestarter_handle_t* handle, uint32_t address, uint8_t dat

handle->firestarter_set_address(handle, address);
rurp_write_data_buffer(data);
delayMicroseconds(1);
delayMicroseconds(3); //Needed for slower address changes like slow ROMs and "Power through address lines"
rurp_set_control_pin(CHIP_ENABLE, 0);
delayMicroseconds(handle->pulse_delay);
rurp_set_control_pin(CHIP_ENABLE, 1);
Expand Down
6 changes: 3 additions & 3 deletions src/uno_rurp_shield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,9 @@ void rurp_write_to_register(uint8_t reg, register_t data) {
default:
return;
}
rurp_set_data_as_output();
PORTD = data;
rurp_write_data_buffer( data);
PORTB |= reg;
delayMicroseconds(1);
// Probably useless - verify later delayMicroseconds(1);
PORTB &= ~(reg);
}

Expand All @@ -223,6 +222,7 @@ void rurp_set_control_pin(uint8_t pin, uint8_t state) {


void rurp_write_data_buffer(uint8_t data) {
rurp_set_data_as_output();
PORTD = data;
}

Expand Down

0 comments on commit a93b814

Please sign in to comment.