mirror of
https://github.com/trabucayre/openFPGALoader.git
synced 2026-09-07 19:56:41 +02:00
Adding BPI flash support and YPCB board support
This commit is contained in:
committed by
Gwenhael Goavec-Merou
parent
3f3e37909b
commit
98fea26507
@@ -0,0 +1,140 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
/*
|
||||
* Copyright (C) 2024 openFPGALoader contributors
|
||||
* BPI (Parallel NOR) Flash support via JTAG bridge
|
||||
*/
|
||||
|
||||
#ifndef SRC_BPIFLASH_HPP_
|
||||
#define SRC_BPIFLASH_HPP_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "jtag.hpp"
|
||||
|
||||
/*!
|
||||
* \class BPIFlash
|
||||
* \brief Intel CFI parallel NOR flash programming via JTAG bridge
|
||||
*/
|
||||
class BPIFlash {
|
||||
public:
|
||||
BPIFlash(Jtag *jtag, int8_t verbose);
|
||||
~BPIFlash();
|
||||
|
||||
/*!
|
||||
* \brief Read device ID and manufacturer info
|
||||
* \return true if device detected
|
||||
*/
|
||||
bool detect();
|
||||
|
||||
/*!
|
||||
* \brief Read flash content
|
||||
* \param[out] data: buffer to store read data
|
||||
* \param[in] addr: start address (word address)
|
||||
* \param[in] len: number of bytes to read
|
||||
* \return true on success
|
||||
*/
|
||||
bool read(uint8_t *data, uint32_t addr, uint32_t len);
|
||||
|
||||
/*!
|
||||
* \brief Write data to flash (handles erase internally)
|
||||
* \param[in] addr: start address (word address)
|
||||
* \param[in] data: data to write
|
||||
* \param[in] len: number of bytes to write
|
||||
* \return true on success
|
||||
*/
|
||||
bool write(uint32_t addr, const uint8_t *data, uint32_t len);
|
||||
|
||||
/*!
|
||||
* \brief Erase a block
|
||||
* \param[in] addr: address within the block to erase
|
||||
* \return true on success
|
||||
*/
|
||||
bool erase_block(uint32_t addr);
|
||||
|
||||
/*!
|
||||
* \brief Bulk erase entire flash
|
||||
* \return true on success
|
||||
*/
|
||||
bool bulk_erase();
|
||||
|
||||
/*!
|
||||
* \brief Get flash capacity in bytes
|
||||
*/
|
||||
uint32_t capacity() const { return _capacity; }
|
||||
|
||||
/*!
|
||||
* \brief Get block size in bytes
|
||||
*/
|
||||
uint32_t block_size() const { return _block_size; }
|
||||
|
||||
private:
|
||||
/* BPI bridge command codes (match bpiOverJtag_core.v) */
|
||||
static const uint8_t CMD_WRITE = 0x1;
|
||||
static const uint8_t CMD_READ = 0x2;
|
||||
static const uint8_t CMD_NOP = 0x3;
|
||||
static const uint8_t CMD_BURST_WRITE = 0x4;
|
||||
|
||||
/* Intel CFI flash commands */
|
||||
static const uint16_t FLASH_CMD_READ_ARRAY = 0x00FF;
|
||||
static const uint16_t FLASH_CMD_READ_ID = 0x0090;
|
||||
static const uint16_t FLASH_CMD_READ_CFI = 0x0098;
|
||||
static const uint16_t FLASH_CMD_READ_STATUS = 0x0070;
|
||||
static const uint16_t FLASH_CMD_CLEAR_STATUS = 0x0050;
|
||||
static const uint16_t FLASH_CMD_PROGRAM = 0x0041; /* Single-word program (MT28GU512AAA) */
|
||||
static const uint16_t FLASH_CMD_BUFFERED_PRG = 0x00E9;
|
||||
static const uint16_t FLASH_CMD_CONFIRM = 0x00D0;
|
||||
static const uint16_t FLASH_CMD_BLOCK_ERASE = 0x0020;
|
||||
static const uint16_t FLASH_CMD_UNLOCK_BLOCK = 0x0060;
|
||||
static const uint16_t FLASH_CMD_UNLOCK_CONF = 0x00D0;
|
||||
|
||||
/* Status register bits */
|
||||
static const uint16_t SR_READY = 0x0080;
|
||||
static const uint16_t SR_ERASE_ERR = 0x0020;
|
||||
static const uint16_t SR_PROG_ERR = 0x0010;
|
||||
static const uint16_t SR_VPP_ERR = 0x0008;
|
||||
static const uint16_t SR_BLOCK_LOCK = 0x0002;
|
||||
|
||||
/*!
|
||||
* \brief Read a 16-bit word from flash at word address
|
||||
*/
|
||||
uint16_t bpi_read(uint32_t word_addr);
|
||||
|
||||
/*!
|
||||
* \brief Write a 16-bit word to flash at word address
|
||||
*/
|
||||
void bpi_write(uint32_t word_addr, uint16_t data);
|
||||
|
||||
/*!
|
||||
* \brief Write a 16-bit word without IR shift or flush (for batched writes)
|
||||
*/
|
||||
void bpi_write_no_flush(uint32_t word_addr, uint16_t data);
|
||||
|
||||
/*!
|
||||
* \brief Burst write multiple 16-bit words in a single DR shift
|
||||
*/
|
||||
void bpi_burst_write(uint32_t word_addr, const uint16_t *data,
|
||||
uint32_t count);
|
||||
|
||||
/*!
|
||||
* \brief Wait for operation to complete
|
||||
* \return true if completed successfully
|
||||
*/
|
||||
bool wait_ready(uint32_t timeout_ms = 10000);
|
||||
|
||||
/*!
|
||||
* \brief Unlock a block for programming/erase
|
||||
*/
|
||||
bool unlock_block(uint32_t word_addr);
|
||||
|
||||
Jtag *_jtag;
|
||||
int8_t _verbose;
|
||||
int _irlen;
|
||||
uint32_t _capacity;
|
||||
uint32_t _block_size;
|
||||
uint16_t _manufacturer_id;
|
||||
uint16_t _device_id;
|
||||
bool _has_burst;
|
||||
};
|
||||
|
||||
#endif // SRC_BPIFLASH_HPP_
|
||||
Reference in New Issue
Block a user