Skip to content

Commit

Permalink
First revision
Browse files Browse the repository at this point in the history
  • Loading branch information
ghecko committed Jul 3, 2020
1 parent 345e7f6 commit 3d88b62
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 61 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# owfmodules.skeleton
Module base repository
# owfmodules.avrisp.eeprom_erase

Please read [CONTRIBUTING.md](https://github.com/immunIT/octowire-framework/blob/master/CONTRIBUTING.md) to follow the contribution process.
Module allows erasing the eeprom memory of an AVR MCU through the ISP protocol.
It use the SPI interface with a GPIO as reset line.
4 changes: 2 additions & 2 deletions git_init.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
git remote set-url origin --push --add https://github.com/immunIT/<module_name>
git remote set-url origin --push --add [email protected]:octowire/<module_name>.git
git remote set-url origin --push --add git@github.com:immunIT/owfmodules.avrisp.eeprom_erase.git
git remote set-url origin --push --add [email protected]:octowire/owfmodules.avrisp.eeprom_erase.git
git remote -v
File renamed without changes.
130 changes: 130 additions & 0 deletions owfmodules/avrisp/eeprom_erase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import struct
import time

from tqdm import tqdm

from octowire_framework.module.AModule import AModule
from octowire.gpio import GPIO
from octowire.spi import SPI
from owfmodules.avrisp.device_id import DeviceID


class EepromErase(AModule):
def __init__(self, owf_config):
super(EepromErase, self).__init__(owf_config)
self.meta.update({
'name': 'AVR erase eeprom memory',
'version': '1.0.0',
'description': 'Module to erase the eeprom memory of an AVR device using the ISP protocol.',
'author': 'Jordan Ovrè / Ghecko <[email protected]>, Paul Duncan / Eresse <[email protected]>'
})
self.options = {
"spi_bus": {"Value": "", "Required": True, "Type": "int",
"Description": "The octowire SPI bus (0=SPI0 or 1=SPI1)", "Default": 0},
"reset_line": {"Value": "", "Required": True, "Type": "int",
"Description": "The octowire GPIO used as the Reset line", "Default": 0},
"spi_baudrate": {"Value": "", "Required": True, "Type": "int",
"Description": "set SPI baudrate (1000000 = 1MHz) maximum = 50MHz", "Default": 1000000},
}
self.dependencies.append("owfmodules.avrisp.device_id>=1.0.0")

def get_device_id(self, spi_bus, reset_line, spi_baudrate):
device_id_module = DeviceID(owf_config=self.config)
# Set DeviceID module options
device_id_module.options["spi_bus"]["Value"] = spi_bus
device_id_module.options["reset_line"]["Value"] = reset_line
device_id_module.options["spi_baudrate"]["Value"] = spi_baudrate
device_id_module.owf_serial = self.owf_serial
device_id = device_id_module.run(return_value=True)
return device_id

@staticmethod
def wait_poll_eeprom(spi_interface, byte, byte_addr):
read_cmd = b'\xA0'

# 10s timeout
timeout = time.time() + 10

while True:
# Send read cmd
spi_interface.transmit(read_cmd + struct.pack(">H", byte_addr))
# Receive the byte and compare it
read_byte = spi_interface.receive(1)[0]
if read_byte == byte:
return True
if time.time() > timeout:
return False

def erase(self, spi_interface, reset, device):
write_cmd = b'\xC0'
enable_mem_access_cmd = b'\xac\x53\x00\x00'

# Drive reset low
reset.status = 0

self.logger.handle("Enable Memory Access...", self.logger.INFO)
# Drive reset low
reset.status = 0
# Enable Memory Access
spi_interface.transmit(enable_mem_access_cmd)
time.sleep(0.5)

# Fill the eeprom with 0xFF
self.logger.handle("Erasing the eeprom memory (Write 0xFF)...", self.logger.INFO)
for addr in tqdm(range(0, int(device["eeprom_size"], 16), 1), desc="Erase", ascii=" #", unit_scale=True,
bar_format="{desc} : {percentage:3.0f}%[{bar}] {n_fmt}/{total_fmt} bytes "
"[elapsed: {elapsed} left: {remaining}]"):
spi_interface.transmit(write_cmd + struct.pack(">H", addr) + b'\xFF')
# Wait until byte write on the eeprom
if not self.wait_poll_eeprom(spi_interface, 0xFF, addr):
self.logger.handle("\nWriting at byte address '{}' take too much time, exiting..".format(addr),
self.logger.ERROR)
return False

# Drive reset high
reset.status = 1
self.logger.handle("Eeprom memory successfully erased.", self.logger.SUCCESS)
return True

def process(self):
spi_bus = self.options["spi_bus"]["Value"]
reset_line = self.options["reset_line"]["Value"]
spi_baudrate = self.options["spi_baudrate"]["Value"]

device = self.get_device_id(spi_bus, reset_line, spi_baudrate)
if device is None:
return

spi_interface = SPI(serial_instance=self.owf_serial, bus_id=spi_bus)
reset = GPIO(serial_instance=self.owf_serial, gpio_pin=reset_line)

# Configure SPI with default phase and polarity
spi_interface.configure(baudrate=spi_baudrate)
# Configure GPIO as output
reset.direction = GPIO.OUTPUT

# Active Reset is low
reset.status = 1

# Erase the target chip
return self.erase(spi_interface, reset, device)

def run(self, return_value=False):
"""
Main function.
Erase the eeprom memory of an AVR device.
:return: Bool if return_value is true, else nothing.
"""
# If detect_octowire is True then Detect and connect to the Octowire hardware. Else, connect to the Octowire
# using the parameters that were configured. It sets the self.owf_serial variable if the hardware is found.
self.connect()
if not self.owf_serial:
return
try:
status = self.process()
if return_value:
return status
except ValueError as err:
self.logger.handle(err, self.logger.ERROR)
except Exception as err:
self.logger.handle("{}: {}".format(type(err).__name__, err), self.logger.ERROR)
50 changes: 0 additions & 50 deletions owfmodules/category/module_name.py

This file was deleted.

12 changes: 6 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

from setuptools import setup, find_packages

__authors__ = ""
__copyright__ = ""
__authors__ = "Jordan Ovrè, Paul Duncan"
__copyright__ = "Copyright (c) ImmunIT - Jordan Ovrè / Paul Duncan"
__license__ = "Apache 2.0"
__version__ = "1.0.0"
__contact__ = ""
__contact__ = "Jordan Ovrè / Ghecko <[email protected]>, Paul Duncan / Eresse <[email protected]>"

description = ''
name = 'owfmodules.<category>.<module_name>'
description = 'Erase the AVR eeprom memory'
name = 'owfmodules.avrisp.eeprom_erase'

setup(
name=name,
Expand All @@ -27,5 +27,5 @@
'Programming Language :: Python :: 3',
'Development Status :: 5 - Production/Stable'
],
keywords=['octowire', 'framework', 'hardware', 'security']
keywords=['octowire', 'framework', 'hardware', 'security', 'AVR', 'eeprom', "erase"]
)

0 comments on commit 3d88b62

Please sign in to comment.