diff --git a/anyio.c b/anyio.c index e3f8881..9192342 100644 --- a/anyio.c +++ b/anyio.c @@ -459,3 +459,20 @@ void anyio_print_supported_board_names() { printf("\n"); } +void anyio_dev_enable_all_module_outputs(board_t *board) { + if (board == NULL) { + return; + } + hm2_read_idrom(&(board->llio.hm2)); + hm2_enable_all_module_outputs(&(board->llio.hm2)); +} + +void anyio_dev_safe_io(board_t *board) { + if (board == NULL) { + return; + } + hm2_read_idrom(&(board->llio.hm2)); + hm2_safe_io(&(board->llio.hm2)); +} + + diff --git a/anyio.h b/anyio.h index 2df16f7..c67be4b 100644 --- a/anyio.h +++ b/anyio.h @@ -41,6 +41,8 @@ int anyio_dev_reset(board_t *board); void anyio_dev_print_hm2_info(board_t *board, int xml_flag); void anyio_dev_print_pin_descriptors(board_t *board); void anyio_dev_print_localio_descriptors(board_t *board); +void anyio_dev_enable_all_module_outputs(board_t *board); +void anyio_dev_safe_io(board_t *board); void anyio_dev_print_sserial_info(board_t *board); void anyio_bitfile_print_info(char *bitfile_name, int verbose_flag); void anyio_print_supported_board_names(); diff --git a/hostmot2.c b/hostmot2.c index 777163d..26ff4ae 100644 --- a/hostmot2.c +++ b/hostmot2.c @@ -59,6 +59,10 @@ hm2_module_desc_t *hm2_find_module(hostmot2_t *hm2, u8 gtag) { return NULL; } +// Note, this pin source function fails as the alt src register is not readable +// so it ends up enabling all alt src on Xilinx and disabling all but the last on +// Efinix because non-readable pins read as 1 on Xilinx and 0 on Efinix) +// probably best fixed with a altsrc shadow register, later... void hm2_set_pin_source(hostmot2_t *hm2, u32 pin_number, u8 source) { u32 data; u16 addr; @@ -74,16 +78,16 @@ void hm2_set_pin_source(hostmot2_t *hm2, u32 pin_number, u8 source) { } addr = md->base_address; - hm2->llio->read(hm2->llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + (pin_number / 24)*4, &data, sizeof(data)); + hm2->llio->read(hm2->llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + (pin_number / hm2->idrom.io_width)*4, &data, sizeof(data)); if (source == HM2_PIN_SOURCE_IS_PRIMARY) { data &= ~(1 << (pin_number % 24)); } else if (source == HM2_PIN_SOURCE_IS_SECONDARY) { - data |= (1 << (pin_number % 24)); + data |= (1 << (pin_number % hm2->idrom.io_width)); } else { printf("hm2_set_pin_source(): invalid pin source 0x%02X\n", source); return; } - hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + (pin_number / 24)*4, &data, sizeof(data)); + hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + (pin_number / hm2->idrom.io_width)*4, &data, sizeof(data)); } void hm2_set_pin_direction(hostmot2_t *hm2, u32 pin_number, u8 direction) { @@ -95,22 +99,54 @@ void hm2_set_pin_direction(hostmot2_t *hm2, u32 pin_number, u8 direction) { printf("hm2_set_pin_direction(): no IOPORT module found\n"); return; } - if (pin_number >= (hm2->idrom.io_ports*hm2->idrom.io_width)) { + if (pin_number >= (hm2->idrom.io_ports*hm2->idrom.port_width)) { printf("hm2_set_pin_direction(): invalid pin number %d\n", pin_number); return; } addr = md->base_address; - hm2->llio->read(hm2->llio, addr + HM2_MOD_OFFS_GPIO_DDR + (pin_number / 24)*4, &data, sizeof(data)); + hm2->llio->read(hm2->llio, addr + HM2_MOD_OFFS_GPIO_DDR + (pin_number / hm2->idrom.port_width)*4, &data, sizeof(data)); if (direction == HM2_PIN_DIR_IS_INPUT) { - data &= ~(1 << (pin_number % 24)); + data &= ~(1 << (pin_number % hm2->idrom.port_width)); } else if (direction == HM2_PIN_DIR_IS_OUTPUT) { - data |= (1 << (pin_number % 24)); + data |= (1 << (pin_number % hm2->idrom.port_width)); } else { printf("hm2_set_pin_direction(): invalid pin direction 0x%02X\n", direction); return; } - hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_DDR + (pin_number / 24)*4, &data, sizeof(data)); + hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_DDR + (pin_number / hm2->idrom.port_width)*4, &data, sizeof(data)); +} + +void hm2_enable_all_module_outputs(hostmot2_t *hm2) { + int num_pins; + u32 data =0xFFFFFFFF; + u16 addr; + // We write all alt src registers to 1's as this is a no-op on inputs so not harmfull + hm2_module_desc_t *md = hm2_find_module(hm2, HM2_GTAG_IOPORT); + addr = md->base_address; + for (u32 i = 0; i < hm2->llio->hm2.idrom.io_ports; i ++) { + hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + i*4, &data, sizeof(data)); + } + num_pins = hm2->llio->hm2.idrom.io_ports * hm2->llio->hm2.idrom.port_width; + + for (int i = 0; i < num_pins; i ++) { + hm2_pin_desc_t *pd = &hm2->llio->hm2.pins[i]; + if (pd->sec_pin & 0x80) { + hm2_set_pin_direction(hm2, i, HM2_PIN_DIR_IS_OUTPUT); + } + } +} + +void hm2_safe_io(hostmot2_t *hm2) { + u32 data =0x00000000; + u16 addr; + // We write all alt src registers and DDR registers to 0 which is the startup I/O state + hm2_module_desc_t *md = hm2_find_module(hm2, HM2_GTAG_IOPORT); + addr = md->base_address; + for (u32 i = 0; i < hm2->llio->hm2.idrom.io_ports; i ++) { + hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + i*4, &data, sizeof(data)); + hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_DDR + i*4, &data, sizeof(data)); + } } // PIN FILE GENERATING SUPPORT diff --git a/hostmot2.h b/hostmot2.h index e24f36d..431772b 100644 --- a/hostmot2.h +++ b/hostmot2.h @@ -94,6 +94,8 @@ hm2_module_desc_t *hm2_find_module(hostmot2_t *hm2, u8 gtag); void hm2_print_pin_file(llio_t *llio, int xml_flag); void hm2_print_pin_descriptors(llio_t *llio); void hm2_print_localio_descriptors(llio_t *llio); +void hm2_enable_all_module_outputs(hostmot2_t *hm2); +void hm2_safe_io(hostmot2_t *hm2); void hm2_set_pin_source(hostmot2_t *hm2, u32 pin_number, u8 source); void hm2_set_pin_direction(hostmot2_t *hm2, u32 pin_number, u8 direction); void sserial_module_init(llio_t *llio); diff --git a/mesaflash.c b/mesaflash.c index 6ec2973..ed20b06 100644 --- a/mesaflash.c +++ b/mesaflash.c @@ -32,7 +32,7 @@ #endif #ifndef VERSION -#define VERSION "3.5.5" +#define VERSION "3.5.6" #endif static int device_flag; @@ -66,6 +66,8 @@ static u32 wpo_data; static int set_flag; static int ipaddr_flag; static int ledmode_flag; +static int enable_all_mod_flag; +static int safe_io_flag; static int xml_flag; static char *lbp16_set_ip_addr; static char *lbp16_set_led_mode; @@ -103,6 +105,8 @@ static struct option long_options[] = { {"serial", no_argument, &serial_flag, 1}, {"rpo", required_argument, 0, 'r'}, {"wpo", required_argument, 0, 'o'}, + {"enable-all-mod", no_argument, &enable_all_mod_flag, 1}, + {"safe-io", no_argument, &safe_io_flag, 1}, {"set", required_argument, 0, 's'}, {"xml", no_argument, &xml_flag, 1}, {"dbname1", required_argument, NULL, '1'}, @@ -209,6 +213,9 @@ void print_usage() { printf(" Ethernet boards).\n"); printf(" --set ledmode=n Set LED mode in EEPROM memory to n, 0 = Hostmot2, 1=Debug\n"); printf(" Default debug is RX packet count. (Only Ethernet boards).\n"); + printf(" --enable-all-mod Enable all module outputs. For low level debugging\n"); + printf(" Note that this is NOT safe for cards connected to equipment\n"); + printf(" --safe-io Return all I/O to default power up state\n"); printf(" --info Print info about configuration in 'filename'.\n"); printf(" --version Print the version.\n"); printf(" --help Print this help message.\n"); @@ -430,7 +437,7 @@ int process_cmd_line(int argc, char *argv[]) { info_flag++; } break; - + case 'h': { print_usage(); exit(0); @@ -541,6 +548,10 @@ int main(int argc, char *argv[]) { ret = anyio_dev_set_remote_ip(board, lbp16_set_ip_addr); } else if (ledmode_flag == 1) { ret = anyio_dev_set_led_mode(board, lbp16_set_led_mode); + } else if (enable_all_mod_flag == 1) { + anyio_dev_enable_all_module_outputs(board); + } else if (safe_io_flag == 1) { + anyio_dev_safe_io(board); } else if (write_flag == 1) { ret = anyio_dev_write_flash(board, bitfile_name, fallback_flag, fix_boot_flag, sha256_check_flag); if (ret == 0) {