|
#define | QSPI_IO_BYTE_TO_MOSI(x) |
|
#define | QSPI_IO_SETC_PAD_DELAY(n) (0x7007 | ((n) << 3)) |
|
#define | QSPI_IO_RESOURCE_SETCI(res, c) asm volatile( "setc res[%0], %1" :: "r" (res), "n" (c)) |
|
#define | QSPI_IO_RESOURCE_SETC(res, r) asm volatile( "setc res[%0], %1" :: "r" (res), "r" (r)) |
|
#define | QSPI_IO_SETSR(c) asm volatile("setsr %0" : : "n"(c)); |
|
#define | QSPI_IO_CLRSR(c) asm volatile("clrsr %0" : : "n"(c)); |
|
|
uint32_t | qspi_io_byte_to_mosi (uint32_t x) |
|
uint32_t | qspi_io_miso_to_byte (uint32_t x) |
|
uint32_t | qspi_io_nibble_swap (uint32_t word) |
|
void | qspi_io_start_transaction (qspi_io_ctx_t *ctx, uint32_t first_word, size_t len, qspi_io_transaction_type_t transaction_type) |
|
void | qspi_io_bytes_out (const qspi_io_ctx_t *ctx, const qspi_io_transfer_mode_t transfer_mode, const uint8_t *data, size_t len) |
|
void | qspi_io_words_out (const qspi_io_ctx_t *ctx, const qspi_io_transfer_mode_t transfer_mode, const uint32_t *data, size_t len) |
|
void | qspi_io_mosi_out (const qspi_io_ctx_t *ctx, const qspi_io_transfer_mode_t transfer_mode, const uint8_t *data, size_t len) |
|
void | qspi_io_sio_direction_input (qspi_io_ctx_t *ctx) |
|
void | qspi_io_bytes_in (const qspi_io_ctx_t *ctx, const qspi_io_transfer_mode_t transfer_mode, uint8_t *data, uint32_t start_time, size_t len) |
|
void | qspi_io_words_in (const qspi_io_ctx_t *ctx, const qspi_io_transfer_mode_t transfer_mode, uint32_t *data, uint32_t start_time, size_t len) |
|
void | qspi_io_miso_in (const qspi_io_ctx_t *ctx, const qspi_io_transfer_mode_t transfer_mode, uint8_t *data, uint32_t start_time, size_t len) |
|
void | qspi_io_miso_poll (const qspi_io_ctx_t *ctx, const uint8_t mask, const uint8_t val, uint32_t start_time) |
|
void | qspi_io_end_transaction (const qspi_io_ctx_t *ctx) |
|
void | qspi_io_deinit (const qspi_io_ctx_t *ctx) |
|
void | qspi_io_init (const qspi_io_ctx_t *ctx, qspi_io_source_clock_t source_clock) |
|
The public API for using HIL QSPI I/O.
◆ QSPI_IO_BYTE_TO_MOSI
#define QSPI_IO_BYTE_TO_MOSI |
( |
|
x | ) |
|
Value:( \
((((x) >> 0) & 1) | 0xE) << (0 * 4) | \
((((x) >> 1) & 1) | 0xE) << (1 * 4) | \
((((x) >> 2) & 1) | 0xE) << (2 * 4) | \
((((x) >> 3) & 1) | 0xE) << (3 * 4) | \
((((x) >> 4) & 1) | 0xE) << (4 * 4) | \
((((x) >> 5) & 1) | 0xE) << (5 * 4) | \
((((x) >> 6) & 1) | 0xE) << (6 * 4) | \
((((x) >> 7) & 1) | 0xE) << (7 * 4) )
This macro may be used when sending out bytes that are only transmitted over the single data line MOSI (SIO0). The returned word should be transmitted using either qspi_io_start_transaction() or qspi_io_words_out(). Typically the byte argument to this macro is a constant known at compile time, like commands, as the compiler can perform this computation at compile time. For arrays of data, it may be more appropriate to use qspi_io_mosi_out() which more efficiently computes this transformation at run time on the fly.
When writing a single byte out in SPI mode, the byte needs to be transformed such that each nibble in the word that is sent out on SIO contains one bit from the byte in bit 0 (which corresponds to SIO0, or MOSI).
- Parameters
-
x | The byte to send out to MOSI. |
◆ qspi_io_sample_edge_t
Enum type used to set which SCLK edge SIO is sampled on.
Enumerator |
---|
qspi_io_sample_edge_rising | Sample SIO on the rising edge
|
qspi_io_sample_edge_falling | Sample SIO on the falling edge
|
◆ qspi_io_source_clock_t
Enum type used to set which of the two clock sources SCLK is derived from.
Enumerator |
---|
qspi_io_source_clock_ref | SCLK is derived from the 100 MHz reference clock
|
qspi_io_source_clock_xcore | SCLK is derived from the core clock
|
◆ qspi_io_transaction_type_t
Enum type used to specify whether the next transaction will be a full speed QSPI transaction with dummy cycles, or a lower speed SPI read transaction without dummy cycles.
Enumerator |
---|
qspi_io_full_speed | The transaction will be full speed with dummy cycles
|
qspi_io_spi_read | The transaction will be low speed without dummy cycles
|
◆ qspi_io_transfer_mode_t
Enum type used to specify whether or not nibbles should be swapped during transfers.
Enumerator |
---|
qspi_io_transfer_normal | Do not swap nibbles
|
qspi_io_transfer_nibble_swap | Swap nibbles
|
◆ qspi_io_byte_to_mosi()
uint32_t qspi_io_byte_to_mosi |
( |
uint32_t |
x | ) |
|
|
inline |
This function should only be called internally by qspi_io_mosi_out(). It performs the same transformation as QSPI_IO_BYTE_TO_MOSI() but also integrates the byte reversal and nibble swap performed by qspi_io_words_out().
- Parameters
-
x | The byte to send out to MOSI. |
- Returns
- the word to output to SIO.
◆ qspi_io_bytes_in()
Inputs a byte array from the QSPI interface. The byte array must start on a 4-byte boundary. qspi_io_sio_direction_input() must have been called previously. This call must be made in time such that its IN instruction executes before start_time
.
- Note
- The number of bytes input may be any number. However, if it is NOT a multiple of four, then this likely will need to be the last call in the transaction. This is because the shorter length of the last input chunk plus the extra overhead required to deal with the sub-word accesses will not allow subsequent I/O to keep up unless the SCLK frequency is significantly slower than the core clock.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
transfer_mode | Can be either qspi_io_transfer_normal or qspi_io_transfer_nibble_swap. When qspi_io_transfer_nibble_swap, each byte transferred in is nibble swapped. Because the data is inherently received nibble swapped over the port, setting this to qspi_io_transfer_nibble_swap actually removes a nibble swap operation. |
data | Pointer to the byte array to save the received data to. This MUST begin on a 4-byte boundary. |
start_time | The port time, relative to the beginning of the transfer, at which to input the first group of four bytes. This must line up with the last nibble of the fourth byte. If len is less than four, then it must line up with the last nibble of the last byte. |
len | The number of bytes to input. |
◆ qspi_io_bytes_out()
Outputs a byte array to the QSPI interface. The byte array must start on a 4-byte boundary. This call must be made in time such that its OUT instruction executes within 8 SCLK cycles of the previous OUT instruction.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
transfer_mode | Can be either qspi_io_transfer_normal or qspi_io_transfer_nibble_swap. When qspi_io_transfer_nibble_swap, each byte transferred out is nibble swapped. Because the data is inherently sent out nibble swapped over the port, setting this to qspi_io_transfer_nibble_swap actually removes a nibble swap operation. |
data | Pointer to the byte array to output. This MUST begin on a 4-byte boundary. |
len | The number of bytes in data to output. |
◆ qspi_io_deinit()
This disables and frees the clock block and all the ports associated with the QSPI I/O interface.
- Parameters
-
ctx | Pointer to the QSPI I/O context. This should have been previously initialized with qspi_io_init(). |
◆ qspi_io_end_transaction()
This sets up CS to deassert at the end of the transaction if it has not already, waits for the current QSPI transaction to complete, and then stops SCLK.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
◆ qspi_io_init()
This sets up the clock block and all the ports associated with the QSPI I/O interface. This must be called first prior to any other QSPI I/O function.
- Parameters
-
ctx | Pointer to the QSPI I/O context. This must be initialized with the clock block and ports to use. |
source_clock | Set to qspi_io_source_clock_ref to use the 100 MHz reference clock as the source for SCLK. Set to qspi_io_source_clock_xcore to use the xcore clock. |
◆ qspi_io_miso_in()
Inputs a byte array from the QSPI interface over the single data line MISO (SIO1). qspi_io_sio_direction_input() must have been called previously. This call must be made in time such that its IN instruction executes before start_time
.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
transfer_mode | Can be either qspi_io_transfer_normal or qspi_io_transfer_nibble_swap. When qspi_io_transfer_nibble_swap, each byte transferred in is nibble swapped. |
data | Pointer to the byte array to save the received data to. |
start_time | The time, relative to the beginning of the transfer, at which to input the first byte. This must line up with the last bit of the first byte. |
len | The number of words to input. |
◆ qspi_io_miso_poll()
void qspi_io_miso_poll |
( |
const qspi_io_ctx_t * |
ctx, |
|
|
const uint8_t |
mask, |
|
|
const uint8_t |
val, |
|
|
uint32_t |
start_time |
|
) |
| |
|
inline |
Polls the SPI interface by repeatedly receiving a byte over MISO until a specified condition is met. For each time the received byte does not meet the condition, the deassertion of CS is extended by eight SCLK cycles. qspi_io_sio_direction_input() must have been called previously. This call must be made in time such that its IN instruction executes before start_time
.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
mask | The bitmask to apply to the received byte before comparing it to val ; |
val | The value that the received byte, masked with mask , must match before returning. |
start_time | The time, relative to the beginning of the transfer, at which to input the first byte. This must line up with the last bit of the first byte. |
◆ qspi_io_miso_to_byte()
uint32_t qspi_io_miso_to_byte |
( |
uint32_t |
x | ) |
|
|
inline |
This function should only be called internally by qspi_io_miso_in().
When reading in a single byte in SPI mode, the word that is received on SIO needs to be transformed such that bit one from each nibble (which corresponds to SIO1, or MISO) is shifted into the correct bit position.
- Parameters
-
x | The word received on SIO. |
- Returns
- the byte received on MISO.
◆ qspi_io_mosi_out()
Outputs a byte array to the QSPI interface over the single data line MOSI (SIO0). This call must be made in time such that its OUT instruction executes within 8 SCLK cycles of the previous OUT instruction.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
transfer_mode | Can be either qspi_io_transfer_normal or qspi_io_transfer_nibble_swap. When qspi_io_transfer_nibble_swap, each byte transferred out is nibble swapped. |
data | Pointer to the byte array to output. |
len | The number of words in data to output. |
◆ qspi_io_nibble_swap()
uint32_t qspi_io_nibble_swap |
( |
uint32_t |
word | ) |
|
|
inline |
This function swaps the nibbles in each of the four bytes of word
.
- Parameters
-
word | The word to nibble swap. |
- Returns
- the nibble swapped word.
◆ qspi_io_sio_direction_input()
This must be called to change the direction of SIO from output to input before calling either qspi_io_bytes_in() or qspi_io_words_in(). This call must be made in time such that the call to port_set_buffered() completes before the sample edge of SCLK shifts in the first nibble of the next data word to be read. This also will setup CS to deassert at the end of the transaction while waiting for the previous output to complete.
- Note
- This is probably the most fragile function. Ensure that the port direction is turned around on time, and that the subsequent read IN instruction executes on time, by inspecting a VCD trace with both ports and instructions.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
◆ qspi_io_start_transaction()
Begins a new QSPI I/O transaction by starting the clock, asserting CS, and sending out the first word which is typically a command.
- Note
- If more words or bytes need to be sent or received as part of this transaction, then the appropriate functions will need to be called immediately following this one. For example, qspi_io_bytes_out() then qspi_io_sio_direction_input() then qspi_io_bytes_in(). The "out" or "in" instruction in each must be executed within eight SCLK cycles of the preceding one, including the OUT instruction in qspi_io_start_transaction(). Some analysis may be necessary depending on the frequency of SCLK. These functions are all marked as inline to help keep them closer together by removing the overhead associated with function calls and to allow better optimization.
-
It is likely not possible to follow an input with an output within a single transaction unless the frequency of SCLK is sufficiently slow. Fortunately in practice this rarely, if ever, required.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
first_word | The first word to output. |
len | The total number of clock cycles in the transaction. CS will at some point during the transaction be setup to deassert automatically after this number of cycles. |
transaction_type | Set to qspi_io_spi_read if the transaction will be a SPI read with no dummy cycles. This may run at a slower clock frequency in order to turn around SIO from output to input in time. Otherwise set to qspi_io_full_speed. |
◆ qspi_io_words_in()
Inputs a word array from the QSPI interface. qspi_io_sio_direction_input() must have been called previously. This call must be made in time such that its IN instruction executes before start_time
.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
transfer_mode | Can be either qspi_io_transfer_normal or qspi_io_transfer_nibble_swap. When qspi_io_transfer_nibble_swap, each byte transferred in is nibble swapped. Because the data is inherently received nibble swapped over the port, setting this to qspi_io_transfer_nibble_swap actually removes a nibble swap operation. |
data | Pointer to the word array to save the received data to. |
start_time | The time, relative to the beginning of the transfer, at which to input the first word. This must line up with the last nibble of the first word. |
len | The number of words to input. |
◆ qspi_io_words_out()
Outputs a word array to the QSPI interface. This call must be made in time such that its OUT instruction executes within 8 SCLK cycles of the previous OUT instruction.
- Parameters
-
ctx | Pointer to the QSPI I/O context. |
transfer_mode | Can be either qspi_io_transfer_normal or qspi_io_transfer_nibble_swap. When qspi_io_transfer_nibble_swap, each byte transferred out is nibble swapped. Because the data is inherently sent out nibble swapped over the port, setting this to qspi_io_transfer_nibble_swap actually removes a nibble swap operation. |
data | Pointer to the word array to output. |
len | The number of words in data to output. |