-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use JTAG to invoke offline mode #28
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
f40010c
firmware: reset JTAG before reconfiguring FPGA
mossmann 97c624d
firmware: jtag_scan()
mossmann ee9aa58
firmware: go offline with JTAG, not PROGRAMN pin
mossmann 97dcca9
firmware: clean up button and USB switch handling
mossmann 1db534c
firmware: FPGA offline at start-up if button
mossmann 9ece423
Unconfigure FPGA before flash operations
mossmann 5a4b6b4
Keep FPGA offline after flash programming
mossmann cc77f52
Remove `apollo force-offline` warning
mossmann dd8a4a3
Reduce excessive USB timeout
mossmann 52c2ee3
firmware: respond to FPGA vendor requests
mossmann bfad85a
firmware: explain JTAG reset for reconfiguration
mossmann File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,15 @@ | ||
/** | ||
* Code for basic FPGA interfacing. | ||
* | ||
* This file is part of LUNA. | ||
* | ||
* Copyright (c) 2020 Great Scott Gadgets <[email protected]> | ||
* Copyright (c) 2020-2023 Great Scott Gadgets <[email protected]> | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
#include <bsp/board_api.h> | ||
#include <hal/include/hal_gpio.h> | ||
|
||
#include <apollo_board.h> | ||
#include "apollo_board.h" | ||
#include "jtag.h" | ||
|
||
/** | ||
* Sets up the I/O pins needed to configure the FPGA. | ||
|
@@ -28,6 +27,18 @@ void fpga_io_init(void) | |
*/ | ||
void trigger_fpga_reconfiguration(void) | ||
{ | ||
/* | ||
* If the JTAG TAP was left in certain states, pulsing PROGRAMN has no | ||
* effect, so we reset the state first. | ||
*/ | ||
jtag_init(); | ||
jtag_go_to_state(STATE_TEST_LOGIC_RESET); | ||
jtag_wait_time(2); | ||
jtag_deinit(); | ||
|
||
/* | ||
* Now pulse PROGRAMN to instruct the FPGA to configure itself. | ||
*/ | ||
gpio_set_pin_direction(FPGA_PROGRAM, GPIO_DIRECTION_OUT); | ||
gpio_set_pin_level(FPGA_PROGRAM, false); | ||
|
||
|
@@ -36,13 +47,3 @@ void trigger_fpga_reconfiguration(void) | |
gpio_set_pin_level(FPGA_PROGRAM, true); | ||
gpio_set_pin_direction(FPGA_PROGRAM, GPIO_DIRECTION_IN); | ||
} | ||
|
||
|
||
/** | ||
* Requests that we hold the FPGA in an unconfigured state. | ||
*/ | ||
void force_fpga_offline(void) | ||
{ | ||
gpio_set_pin_direction(FPGA_PROGRAM, GPIO_DIRECTION_OUT); | ||
gpio_set_pin_level(FPGA_PROGRAM, false); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
/** | ||
* This file is part of LUNA. | ||
* | ||
* Copyright (c) 2020 Great Scott Gadgets <[email protected]> | ||
* Copyright (c) 2020-2023 Great Scott Gadgets <[email protected]> | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
|
@@ -13,17 +11,6 @@ | |
|
||
#include <jtag.h> | ||
|
||
extern uint8_t jtag_in_buffer[256]; | ||
extern uint8_t jtag_out_buffer[256]; | ||
|
||
/** | ||
* Flags for our JTAG commands. | ||
*/ | ||
enum { | ||
FLAG_ADVANCE_STATE = 0b01, | ||
FLAG_FORCE_BITBANG = 0b10 | ||
}; | ||
|
||
|
||
/** | ||
* Hook that performs hardware-specific initialization. | ||
|
@@ -50,60 +37,3 @@ void jtag_platform_deinit(void) | |
// Restore use of our connection to a default of being a UART. | ||
uart_configure_pinmux(); | ||
} | ||
|
||
|
||
/** | ||
* Request that performs the actual JTAG scan event. | ||
* Arguments: | ||
* wValue: the number of bits to scan; total | ||
* wIndex: | ||
* - 1 if the given command should advance the FSM | ||
* - 2 if the given command should be sent using the slow method | ||
*/ | ||
bool handle_jtag_request_scan(uint8_t rhport, tusb_control_request_t const* request) | ||
{ | ||
// Our bulk method can only send whole bytes; so send as many bytes as we can | ||
// using the fast method; and then send the remainder using our slow method. | ||
size_t bytes_to_send_bulk = request->wValue / 8; | ||
size_t bits_to_send_slow = request->wValue % 8; | ||
|
||
// We can't handle 0-byte transfers; fail out. | ||
if (!bits_to_send_slow && !bytes_to_send_bulk) { | ||
return false; | ||
} | ||
|
||
// If this would scan more than we have buffer for, fail out. | ||
if (bytes_to_send_bulk > sizeof(jtag_out_buffer)) { | ||
return false; | ||
} | ||
|
||
// If we've been asked to send data the slow way, honor that, and send all of our bits | ||
// using the slow method. | ||
if (request->wIndex & FLAG_FORCE_BITBANG) { | ||
bytes_to_send_bulk = 0; | ||
bits_to_send_slow = request->wValue; | ||
} | ||
|
||
// If we're going to advance state, always make sure the last bit is sent using the slow method, | ||
// so we can handle JTAG TAP state advancement on the last bit. If we don't have any bits to send slow, | ||
// send the last byte slow. | ||
if (!bits_to_send_slow && (request->wIndex & FLAG_ADVANCE_STATE)) { | ||
bytes_to_send_bulk--; | ||
bits_to_send_slow = 8; | ||
} | ||
|
||
// Switch to SPI mode, and send the bulk of the transfer using it. | ||
if (bytes_to_send_bulk) { | ||
spi_configure_pinmux(SPI_FPGA_JTAG); | ||
spi_send(SPI_FPGA_JTAG, jtag_out_buffer, jtag_in_buffer, bytes_to_send_bulk); | ||
} | ||
|
||
// Switch back to GPIO mode, and send the remainder using the slow method. | ||
spi_release_pinmux(SPI_FPGA_JTAG); | ||
if (bits_to_send_slow) { | ||
jtag_tap_shift(jtag_out_buffer + bytes_to_send_bulk, jtag_in_buffer + bytes_to_send_bulk, | ||
bits_to_send_slow, request->wIndex); | ||
} | ||
return tud_control_xfer(rhport, request, NULL, 0); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,15 @@ | ||
/** | ||
* Code for basic FPGA interfacing. | ||
* | ||
* This file is part of LUNA. | ||
* | ||
* Copyright (c) 2020 Great Scott Gadgets <[email protected]> | ||
* Copyright (c) 2020-2023 Great Scott Gadgets <[email protected]> | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
#include <bsp/board_api.h> | ||
#include <hal/include/hal_gpio.h> | ||
|
||
#include "jtag.h" | ||
|
||
// List of pins used for FPGA interfacing. | ||
enum { | ||
DONE_GPIO = PIN_PA15, | ||
|
@@ -44,6 +44,18 @@ void fpga_io_init(void) | |
*/ | ||
void trigger_fpga_reconfiguration(void) | ||
{ | ||
/* | ||
* If the JTAG TAP was left in certain states, pulsing PROGRAMN has no | ||
* effect, so we reset the state first. | ||
*/ | ||
jtag_init(); | ||
jtag_go_to_state(STATE_TEST_LOGIC_RESET); | ||
jtag_wait_time(2); | ||
jtag_deinit(); | ||
|
||
/* | ||
* Now pulse PROGRAMN to instruct the FPGA to configure itself. | ||
*/ | ||
gpio_set_pin_direction(PIN_PROG, GPIO_DIRECTION_OUT); | ||
gpio_set_pin_level(PIN_PROG, false); | ||
|
||
|
@@ -52,13 +64,3 @@ void trigger_fpga_reconfiguration(void) | |
gpio_set_pin_level(PIN_PROG, true); | ||
gpio_set_pin_direction(PIN_PROG, GPIO_DIRECTION_IN); | ||
} | ||
|
||
|
||
/** | ||
* Requests that we hold the FPGA in an unconfigured state. | ||
*/ | ||
void force_fpga_offline(void) | ||
{ | ||
gpio_set_pin_direction(PIN_PROG, GPIO_DIRECTION_OUT); | ||
gpio_set_pin_level(PIN_PROG, false); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
/** | ||
* This file is part of LUNA. | ||
* | ||
* Copyright (c) 2020 Great Scott Gadgets <[email protected]> | ||
* Copyright (c) 2020-2023 Great Scott Gadgets <[email protected]> | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
|
@@ -12,9 +10,6 @@ | |
|
||
#include <jtag.h> | ||
|
||
extern uint8_t jtag_in_buffer[256]; | ||
extern uint8_t jtag_out_buffer[256]; | ||
|
||
|
||
/** | ||
* Hook that performs hardware-specific initialization. | ||
|
@@ -41,49 +36,3 @@ void jtag_platform_deinit(void) | |
{ | ||
gpio_set_pin_direction(SIDEBAND_PHY_RESET, GPIO_DIRECTION_IN); | ||
} | ||
|
||
|
||
/** | ||
* Request that performs the actual JTAG scan event. | ||
* Arguments: | ||
* wValue: the number of bits to scan; total | ||
* wIndex: 1 if the given command should advance the FSM | ||
*/ | ||
bool handle_jtag_request_scan(uint8_t rhport, tusb_control_request_t const* request) | ||
{ | ||
// Our bulk method can only send whole bytes; so send as many bytes as we can | ||
// using the fast method; and then send the remainder using our slow method. | ||
size_t bytes_to_send_bulk = request->wValue / 8; | ||
size_t bits_to_send_slow = request->wValue % 8; | ||
|
||
// We can't handle 0-byte transfers; fail out. | ||
if (!bits_to_send_slow && !bytes_to_send_bulk) { | ||
return false; | ||
} | ||
|
||
// If this would scan more than we have buffer for, fail out. | ||
if (bytes_to_send_bulk > sizeof(jtag_out_buffer)) { | ||
return false; | ||
} | ||
|
||
// If we're going to advance state, always make sure the last bit is sent using the slow method, | ||
// so we can handle JTAG TAP state advancement on the last bit. If we don't have any bits to send slow, | ||
// send the last byte slow. | ||
if (!bits_to_send_slow && request->wIndex) { | ||
bytes_to_send_bulk--; | ||
bits_to_send_slow = 8; | ||
} | ||
|
||
// Switch to SPI mode, and send the bulk of the transfer using it. | ||
spi_configure_pinmux(SPI_FPGA_JTAG); | ||
spi_send(SPI_FPGA_JTAG, jtag_out_buffer, jtag_in_buffer, bytes_to_send_bulk); | ||
|
||
// Switch back to GPIO mode, and send the remainder using the slow method. | ||
spi_release_pinmux(SPI_FPGA_JTAG); | ||
if (bits_to_send_slow) { | ||
jtag_tap_shift(jtag_out_buffer + bytes_to_send_bulk, jtag_in_buffer + bytes_to_send_bulk, | ||
bits_to_send_slow, request->wIndex); | ||
} | ||
return tud_control_xfer(rhport, request, NULL, 0); | ||
} | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
/** | ||
* Code for basic FPGA interfacing. | ||
* | ||
* This file is part of LUNA. | ||
* | ||
* Copyright (c) 2020 Great Scott Gadgets <[email protected]> | ||
* Copyright (c) 2020-2023 Great Scott Gadgets <[email protected]> | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of these blocks? Could you add a comment?
Besides that, I think the
jtag_go_to_state(STATE_TEST_LOGIC_RESET)
is redundant, as this is done implicitly injtag_init()
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jtag_init()
doesjtag_set_current_state(STATE_TEST_LOGIC_RESET)
, notjtag_go_to_state(STATE_TEST_LOGIC_RESET)
, so it isn't redundant, but perhapsjtag_init()
really should calljtag_go_to_state(STATE_TEST_LOGIC_RESET)
. I've opened #29 to track that as a separate issue.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the comments you suggested.