openFPGALoader/src/altera.cpp

162 lines
4.7 KiB
C++
Raw Normal View History

2019-09-26 18:29:20 +02:00
#include "altera.hpp"
#include <string.h>
#include <string>
#include "jtag.hpp"
2019-09-26 18:29:20 +02:00
#include "device.hpp"
#include "epcq.hpp"
#include "progressBar.hpp"
#include "rawParser.hpp"
2019-09-26 18:29:20 +02:00
#define IDCODE 6
#define BYPASS 0x3FF
#define IRLENGTH 10
// DATA_DIR is defined at compile time.
#define BIT_FOR_FLASH (DATA_DIR "/openFPGALoader/test_sfl.svf")
Altera::Altera(Jtag *jtag, const std::string &filename,
const std::string &file_type, int8_t verbose):
Device(jtag, filename, file_type, verbose), _svf(_jtag, _verbose)
{
if (!_file_extension.empty()) {
if (_file_extension == "svf" || _file_extension == "rbf")
_mode = Device::MEM_MODE;
else
_mode = Device::SPI_MODE;
}
}
2019-09-26 18:29:20 +02:00
Altera::~Altera()
{}
void Altera::reset()
{
/* PULSE_NCONFIG */
unsigned char tx_buff[2] = {0x01, 0x00};
_jtag->set_state(Jtag::TEST_LOGIC_RESET);
_jtag->shiftIR(tx_buff, NULL, IRLENGTH);
_jtag->toggleClk(1);
_jtag->set_state(Jtag::TEST_LOGIC_RESET);
}
void Altera::programMem()
{
RawParser _bit(_filename, false);
_bit.parse();
int byte_length = _bit.getLength()/8;
uint8_t *data = _bit.getData();
uint32_t clk_period = 1e9/(float)_jtag->getClkFreq();
unsigned char cmd[2];
unsigned char tx[864/8], rx[864/8];
memset(tx, 0, 864/8);
/* enddr idle
* endir irpause
* state idle
*/
/* ir 0x02 IRLENGTH */
*reinterpret_cast<uint16_t *>(cmd) = 0x02;
_jtag->shiftIR(cmd, NULL, IRLENGTH, Jtag::PAUSE_IR);
/* RUNTEST IDLE 12000 TCK ENDSTATE IDLE; */
_jtag->set_state(Jtag::RUN_TEST_IDLE);
_jtag->toggleClk(1000000/clk_period);
/* write */
ProgressBar progress("Flash SRAM", byte_length, 50, _quiet);
/* 2.2.6.5 */
_jtag->set_state(Jtag::SHIFT_DR);
int xfer_len = 512;
int tx_len;
int tx_end;
for (int i=0; i < byte_length; i+=xfer_len) {
if (i + xfer_len > byte_length) { // last packet with some size
tx_len = (byte_length - i) * 8;
tx_end = 1; // to move in EXIT1_DR
} else {
tx_len = xfer_len * 8;
tx_end = 0;
}
_jtag->read_write(data+i, NULL, tx_len, tx_end);
progress.display(i);
}
progress.done();
/* reboot */
/* SIR 10 TDI (004); */
*reinterpret_cast<uint16_t *>(cmd) = 0x04;
_jtag->shiftIR(cmd, NULL, IRLENGTH, Jtag::PAUSE_IR);
/* RUNTEST 60 TCK; */
_jtag->set_state(Jtag::RUN_TEST_IDLE);
_jtag->toggleClk(5000/clk_period);
/*
* SDR 864 TDI
* (000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
* TDO (00000000000000000000
* 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000)
* MASK (00000000000000000000000000000000000000000000000000
* 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000);
*/
_jtag->shiftDR(tx, rx, 864, Jtag::RUN_TEST_IDLE);
/* TBD -> something to check */
/* SIR 10 TDI (003); */
*reinterpret_cast<uint16_t *>(cmd) = 0x003;
_jtag->shiftIR(cmd, NULL, IRLENGTH, Jtag::PAUSE_IR);
/* RUNTEST 49152 TCK; */
_jtag->set_state(Jtag::RUN_TEST_IDLE);
_jtag->toggleClk(4099645/clk_period);
/* RUNTEST 512 TCK; */
_jtag->set_state(Jtag::RUN_TEST_IDLE);
_jtag->toggleClk(512);
/* SIR 10 TDI (3FF); */
*reinterpret_cast<uint16_t *>(cmd) = BYPASS;
_jtag->shiftIR(cmd, NULL, IRLENGTH, Jtag::PAUSE_IR);
/* RUNTEST 12000 TCK; */
_jtag->set_state(Jtag::RUN_TEST_IDLE);
_jtag->toggleClk(1000000/clk_period);
/* -> idle */
_jtag->set_state(Jtag::RUN_TEST_IDLE);
}
void Altera::program(unsigned int offset)
{
if (_mode == Device::NONE_MODE)
return;
/* in all case we consider svf is mandatory
* MEM_MODE : svf file provided for constructor
* is the bitstream to use
* SPI_MODE : svf file provided is bridge to have
* access to the SPI flash
*/
/* mem mode -> svf */
if (_mode == Device::MEM_MODE) {
if (_file_extension == "svf")
_svf.parse(_filename);
else
programMem();
} else if (_mode == Device::SPI_MODE) {
/* GGM: TODO: fix this issue */
EPCQ epcq(0x403, 0x6010/*_jtag->vid(), _jtag->pid()*/, 2, 6000000);
_svf.parse(BIT_FOR_FLASH);
epcq.program(offset, _filename, (_file_extension == "rpd")? true:false);
reset();
}
}
2019-09-26 18:29:20 +02:00
int Altera::idCode()
{
unsigned char tx_data[4] = {IDCODE};
unsigned char rx_data[4];
_jtag->go_test_logic_reset();
_jtag->shiftIR(tx_data, NULL, IRLENGTH);
memset(tx_data, 0, 4);
_jtag->shiftDR(tx_data, rx_data, 32);
return ((rx_data[0] & 0x000000ff) |
((rx_data[1] << 8) & 0x0000ff00) |
((rx_data[2] << 16) & 0x00ff0000) |
((rx_data[3] << 24) & 0xff000000));
}