diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index a222d61b..723e2f6e 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -234,6 +234,7 @@ set(CPPSRC apps/ui_debug.cpp apps/ui_encoders.cpp apps/ui_fileman.cpp + apps/ui_flash_utility.cpp apps/ui_freqman.cpp apps/ui_jammer.cpp apps/ui_keyfob.cpp diff --git a/firmware/application/apps/ui_flash_utility.cpp b/firmware/application/apps/ui_flash_utility.cpp new file mode 100644 index 00000000..4dcd2c32 --- /dev/null +++ b/firmware/application/apps/ui_flash_utility.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2023 Bernd Herzog + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "ui_flash_utility.hpp" +#include "portapack_shared_memory.hpp" + +namespace ui { + +Thread* FlashUtilityView::thread { nullptr }; +static constexpr size_t max_filename_length = 26; + +FlashUtilityView::FlashUtilityView(NavigationView& nav) : nav_ (nav) { + add_children({ + &labels, + &menu_view + }); + + menu_view.set_parent_rect({ 0, 3 * 8, 240, 33 * 8 }); + + for (const auto& entry : std::filesystem::directory_iterator(u"FIRMWARE", u"*.bin")) { + auto filename = entry.path().filename(); + auto path = entry.path().native(); + + menu_view.add_item({ + filename.string().substr(0, max_filename_length), + ui::Color::red(), + &bitmap_icon_temperature, + [this, path]() { + this->firmware_selected(path); + } + }); + } +} + +void FlashUtilityView::firmware_selected(std::filesystem::path::string_type path) { + nav_.push( + "Warning!", + "This will replace your\ncurrent firmware.\n\nIf things go wrong you are\nrequired to flash manually\nwith dfu.", + YESNO, + [this, path](bool choice) { + if (choice) { + std::u16string full_path = std::u16string(u"FIRMWARE/") + path; + this->flash_firmware(full_path); + } + } + ); +} + +void FlashUtilityView::flash_firmware(std::filesystem::path::string_type path) { + ui::Painter painter; + painter.fill_rectangle( + { 0, 0, portapack::display.width(), portapack::display.height() }, + ui::Color::black() + ); + + painter.draw_string({ 12, 24 }, this->nav_.style(), "This will take 15 seconds."); + painter.draw_string({ 12, 64 }, this->nav_.style(), "Please wait while LEDs RX"); + painter.draw_string({ 12, 84 }, this->nav_.style(), "and TX are flashing."); + painter.draw_string({ 12, 124 }, this->nav_.style(), "Then restart the device."); + + std::memcpy(&shared_memory.bb_data.data[0], path.c_str(), (path.length() + 1) * 2); + m4_init(portapack::spi_flash::image_tag_flash_utility, portapack::memory::map::m4_code, false); + m0_halt(); +} + +void FlashUtilityView::focus() { + menu_view.focus(); +} + +} /* namespace ui */ diff --git a/firmware/application/apps/ui_flash_utility.hpp b/firmware/application/apps/ui_flash_utility.hpp new file mode 100644 index 00000000..82acc22b --- /dev/null +++ b/firmware/application/apps/ui_flash_utility.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2023 Bernd Herzog + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __UI_FLSH_UITILTY_H__ +#define __UI_FLSH_UITILTY_H__ + +#include "ui_widget.hpp" +#include "ui_navigation.hpp" +#include "string_format.hpp" +#include "ff.h" +#include "baseband_api.hpp" +#include "core_control.hpp" + +#include + +namespace ui { + +class FlashUtilityView : public View { +public: + FlashUtilityView(NavigationView& nav); + + void focus() override; + + std::string title() const override { return "Flash Utility"; }; + +private: + NavigationView& nav_; + + bool confirmed = false; + static Thread* thread; + + Labels labels { + { { 4, 4 }, "Select firmware to flash:", Color::white() } + }; + + MenuView menu_view { + { 0, 2 * 8, 240, 26 * 8 }, + true + }; + + void firmware_selected(std::filesystem::path::string_type path); + void flash_firmware(std::filesystem::path::string_type path); +}; + +} /* namespace ui */ + +#endif/*__UI_FLSH_UITILTY_H__*/ diff --git a/firmware/application/ui_navigation.cpp b/firmware/application/ui_navigation.cpp index ffd5d09f..c85417d5 100644 --- a/firmware/application/ui_navigation.cpp +++ b/firmware/application/ui_navigation.cpp @@ -70,6 +70,7 @@ #include "ui_playlist.hpp" #include "ui_view_wav.hpp" #include "ui_whipcalc.hpp" +#include "ui_flash_utility.hpp" //#include "acars_app.hpp" #include "ais_app.hpp" @@ -613,6 +614,8 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) { { "Antenna length", ui::Color::green(), &bitmap_icon_tools_antenna, [&nav](){ nav.push(); } }, { "Wipe SD card", ui::Color::red(), &bitmap_icon_tools_wipesd, [&nav](){ nav.push(); } }, + { "Flash Utility", ui::Color::red(), &bitmap_icon_temperature, [&nav](){ nav.push(); } }, + }); set_max_rows(2); // allow wider buttons } diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index 79ea441e..76065cdd 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -90,8 +90,6 @@ set(CSRC ${PORTSRC} ${KERNSRC} ${TESTSRC} - ${HALSRC} - ${PLATFORMSRC} ${BOARDSRC} ) @@ -262,10 +260,11 @@ macro(DeclareTargets chunk_tag name) project("baseband_${name}") include(${RULESPATH}/rules.cmake) - add_executable(${PROJECT_NAME}.elf $ ${MODE_CPPSRC}) + add_executable(${PROJECT_NAME}.elf $ ${MODE_CPPSRC} ${HALSRC} ${PLATFORMSRC}) set_target_properties(${PROJECT_NAME}.elf PROPERTIES LINK_DEPENDS ${LDSCRIPT}) add_definitions(${DEFS}) - include_directories(. ${INCDIR}) + target_compile_definitions(${PROJECT_NAME}.elf PUBLIC "-DBASEBAND_${name}") + include_directories(. ${INCDIR} ${MODE_INCDIR}) link_directories(${LLIBDIR}) target_link_libraries(${PROJECT_NAME}.elf ${LIBS}) target_link_libraries(${PROJECT_NAME}.elf -Wl,-Map=${PROJECT_NAME}.map) @@ -505,6 +504,17 @@ set(MODE_CPPSRC ) DeclareTargets(PWFM wfm_audio) +### Flash Utility + +include(${CHIBIOS_PORTAPACK}/os/various/fatfs_bindings/fatfs.cmake) +set(MODE_INCDIR ${FATFSINC}) +set(MODE_CPPSRC + proc_flash_utility.cpp + w25q80bv.cpp + ${FATFSSRC} +) +DeclareTargets(PFUT flash_utility) + ### HackRF "factory" firmware add_custom_command( diff --git a/firmware/baseband/debug.hpp b/firmware/baseband/debug.hpp index 4cd06d0e..f4972527 100644 --- a/firmware/baseband/debug.hpp +++ b/firmware/baseband/debug.hpp @@ -36,6 +36,7 @@ inline uint32_t get_free_stack_space(){ return stack_space_left; } +/* Executes a breakpoint only when a debugger is attached. */ #define HALT_IF_DEBUGGING() \ do { \ if ((*(volatile uint32_t *)0xE000EDF0) & (1 << 0)) { \ @@ -43,4 +44,9 @@ inline uint32_t get_free_stack_space(){ } \ } while (0) +/* Stops execution until a debugger is attached. */ +#define HALT_UNTIL_DEBUGGING() \ + while (!((*(volatile uint32_t *)0xE000EDF0) & (1 << 0))) {} \ + __asm__ __volatile__("bkpt 1") + #endif/*__DEBUG_H__*/ diff --git a/firmware/baseband/halconf.h b/firmware/baseband/halconf.h index c157afbd..d79a158e 100755 --- a/firmware/baseband/halconf.h +++ b/firmware/baseband/halconf.h @@ -119,7 +119,11 @@ * @brief Enables the SDC subsystem. */ #if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#ifdef BASEBAND_flash_utility +#define HAL_USE_SDC TRUE +#else #define HAL_USE_SDC FALSE +#endif /* BASEBAND_flash_utility */ #endif /** diff --git a/firmware/baseband/proc_flash_utility.cpp b/firmware/baseband/proc_flash_utility.cpp new file mode 100644 index 00000000..c3730858 --- /dev/null +++ b/firmware/baseband/proc_flash_utility.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2023 Bernd Herzog + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "ch.h" +#include "hal.h" +#include "ff.h" + +#include "w25q80bv.hpp" +#include "debug.hpp" +#include "portapack_shared_memory.hpp" + +#define PAGE_LEN 256U +#define NUM_PAGES 4096U + +void initialize_flash(); +void erase_flash(); +void initialize_sdcard(); +void write_firmware(FIL *); +void write_page(size_t, uint8_t *, size_t); + +int main() { + const TCHAR *filename = reinterpret_cast(&shared_memory.bb_data.data[0]); + + initialize_flash(); + palSetPad(LED_PORT, LEDRX_PAD); + erase_flash(); + + initialize_sdcard(); + + FIL firmware_file; + if (f_open(&firmware_file, filename, FA_READ) != FR_OK) chDbgPanic("no file"); + + palSetPad(LED_PORT, LEDTX_PAD); + + write_firmware(&firmware_file); + + palClearPad(LED_PORT, LEDTX_PAD); + palClearPad(LED_PORT, LEDRX_PAD); + + f_close(&firmware_file); + + while(1) + __WFE(); + + return 0; +} + +void initialize_flash() { + w25q80bv::disable_spifi(); + w25q80bv::initialite_spi(); + w25q80bv::setup(); + + w25q80bv::wait_for_device(); + w25q80bv::wait_not_busy(); +} + +void erase_flash() { + w25q80bv::remove_write_protection(); + w25q80bv::wait_not_busy(); + + w25q80bv::erase_chip(); + w25q80bv::wait_not_busy(); +} + +void initialize_sdcard() { + static FATFS fs; + + sdcStart(&SDCD1, nullptr); + if (sdcConnect(&SDCD1) == CH_FAILED) chDbgPanic("no sd card #1"); + if (f_mount(&fs, reinterpret_cast(_T("")), 1) != FR_OK) chDbgPanic("no sd card #2"); +} + +void write_firmware(FIL *firmware_file) { + uint8_t *data_buffer = &shared_memory.bb_data.data[0]; + + for (size_t page_index = 0; page_index < NUM_PAGES; page_index++) { + if (page_index % 32 == 0) + palTogglePad(LED_PORT, LEDTX_PAD); + + size_t bytes_read; + if (f_read(firmware_file, data_buffer, PAGE_LEN, &bytes_read) != FR_OK) chDbgPanic("no data"); + + if (bytes_read > 0) + write_page(page_index, data_buffer, bytes_read); + + if (bytes_read < PAGE_LEN) + return; + } +} + +void write_page(size_t page_index, uint8_t *data_buffer, size_t data_length) { + w25q80bv::wait_not_busy(); + w25q80bv::remove_write_protection(); + w25q80bv::wait_not_busy(); + w25q80bv::write(page_index, data_buffer, data_length); + w25q80bv::wait_not_busy(); +} diff --git a/firmware/baseband/w25q80bv.cpp b/firmware/baseband/w25q80bv.cpp new file mode 100644 index 00000000..d7af6b30 --- /dev/null +++ b/firmware/baseband/w25q80bv.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2023 Bernd Herzog + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "w25q80bv.hpp" +#include "debug.hpp" + +namespace w25q80bv { + +void disable_spifi(){ + RESET_CTRL1 = RESET_CTRL1_SPIFI_RST; +} + +void initialite_spi(){ + palSetPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + palOutputPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + + const uint32_t clock_prescale_rate = 2; + const uint32_t serial_clock_rate = 2; + + SSP_CR1(SSP0_BASE) = 0; + SSP_CPSR(SSP0_BASE) = clock_prescale_rate; + SSP_CR0(SSP0_BASE) = (serial_clock_rate << 8) | SSP_DATA_8BITS; + SSP_CR1(SSP0_BASE) = SSP_ENABLE; +} + +void setup() { + /* Init SPIFI GPIO to Normal GPIO */ + + MMIO32(PIN_GROUP3 + PIN3) = (SCU_SSP_IO | SCU_CONF_FUNCTION2); + MMIO32(PIN_GROUP3 + PIN4) = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0); + MMIO32(PIN_GROUP3 + PIN5) = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0); + MMIO32(PIN_GROUP3 + PIN6) = (SCU_GPIO_FAST | SCU_CONF_FUNCTION0); + MMIO32(PIN_GROUP3 + PIN7) = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4); + MMIO32(PIN_GROUP3 + PIN8) = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4); + + /* configure SSP pins */ + MMIO32(SCU_SSP0_CIPO) = (SCU_SSP_IO | SCU_CONF_FUNCTION5); + MMIO32(SCU_SSP0_COPI) = (SCU_SSP_IO | SCU_CONF_FUNCTION5); + MMIO32(SCU_SSP0_SCK) = (SCU_SSP_IO | SCU_CONF_FUNCTION2); + + /* configure GPIO pins */ + MMIO32(SCU_FLASH_HOLD) = SCU_GPIO_FAST; + MMIO32(SCU_FLASH_WP) = SCU_GPIO_FAST; + MMIO32(SCU_SSP0_CS) = (SCU_GPIO_FAST | SCU_CONF_FUNCTION4); + + //remove hardware write protection + /* drive CS, HOLD, and WP pins high */ + palSetPad(W25Q80BV_HOLD_PORT, W25Q80BV_HOLD_PAD); + palSetPad(W25Q80BV_WP_PORT, W25Q80BV_WP_PAD); + + /* Set GPIO pins as outputs. */ + palOutputPad(W25Q80BV_HOLD_PORT, W25Q80BV_HOLD_PAD); + palOutputPad(W25Q80BV_WP_PORT, W25Q80BV_WP_PAD); +} + +void wait_for_device() { + uint8_t device_id; + do { + device_id = get_device_id(); + } while (device_id != W25Q80BV_DEVICE_ID_RES && + device_id != W25Q16DV_DEVICE_ID_RES); +} + +void wait_not_busy() { + while (get_status() & W25Q80BV_STATUS_BUSY) {HALT_IF_DEBUGGING();} +} + +void remove_write_protection() { + uint8_t data[] = {W25Q80BV_WRITE_ENABLE}; + palClearPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + + for (size_t j = 0; j < 1; j++) { + data[j] = spi_ssp_transfer_word(data[j]); + } + + palSetPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + + while (!(get_status() & W25Q80BV_STATUS_WEL)) {HALT_IF_DEBUGGING();} +} + +uint32_t spi_ssp_transfer_word(const uint32_t data) { + while ((SSP_SR(SSP0_BASE) & SSP_SR_TNF) == 0) {HALT_IF_DEBUGGING();} + SSP_DR(SSP0_BASE) = data; + while (SSP_SR(SSP0_BASE) & SSP_SR_BSY) {HALT_IF_DEBUGGING();} + while ((SSP_SR(SSP0_BASE) & SSP_SR_RNE) == 0) {HALT_IF_DEBUGGING();} + return SSP_DR(SSP0_BASE); +} + +uint8_t get_status() { + uint8_t data[] = {W25Q80BV_READ_STATUS1, 0xFF}; + palClearPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + + for (size_t j = 0; j < 2; j++) { + data[j] = spi_ssp_transfer_word(data[j]); + } + + palSetPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + + return data[1]; +} + +uint8_t get_device_id() { + uint8_t data[] = {W25Q80BV_DEVICE_ID, 0xFF, 0xFF, 0xFF, 0xFF}; + palClearPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + + for (size_t j = 0; j < 5; j++) { + data[j] = spi_ssp_transfer_word(data[j]); + } + + palSetPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + + return data[4]; +} + +void erase_chip() { + uint8_t data[] = {W25Q80BV_CHIP_ERASE}; + palClearPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + + for (size_t j = 0; j < 1; j++) { + data[j] = spi_ssp_transfer_word(data[j]); + } + + palSetPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); +} + +void write(size_t page_index, uint8_t *data_buffer, size_t length) { + size_t page_len = 256U; + size_t addr = page_index * page_len; + uint8_t header[] = { + W25Q80BV_PAGE_PROGRAM, + (uint8_t)((addr & 0xFF0000) >> 16), + (uint8_t)((addr & 0xFF00) >> 8), + (uint8_t)(addr & 0xFF) + }; + + palClearPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); + for (size_t j = 0; j < 4; j++) { + header[j] = spi_ssp_transfer_word(header[j]); + } + + for (size_t j = 0; j < length; j++) { + data_buffer[j] = spi_ssp_transfer_word(data_buffer[j]); + } + palSetPad(W25Q80BV_SELECT_PORT, W25Q80BV_SELECT_PAD); +} +} diff --git a/firmware/baseband/w25q80bv.hpp b/firmware/baseband/w25q80bv.hpp new file mode 100644 index 00000000..1d29a653 --- /dev/null +++ b/firmware/baseband/w25q80bv.hpp @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2023 Bernd Herzog + * + * This file is part of PortaPack. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __W25Q80BV_H__ +#define __W25Q80BV_H__ + +#include "ch.h" +#include "hal.h" + +#define RGU_BASE 0x40053000 +#define RESET_CTRL1 MMIO32(RGU_BASE + 0x104) +#define RESET_CTRL1_SPIFI_RST_SHIFT (21) +#define RESET_CTRL1_SPIFI_RST (1 << RESET_CTRL1_SPIFI_RST_SHIFT) + +#define W25Q80BV_WRITE_ENABLE 0x06 +#define W25Q80BV_CHIP_ERASE 0xC7 +#define W25Q80BV_DEVICE_ID 0xAB +#define W25Q80BV_PAGE_PROGRAM 0x02 + +#define PERIPH_BASE_APB0 0x40080000 +#define SCU_BASE (PERIPH_BASE_APB0 + 0x06000) +#define MMIO32(addr) (*(volatile uint32_t *)(addr)) + +#define PIN_GROUP3 (SCU_BASE + 0x180) +#define PIN3 0x00C +#define PIN4 0x010 +#define PIN5 0x014 +#define PIN6 0x018 +#define PIN7 0x01C +#define PIN8 0x020 + +#define BIT0 (1<<0) +#define BIT1 (1<<1) +#define BIT2 (1<<2) +#define BIT3 (1<<3) +#define BIT4 (1<<4) +#define BIT5 (1<<5) +#define BIT6 (1<<6) +#define BIT7 (1<<7) +#define BIT8 (1<<8) + +#define SCU_CONF_EPUN_DIS_PULLUP (BIT4) +#define SCU_CONF_EHS_FAST (BIT5) +#define SCU_CONF_EZI_EN_IN_BUFFER (BIT6) +#define SCU_CONF_ZIF_DIS_IN_GLITCH_FILT (BIT7) + +#define SCU_GPIO_FAST (SCU_CONF_EPUN_DIS_PULLUP | \ + SCU_CONF_EHS_FAST | \ + SCU_CONF_EZI_EN_IN_BUFFER | \ + SCU_CONF_ZIF_DIS_IN_GLITCH_FILT) +#define SCU_SSP_IO SCU_GPIO_FAST + +#define SCU_CONF_FUNCTION0 (0x0) +#define SCU_CONF_FUNCTION2 (0x2) +#define SCU_CONF_FUNCTION4 (0x4) +#define SCU_CONF_FUNCTION5 (0x5) + +#define SCU_SSP0_CIPO (PIN_GROUP3 + PIN6) +#define SCU_SSP0_COPI (PIN_GROUP3 + PIN7) +#define SCU_SSP0_SCK (PIN_GROUP3 + PIN3) +#define SCU_SSP0_CS (PIN_GROUP3 + PIN8) +#define SCU_FLASH_HOLD (PIN_GROUP3 + PIN4) +#define SCU_FLASH_WP (PIN_GROUP3 + PIN5) + +#define W25Q80BV_DEVICE_ID_RES 0x13 /* Expected device_id for W25Q80BV */ +#define W25Q16DV_DEVICE_ID_RES 0x14 /* Expected device_id for W25Q16DV */ + +#define SSP_CR1(port) MMIO32(port + 0x004) +#define PERIPH_BASE_APB0 0x40080000 +#define SSP0_BASE (PERIPH_BASE_APB0 + 0x03000) +#define SSP_CPSR(port) MMIO32(port + 0x010) +#define SSP_CR0(port) MMIO32(port + 0x000) +#define SSP_ENABLE BIT1 +#define SSP_DATA_8BITS 0x7 + +#define palSetPad(port, pad) (LPC_GPIO->SET[(port)] = 1 << (pad)) +#define palClearPad(port, pad) (LPC_GPIO->CLR[(port)] = 1 << (pad)) +#define palOutputPad(port, pad) (LPC_GPIO->DIR[(port)] |= 1 << (pad)) +#define palTogglePad(port, pad) (LPC_GPIO->NOT[(port)] |= 1 << (pad)) + +#define W25Q80BV_SELECT_PORT 5 +#define W25Q80BV_SELECT_PAD 11 +#define W25Q80BV_WP_PORT 1 +#define W25Q80BV_WP_PAD 15 +#define W25Q80BV_HOLD_PORT 1 +#define W25Q80BV_HOLD_PAD 14 + +#define LED_PORT 2 +#define LEDRX_PAD 2 +#define LEDTX_PAD 8 + + +#define W25Q80BV_STATUS_BUSY 0x01 +#define W25Q80BV_STATUS_WEL 0x02 +#define W25Q80BV_READ_STATUS1 0x05 +#define W25Q80BV_READ_STATUS2 0x35 + +#define PERIPH_BASE_APB0 0x40080000 +#define SSP0_BASE (PERIPH_BASE_APB0 + 0x03000) +#define SSP_DR(port) MMIO32(port + 0x008) +#define SSP_SR(port) MMIO32(port + 0x00C) + +#define SSP_SR_TNF BIT1 +#define SSP_SR_RNE BIT2 +#define SSP_SR_BSY BIT4 + +namespace w25q80bv { + void disable_spifi(); + uint8_t get_status(); + void wait_for_device(); + void wait_not_busy(); + uint32_t spi_ssp_transfer_word(const uint32_t data); + void initialite_spi(); + void setup(); + void remove_write_protection(); + uint8_t get_device_id(); + void erase_chip(); + void write(size_t page_index, uint8_t *data_buffer, size_t length); +} + +#endif/*__W25Q80BV_H__*/ diff --git a/firmware/application/ffconf.h b/firmware/common/ffconf.h similarity index 100% rename from firmware/application/ffconf.h rename to firmware/common/ffconf.h diff --git a/firmware/common/spi_image.hpp b/firmware/common/spi_image.hpp index ce2ab1c8..709807fb 100644 --- a/firmware/common/spi_image.hpp +++ b/firmware/common/spi_image.hpp @@ -106,6 +106,7 @@ constexpr image_tag_t image_tag_gps { 'P', 'G', 'P', 'S' }; constexpr image_tag_t image_tag_siggen { 'P', 'S', 'I', 'G' }; constexpr image_tag_t image_tag_sstv_tx { 'P', 'S', 'T', 'X' }; constexpr image_tag_t image_tag_tones { 'P', 'T', 'O', 'N' }; +constexpr image_tag_t image_tag_flash_utility { 'P', 'F', 'U', 'T' }; constexpr image_tag_t image_tag_noop { 'P', 'N', 'O', 'P' }; diff --git a/sdcard/FIRMWARE/hackrf_one_usb.bin b/sdcard/FIRMWARE/hackrf_one_usb.bin new file mode 100644 index 00000000..6e7935ec Binary files /dev/null and b/sdcard/FIRMWARE/hackrf_one_usb.bin differ diff --git a/sdcard/FIRMWARE/pp-mayhem-1.6.0.bin b/sdcard/FIRMWARE/pp-mayhem-1.6.0.bin new file mode 100644 index 00000000..896a71fb Binary files /dev/null and b/sdcard/FIRMWARE/pp-mayhem-1.6.0.bin differ