I think it's the time to implement this feature. For STM32 JTAG/SWD support, this feature is MUCH more difficult than the change in ADIv5 code.
I demonstrate the multi-interface framework in vsprog, which is the programmer for Versaloon supporting JTAG/SWD/SPI/UART/USART/IIC/PSoC_ISSP/LPC900_ICP/C8051F_C2/STM8_SWIM and so on. Every interface has an ID(bit-mask): // interfaces #define USART (1 << 0) // UART and USART #define SPI (1 << 1) #define I2C (1 << 2) #define GPIO (1 << 3) #define CAN (1 << 4) #define CLOCK (1 << 5) // clock output control #define ADC (1 << 6) // analog to digit #define DAC (1 << 7) // digit to analog #define POWER (1 << 8) // power output control #define ISSP (1 << 16) // PSoc_ISSP #define JTAG_LL (1 << 17) // similar low level driver to OpenOCD JTAG drive, used in SVF Player #define JTAG_HL (1 << 18) // A high level driver used in MCU support #define MSP430_SBW (1 << 19) #define C2 (1 << 20) // C8051F_C2 #define MSP430_JTAG (1 << 21) #define LPC_ICP (1 << 22) // LPC900_ICP #define SWJ (1 << 23) // acutally it should be SWD #define SWIM (1 << 24) // STM8_SWIM #define HV (1 << 25) // High Voltage control, some targets including AVR/PIC need High Voltage support ...... Disadvantage is that the number of interfaces is limitted, if using 64-bit integer, ONLY 64 interfaces can be defined. Every target must define a interface_needed according to different program_mode. For AVR: const struct program_mode_t avr8_program_mode[] = { {'i', SET_FREQUENCY, SPI | GPIO}, // ISP mode, SPI and GPIO(for reset control) is needed {'j', SET_FREQUENCY, JTAG_HL}, // JTAG mode, JTAG_HL is needed {'p', "", HV | GPIO}, // High Voltage Parallel Mode, HV and GPIO {'s', "", HV | GPIO}, // High Voltage Serial Mode, HV and GPIO {0, NULL, 0} }; For STM32: const struct program_mode_t stm32_program_mode[] = { {'j', SET_FREQUENCY, JTAG_HL}, // JTAG mode, JTAG_HL {'s', "", SWJ}, // SWD mode, SWJ {'i', USE_COMM, 0}, // ISP mode, ComPort on PC {0, NULL, 0} }; When initializing dongle, a interface_supported should be returned to indicate the supported interfaces. // init programmer capabilities cur_programmer->init_capability(cur_programmer); RESULT versaloon_init_capability(void *p) { struct programmer_info_t *t = (struct programmer_info_t *)p; t->init = versaloon_init; t->fini = versaloon_fini; t->interfaces = (SPI | GPIO | ISSP | JTAG_LL | JTAG_HL | SWIM | C2 | MSP430_JTAG | MSP430_SBW | LPC_ICP | SWJ); ...... // SPI t->spi_init = versaloon_spi_init; t->spi_fini = versaloon_spi_fini; t->spi_config = versaloon_spi_config; t->spi_io = versaloon_spi_io; ...... // GPIO t->gpio_init = versaloon_gpio_init; t->gpio_fini = versaloon_gpio_fini; t->gpio_config = versaloon_gpio_config; t->gpio_in = versaloon_gpio_in; t->gpio_out = versaloon_gpio_out; ...... } Check whether the specified mode of the target is supported. // init and check programmer's ability i = cur_target->program_mode[program_info.mode].interface_needed; if ((cur_programmer->interfaces & i) != i) { LOG_ERROR(_GETTEXT("%s can not support %s in the mode defined.\n"), cur_programmer->name, cur_target->name); free_all_and_exit(EXIT_FAILURE); } And then, target related code could call the specified interfaces. // init spi_init(); reset_init(); // use avr8_isp_frequency spi_conf(pi->frequency); // toggle reset reset_clr(); reset_output(); delay_ms(1); reset_input(); delay_ms(1); reset_clr(); reset_output(); delay_ms(10); // enter into program mode command cmd_buf[0] = 0xAC; cmd_buf[1] = 0x53; cmd_buf[2] = 0x00; cmd_buf[3] = 0x00; poll_byte = 0; // ret[2] should be 0x53 spi_io(cmd_buf, 4, &poll_byte, 2, 1); // send out 4 bytes in cmd_buf, receive 1 byte from the 2nd byte into poll_byte if ((ERROR_OK != commit()) || (poll_byte != 0x53)) { return ERRCODE_FAILURE_ENTER_PROG_MODE; } -- Best Regards, SimonQian http://www.SimonQian.com
_______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development