X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2FOpenULINK%2Fsrc%2Fprotocol.c;h=9688fbdd093558f04c770e9c0b22fa0e50165f43;hp=05929d0f99d8164eb57fd055f2407f904fdea97e;hb=a2935397b48ce2a1bbb8e49258b340479e0b9c8e;hpb=3c3f3c42472faa0414a8096133cb9b8a9ab37c86 diff --git a/src/jtag/drivers/OpenULINK/src/protocol.c b/src/jtag/drivers/OpenULINK/src/protocol.c index 05929d0f99..9688fbdd09 100644 --- a/src/jtag/drivers/OpenULINK/src/protocol.c +++ b/src/jtag/drivers/OpenULINK/src/protocol.c @@ -28,18 +28,19 @@ #include "reg_ezusb.h" /** - * @file Implementation of the OpenULINK communication protocol. + * @file + * Implementation of the OpenULINK communication protocol. * * The OpenULINK protocol uses one OUT and one IN endpoint. These two endpoints * are configured to use the maximum packet size for full-speed transfers, * 64 bytes. Commands always start with a command ID (see msgtypes.h for * command ID definitions) and contain zero or more payload data bytes in both - * transfer directions (IN and OUT). The payload + * transfer directions (IN and OUT). The payload * * Almost all commands contain a fixed number of payload data bytes. The number * of payload data bytes for the IN and OUT direction does not need to be the * same. - * + * * Multiple commands may be sent in one EP2 Bulk-OUT packet. Because the * OpenULINK firmware does not perform bounds checking for EP2 Bulk-IN packets, * the host MUST ensure that the commands sent in the OUT packet require a @@ -47,130 +48,156 @@ */ /** Index in EP2 Bulk-OUT data buffer that contains the current command ID */ -volatile u8 cmd_id_index; +volatile uint8_t cmd_id_index; /** Number of data bytes already in EP2 Bulk-IN buffer */ -volatile u8 payload_index_in; +volatile uint8_t payload_index_in; /** * Execute a SET_LEDS command. */ void execute_set_led_command(void) { - u8 led_state = OUT2BUF[cmd_id_index + 1]; + uint8_t led_state = OUT2BUF[cmd_id_index + 1]; - if (led_state & RUN_LED_ON) { - SET_RUN_LED(); - } + if (led_state & RUN_LED_ON) + SET_RUN_LED(); - if (led_state & COM_LED_ON) { - SET_COM_LED(); - } + if (led_state & COM_LED_ON) + SET_COM_LED(); - if (led_state & RUN_LED_OFF) { - CLEAR_RUN_LED(); - } + if (led_state & RUN_LED_OFF) + CLEAR_RUN_LED(); - if (led_state & COM_LED_OFF) { - CLEAR_COM_LED(); - } + if (led_state & COM_LED_OFF) + CLEAR_COM_LED(); } /** * Executes one command and updates global command indexes. * - * @param index the index of the Bulk EP2-OUT data buffer at which the - * command ID is stored. * @return true if this command was the last command. * @return false if there are more commands within the current contents of the - * Bulk EP2-OUT data buffer. + * Bulk EP2-OUT data buffer. */ bool execute_command(void) { - u8 usb_out_bytecount, usb_in_bytecount; - u16 signal_state; - u16 count; - - /* Most commands do not transfer IN data. To save code space, we write 0 to - * usb_in_bytecount here, then modify it in the switch statement below where - * neccessary */ - usb_in_bytecount = 0; - - switch (OUT2BUF[cmd_id_index] /* Command ID */) { - case CMD_SCAN_IN: - usb_out_bytecount = 5; - usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; - jtag_scan_in(cmd_id_index + 1, payload_index_in); - break; - case CMD_SCAN_OUT: - usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5; - jtag_scan_out(cmd_id_index + 1); - break; - case CMD_SCAN_IO: - usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; - usb_out_bytecount = usb_in_bytecount + 5; - jtag_scan_io(cmd_id_index + 1, payload_index_in); - break; - case CMD_CLOCK_TMS: - usb_out_bytecount = 2; - jtag_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]); - break; - case CMD_CLOCK_TCK: - usb_out_bytecount = 2; - count = (u16)OUT2BUF[cmd_id_index + 1]; - count |= ((u16)OUT2BUF[cmd_id_index + 2]) << 8; - jtag_clock_tck(count); - break; - case CMD_SLEEP_US: - usb_out_bytecount = 2; - count = (u16)OUT2BUF[cmd_id_index + 1]; - count |= ((u16)OUT2BUF[cmd_id_index + 2]) << 8; - delay_us(count); - break; - case CMD_SLEEP_MS: - usb_out_bytecount = 2; - count = (u16)OUT2BUF[cmd_id_index + 1]; - count |= ((u16)OUT2BUF[cmd_id_index + 2]) << 8; - delay_ms(count); - break; - case CMD_GET_SIGNALS: - usb_out_bytecount = 0; - usb_in_bytecount = 2; - signal_state = jtag_get_signals(); - IN2BUF[payload_index_in] = (signal_state >> 8) & 0x00FF; - IN2BUF[payload_index_in + 1] = signal_state & 0x00FF; - break; - case CMD_SET_SIGNALS: - usb_out_bytecount = 2; - jtag_set_signals(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]); - break; - case CMD_SET_LEDS: - usb_out_bytecount = 1; - execute_set_led_command(); - break; - case CMD_TEST: - usb_out_bytecount = 1; - /* Do nothing... This command is only used to test if the device is ready - * to accept new commands */ - break; - default: - /* Should never be reached */ - usb_out_bytecount = 0; - break; - } - - /* Update EP2 Bulk-IN data byte count */ - payload_index_in += usb_in_bytecount; - - /* Determine if this was the last command */ - if ((cmd_id_index + usb_out_bytecount + 1) >= OUT2BC) { - return true; - } - else { - /* Not the last command, update cmd_id_index */ - cmd_id_index += (usb_out_bytecount + 1); - return false; - } + uint8_t usb_out_bytecount, usb_in_bytecount; + uint16_t signal_state; + uint16_t count; + + /* Most commands do not transfer IN data. To save code space, we write 0 to + * usb_in_bytecount here, then modify it in the switch statement below where + * neccessary */ + usb_in_bytecount = 0; + + switch (OUT2BUF[cmd_id_index] /* Command ID */) { + case CMD_SCAN_IN: + usb_out_bytecount = 5; + usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; + jtag_scan_in(cmd_id_index + 1, payload_index_in); + break; + case CMD_SCAN_OUT: + usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5; + jtag_scan_out(cmd_id_index + 1); + break; + case CMD_SCAN_IO: + usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; + usb_out_bytecount = usb_in_bytecount + 5; + jtag_scan_io(cmd_id_index + 1, payload_index_in); + break; + case CMD_CLOCK_TMS: + usb_out_bytecount = 2; + jtag_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]); + break; + case CMD_CLOCK_TCK: + usb_out_bytecount = 2; + count = (uint16_t)OUT2BUF[cmd_id_index + 1]; + count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8; + jtag_clock_tck(count); + break; + case CMD_SLOW_SCAN_IN: + usb_out_bytecount = 5; + usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; + jtag_slow_scan_in(cmd_id_index + 1, payload_index_in); + break; + case CMD_SLOW_SCAN_OUT: + usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5; + jtag_slow_scan_out(cmd_id_index + 1); + break; + case CMD_SLOW_SCAN_IO: + usb_in_bytecount = OUT2BUF[cmd_id_index + 1]; + usb_out_bytecount = usb_in_bytecount + 5; + jtag_slow_scan_io(cmd_id_index + 1, payload_index_in); + break; + case CMD_SLOW_CLOCK_TMS: + usb_out_bytecount = 2; + jtag_slow_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]); + break; + case CMD_SLOW_CLOCK_TCK: + usb_out_bytecount = 2; + count = (uint16_t)OUT2BUF[cmd_id_index + 1]; + count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8; + jtag_slow_clock_tck(count); + break; + case CMD_SLEEP_US: + usb_out_bytecount = 2; + count = (uint16_t)OUT2BUF[cmd_id_index + 1]; + count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8; + delay_us(count); + break; + case CMD_SLEEP_MS: + usb_out_bytecount = 2; + count = (uint16_t)OUT2BUF[cmd_id_index + 1]; + count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8; + delay_ms(count); + break; + case CMD_GET_SIGNALS: + usb_out_bytecount = 0; + usb_in_bytecount = 2; + signal_state = jtag_get_signals(); + IN2BUF[payload_index_in] = (signal_state >> 8) & 0x00FF; + IN2BUF[payload_index_in + 1] = signal_state & 0x00FF; + break; + case CMD_SET_SIGNALS: + usb_out_bytecount = 2; + jtag_set_signals(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]); + break; + case CMD_CONFIGURE_TCK_FREQ: + usb_out_bytecount = 5; + jtag_configure_tck_delay( + OUT2BUF[cmd_id_index + 1], /* scan_in */ + OUT2BUF[cmd_id_index + 2], /* scan_out */ + OUT2BUF[cmd_id_index + 3], /* scan_io */ + OUT2BUF[cmd_id_index + 4], /* clock_tck */ + OUT2BUF[cmd_id_index + 5]); /* clock_tms */ + break; + case CMD_SET_LEDS: + usb_out_bytecount = 1; + execute_set_led_command(); + break; + case CMD_TEST: + usb_out_bytecount = 1; + /* Do nothing... This command is only used to test if the device is ready + * to accept new commands */ + break; + default: + /* Should never be reached */ + usb_out_bytecount = 0; + break; + } + + /* Update EP2 Bulk-IN data byte count */ + payload_index_in += usb_in_bytecount; + + /* Determine if this was the last command */ + if ((cmd_id_index + usb_out_bytecount + 1) >= OUT2BC) + return true; + else { + /* Not the last command, update cmd_id_index */ + cmd_id_index += (usb_out_bytecount + 1); + return false; + } } /** @@ -178,35 +205,36 @@ bool execute_command(void) */ void command_loop(void) { - bool last_command; - - while (1) { - cmd_id_index = 0; - payload_index_in = 0; - - /* Wait until host sends EP2 Bulk-OUT packet */ - while (!EP2_out); - EP2_out = 0; - - /* Turn on COM LED to indicate command execution */ - SET_COM_LED(); - - /* Execute the commands */ - last_command = false; - while (last_command == false) { - last_command = execute_command(); - } - - CLEAR_COM_LED(); - - /* Send back EP2 Bulk-IN packet if required */ - if (payload_index_in > 0) { - IN2BC = payload_index_in; - while (!EP2_in); - EP2_in = 0; - } - - /* Re-arm EP2-OUT after command execution */ - OUT2BC = 0; - } + bool last_command; + + while (1) { + cmd_id_index = 0; + payload_index_in = 0; + + /* Wait until host sends EP2 Bulk-OUT packet */ + while (!EP2_out) + ; + EP2_out = 0; + + /* Turn on COM LED to indicate command execution */ + SET_COM_LED(); + + /* Execute the commands */ + last_command = false; + while (last_command == false) + last_command = execute_command(); + + CLEAR_COM_LED(); + + /* Send back EP2 Bulk-IN packet if required */ + if (payload_index_in > 0) { + IN2BC = payload_index_in; + while (!EP2_in) + ; + EP2_in = 0; + } + + /* Re-arm EP2-OUT after command execution */ + OUT2BC = 0; + } }