On Tuesday 02 March 2010, simon qian wrote:
> I think it's the time to implement this feature.

Depends what you mean by $SUBJECT, or "interface".

I'd tend to think "multi-transport" support would be more important
to have than supporting multiple debug adapters a the same time.


> For STM32 JTAG/SWD support, this feature is MUCH more difficult than the
> change in ADIv5 code.

More "pervasive", sure.  On the other hand, it's a lot simpler
at a conceptual level ...

 
> 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

I have no idea what most of these would be ...

... however you will notice that there is now a flag word
called "jtag_interface.supported".  I had imagined would soon
grow at least DEBUG_CAP_SWD to indicate a dual-mode JTAG/SWD
adapter.



> #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.

There are 45 tcl/interface/*.cfg files today, so if you're using the
word "interface" to mean "debug adapter" and want to assign one bit
to each of them, I can see how that would be a problem.

But we're not talking about that many transports, so far as I understand.
And I'm fairly sure we'll also need a way to map strings to whatever kind
of transport ID we end up using.  My first thought would be to use
pointers to some kind of per-transport struct.

 
> Every target must define a interface_needed according to different
> program_mode.
> For AVR:
> const struct program_mode_t avr8_program_mode[] =

OK, now I'm not following much at all.  Many targets won't have
options here; e.g. they're JTAG-only.

Plus by "program_mode" you suggest flash writing, not debugging ...

Agreed that if we want to support, for example, various ROM codes:

        + Programming Stellaris chips over UART, SSI, or I2C, using their
          Boot Loader, which "is executed from the ROM when flash is
          empty and is used to download code to the flash memory of a
          device without the use of a debug interface"  (or on some
          chips can be invoked by application firmware)

        * Programming LPC17xx chips over UART using their Boot Loader
          in ISP mode

        * ... and I don't doubt that there are more examples of ways
          vendors let firmware be loaded onto chips, without using any
          debug-capable link

Then we'd need to add a "program mode for those targets.  But not all
targets have them -- not even all microcontrollers -- so not all would
need to define such a thing.

There is one similarity I see between talking to chips over e.g. UART
vs JTAG or SWD ... initializing OpenOCD would be very different from
the current "everything uses JTAG" model.  But in the case of wanting
to talk to a bootloader to program the chip ... there's more to it
than that:  we wouldn't even be able to consider using the link to
debug, with GDB.  It would be a program-only link.

So this suggests two new major flavors of mode for OpenOCD.  One
would be the transport type (JTAG, SWD, UART, etc) ... another would
be called maybe "operation" type:  "debug" or "program".

Previously everything has assumed "debug" via "JTAG".

- Dave


> {
>     {'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
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to