#include <fcntl.h> /* _O_BINARY */
#endif
-#include "mpsse.h"
#include "jtag.h"
#include "lattice_cmds.h"
FC_RESET = 0x99, /* Reset Device */
};
+
+// ---------------------------------------------------------
+// JTAG -> SPI functions
+// ---------------------------------------------------------
+
+/*
+ * JTAG performrs all shifts LSB first, our FLSAH is expeting bytes MSB first,
+ * There are a few ways to fix this, for now we just bit-reverse all the input data to the JTAG core
+ */
+uint8_t bit_reverse(uint8_t in){
+
+ uint8_t out = (in & 0x01) ? 0x80 : 0x00;
+ out |= (in & 0x02) ? 0x40 : 0x00;
+ out |= (in & 0x04) ? 0x20 : 0x00;
+ out |= (in & 0x08) ? 0x10 : 0x00;
+ out |= (in & 0x10) ? 0x08 : 0x00;
+ out |= (in & 0x20) ? 0x04 : 0x00;
+ out |= (in & 0x40) ? 0x02 : 0x00;
+ out |= (in & 0x80) ? 0x01 : 0x00;
+
+ return out;
+}
+
+void xfer_spi(uint8_t* data, uint32_t len){
+ /* Reverse bit order of all bytes */
+ for(int i = 0; i < len; i++){
+ data[i] = bit_reverse(data[i]);
+ }
+
+ /* Don't switch states if we're already in SHIFT-DR */
+ if(jtag_current_state() != STATE_SHIFT_DR)
+ jtag_go_to_state(STATE_SHIFT_DR);
+ jtag_tap_shift(data, data, len * 8, true);
+
+ /* Reverse bit order of all return bytes */
+ for(int i = 0; i < len; i++){
+ data[i] = bit_reverse(data[i]);
+ }
+}
+
+void send_spi(uint8_t* data, uint32_t len){
+ uint8_t unused[len];
+
+ /* Flip bit order of all bytes */
+ for(int i = 0; i < len; i++){
+ data[i] = bit_reverse(data[i]);
+ }
+
+ jtag_go_to_state(STATE_SHIFT_DR);
+ /* Stay in SHIFT-DR state, this keep CS low */
+ jtag_tap_shift(data, unused, len * 8, false);
+}
+
// ---------------------------------------------------------
// FLASH function implementations
// ---------------------------------------------------------
xfer_spi(data, 8);
}
-static void flash_power_up()
-{
- uint8_t data_rpd[1] = { FC_RPD };
- xfer_spi(data_rpd, 1);
-}
-
-static void flash_power_down()
-{
- uint8_t data[1] = { FC_PD };
- xfer_spi(data, 1);
-}
-
static uint8_t flash_read_status()
{
uint8_t data[2] = { FC_RSR1 };
}
-// ---------------------------------------------------------
-// JTAG -> SPI functions
-// ---------------------------------------------------------
-
-/*
- * JTAG performrs all shifts LSB first, our FLSAH is expeting bytes MSB first,
- * There are a few ways to fix this, for now we just bit-reverse all the input data to the JTAG core
- */
-uint8_t bit_reverse(uint8_t in){
-
- uint8_t out = (in & 0x01) ? 0x80 : 0x00;
- out |= (in & 0x02) ? 0x40 : 0x00;
- out |= (in & 0x04) ? 0x20 : 0x00;
- out |= (in & 0x08) ? 0x10 : 0x00;
- out |= (in & 0x10) ? 0x08 : 0x00;
- out |= (in & 0x20) ? 0x04 : 0x00;
- out |= (in & 0x40) ? 0x02 : 0x00;
- out |= (in & 0x80) ? 0x01 : 0x00;
-
- return out;
-}
-
-void xfer_spi(uint8_t* data, uint32_t len){
- /* Reverse bit order of all bytes */
- for(int i = 0; i < len; i++){
- data[i] = bit_reverse(data[i]);
- }
-
- /* Don't switch states if we're already in SHIFT-DR */
- if(jtag_current_state() != STATE_SHIFT_DR)
- jtag_go_to_state(STATE_SHIFT_DR);
- jtag_tap_shift(data, data, len * 8, true);
-
- /* Reverse bit order of all return bytes */
- for(int i = 0; i < len; i++){
- data[i] = bit_reverse(data[i]);
- }
-}
-
-void send_spi(uint8_t* data, uint32_t len){
- uint8_t unused[len];
-
- /* Flip bit order of all bytes */
- for(int i = 0; i < len; i++){
- data[i] = bit_reverse(data[i]);
- }
-
- jtag_go_to_state(STATE_SHIFT_DR);
- /* Stay in SHIFT-DR state, this keep CS low */
- jtag_tap_shift(data, unused, len * 8, false);
-}
-
// ---------------------------------------------------------
// ECP5 specific JTAG functions
// ---------------------------------------------------------
// ---------------------------------------------------------
fprintf(stderr, "init..");
- mpsse_init(ifnum, devstr, slow_clock);
-
- fprintf(stderr, "jtag..\n");
- mpsse_jtag_init();
+ jtag_init(ifnum, devstr, slow_clock);
fprintf(stderr, "idcode..\n");
read_idcode();
flash_reset();
- flash_power_up();
flash_read_id();
flash_read(rw_offset + addr, buffer_flash, rc);
if (memcmp(buffer_file, buffer_flash, rc)) {
fprintf(stderr, "Found difference between flash and file!\n");
- mpsse_error(3);
+ jtag_error(3);
}
}
// ---------------------------------------------------------
fprintf(stderr, "Bye.\n");
- mpsse_close();
+ jtag_deinit();
return 0;
}
current_state = state;
}
-
-/**
- * Hook for any per-platform initialization that needs to occur.
- */
-__attribute__((weak)) void jtag_platform_init(void)
-{
-
+void jtag_error(int status){
+ mpsse_error(status);
}
+void jtag_deinit(){
+ mpsse_close();
+}
/**
* Performs any start-of-day tasks necessary to talk JTAG to our FPGA.
*/
-void jtag_init(void)
+void jtag_init(int ifnum, const char *devstr, bool slow_clock)
{
- jtag_platform_init();
+ mpsse_init(ifnum, devstr, slow_clock);
+
jtag_set_current_state(STATE_TEST_LOGIC_RESET);
jtag_go_to_state(STATE_TEST_LOGIC_RESET);
}
extern struct ftdi_context mpsse_ftdic;
-static inline uint8_t jtag_pulse_clock_and_read_tdo(bool tms, bool tdi)
+static inline void jtag_pulse_clock_and_read_tdo(bool tms, bool tdi)
{
- uint8_t ret;
*ptr++ = MC_DATA_TMS | MC_DATA_IN | MC_DATA_LSB | MC_DATA_BITS;
*ptr++ = 0;
*ptr++ = (tdi ? 0x80 : 0) | (tms ? 0x01 : 0);
for (uint32_t i = 0; i < byte_count; ++i) {
uint8_t byte_out = input_data[i];
- uint8_t tdo_byte = 0;
for (int j = 0; j < 8 && bit_count-- > 0; ++j) {
bool tms = false;
if (bit_count == 0 && must_end) {
mpsse_xfer(data, 3, 0);
} else {
- uint8_t d = 0;
- uint8_t count = 0;
-
- uint8_t* ptr = data;
-
while (jtag_current_state() != state) {
uint8_t data[3] = {
MC_DATA_TMS | MC_DATA_LSB | MC_DATA_ICN | MC_DATA_BITS,