12 #include <xcore/port.h>
13 #include <xcore/clock.h>
77 #define QSPI_IO_BYTE_TO_MOSI(x) ( \
78 ((((x) >> 0) & 1) | 0xE) << (0 * 4) | \
79 ((((x) >> 1) & 1) | 0xE) << (1 * 4) | \
80 ((((x) >> 2) & 1) | 0xE) << (2 * 4) | \
81 ((((x) >> 3) & 1) | 0xE) << (3 * 4) | \
82 ((((x) >> 4) & 1) | 0xE) << (4 * 4) | \
83 ((((x) >> 5) & 1) | 0xE) << (5 * 4) | \
84 ((((x) >> 6) & 1) | 0xE) << (6 * 4) | \
85 ((((x) >> 7) & 1) | 0xE) << (7 * 4) )
221 size_t transaction_length;
222 uint32_t transaction_start;
223 uint32_t sample_delay;
224 uint32_t sample_edge;
225 uint32_t sio_pad_delay;
240 __attribute__((always_inline))
243 uint32_t ones = 0xFFFFFFFF;
270 __attribute__((always_inline))
273 uint32_t unzipped = 0;
279 :
"+r"(unzipped),
"+r"(x)
293 __attribute__((always_inline))
300 "{and %0,%0,%2 ; and %1,%0,%3}\n"
301 "{shl %0,%0,4 ; shr %1,%1,4}\n"
302 :
"+r"(word),
"=r"(tmp)
303 :
"r"(0x0F0F0F0F),
"r"(0xF0F0F0F0)
310 #define QSPI_IO_SETC_PAD_DELAY(n) (0x7007 | ((n) << 3))
313 #define QSPI_IO_RESOURCE_SETCI(res, c) asm volatile( "setc res[%0], %1" :: "r" (res), "n" (c))
314 #define QSPI_IO_RESOURCE_SETC(res, r) asm volatile( "setc res[%0], %1" :: "r" (res), "r" (r))
315 #define QSPI_IO_SETSR(c) asm volatile("setsr %0" : : "n"(c));
316 #define QSPI_IO_CLRSR(c) asm volatile("clrsr %0" : : "n"(c));
350 __attribute__((always_inline))
357 QSPI_IO_SETSR(XS1_SR_QUEUE_MASK | XS1_SR_FAST_MASK);
359 ctx->transaction_length = len;
361 port_set_master(ctx->sio_port);
362 port_set_no_ready(ctx->sio_port);
365 clock_set_divide(ctx->clock_block, ctx->spi_read_clk_divisor);
366 ctx->sample_delay = ctx->spi_read_sclk_sample_delay;
367 ctx->sample_edge = ctx->spi_read_sclk_sample_edge;
368 ctx->sio_pad_delay = QSPI_IO_SETC_PAD_DELAY(ctx->spi_read_sio_pad_delay);
369 ctx->sio_drive = XS1_SETC_DRIVE_PULL_UP;
371 clock_set_divide(ctx->clock_block, ctx->full_speed_clk_divisor);
372 ctx->sample_delay = ctx->full_speed_sclk_sample_delay;
373 ctx->sample_edge = ctx->full_speed_sclk_sample_edge;
374 ctx->sio_pad_delay = QSPI_IO_SETC_PAD_DELAY(ctx->full_speed_sio_pad_delay);
375 ctx->sio_drive = XS1_SETC_DRIVE_DRIVE;
378 first_word = byterev(first_word);
382 QSPI_IO_RESOURCE_SETCI(ctx->sio_port, XS1_SETC_DRIVE_DRIVE);
384 port_out(ctx->sio_port, first_word);
385 port_out(ctx->cs_port, 1);
386 clock_start(ctx->clock_block);
405 __attribute__((always_inline))
411 const uint32_t *data_words = (
const uint32_t *) data;
412 size_t word_len = len /
sizeof(uint32_t);
420 for (i = 0; i < word_len; i++) {
421 word = data_words[i];
425 port_out(ctx->sio_port, word);
428 len &=
sizeof(uint32_t) - 1;
431 word = data_words[i];
437 port_set_shift_count(ctx->sio_port, len);
438 port_out(ctx->sio_port, word);
456 __attribute__((always_inline))
459 const uint32_t *data,
468 for (
int i = 0; i < len; i++) {
469 word = byterev(data[i]);
473 port_out(ctx->sio_port, word);
490 __attribute__((always_inline))
502 for (
int i = 0; i < len; i++) {
508 port_out(ctx->sio_port, word);
528 __attribute__((always_inline))
541 if (ctx->transaction_length != 0) {
543 port_sync(ctx->cs_port);
544 cs_start = port_get_trigger_time(ctx->cs_port);
545 port_out_at_time(ctx->cs_port, cs_start + ctx->transaction_length, 0);
546 ctx->transaction_length = 0;
547 ctx->transaction_start = cs_start + ctx->sample_delay;
550 if (ctx->sample_delay) {
558 QSPI_IO_RESOURCE_SETCI(ctx->cs_port, QSPI_IO_SETC_PAD_DELAY(5));
583 "n"(XS1_SETC_INUSE_ON),
584 "n"(XS1_SETC_SDELAY_SDELAY),
585 "n"(XS1_SETC_BUF_BUFFERS)
597 "n"(XS1_SETC_INUSE_ON),
598 "n"(XS1_SETC_BUF_BUFFERS)
602 QSPI_IO_RESOURCE_SETC(ctx->sio_port, ctx->sio_pad_delay);
603 QSPI_IO_RESOURCE_SETC(ctx->sio_port, ctx->sio_drive);
604 port_set_transfer_width(ctx->sio_port, 32);
605 port_set_ready_strobed(ctx->sio_port);
606 port_set_slave(ctx->sio_port);
638 __attribute__((always_inline))
645 uint32_t *data_words = (uint32_t *) data;
646 size_t word_len = len /
sizeof(uint32_t);
650 port_set_trigger_time(ctx->sio_port, ctx->transaction_start + start_time);
656 for (i = 0; i < word_len; i++) {
657 word = port_in(ctx->sio_port);
661 data_words[i] = word;
679 len &=
sizeof(uint32_t) - 1;
693 port_set_shift_count(ctx->sio_port, len * 8);
696 word = port_in(ctx->sio_port);
697 word >>= 8 * (4 - len);
699 data = (uint8_t *) &data_words[i];
704 for (i = 0; i < len; i++) {
705 *data++ = word & 0xFF;
728 __attribute__((always_inline))
737 port_set_trigger_time(ctx->sio_port, ctx->transaction_start + start_time);
743 for (
int i = 0; i < len; i++) {
744 word = port_in(ctx->sio_port);
748 data[i] = byterev(word);
768 __attribute__((always_inline))
777 port_set_trigger_time(ctx->sio_port, ctx->transaction_start + start_time);
783 for (
int i = 0; i < len; i++) {
808 __attribute__((always_inline))
816 port_set_trigger_time(ctx->sio_port, ctx->transaction_start + start_time);
825 if ((word & mask) == val) {
829 port_clear_buffer(ctx->cs_port);
830 port_out_at_time(ctx->cs_port, port_get_trigger_time(ctx->cs_port) + 8, 0);
841 __attribute__((always_inline))
852 if (ctx->transaction_length != 0) {
854 port_sync(ctx->cs_port);
855 cs_start = port_get_trigger_time(ctx->cs_port);
856 port_out_at_time(ctx->cs_port, cs_start + ctx->transaction_length, 0);
859 port_sync(ctx->cs_port);
860 clock_stop(ctx->clock_block);
866 QSPI_IO_RESOURCE_SETCI(ctx->sio_port, QSPI_IO_SETC_PAD_DELAY(0));
867 QSPI_IO_RESOURCE_SETCI(ctx->cs_port, QSPI_IO_SETC_PAD_DELAY(0));
868 port_set_sample_falling_edge(ctx->sio_port);
875 QSPI_IO_RESOURCE_SETCI(ctx->sio_port, XS1_SETC_DRIVE_PULL_UP);
878 QSPI_IO_CLRSR(XS1_SR_QUEUE_MASK | XS1_SR_FAST_MASK);
void qspi_io_init(const qspi_io_ctx_t *ctx, qspi_io_source_clock_t source_clock)
void qspi_io_end_transaction(const qspi_io_ctx_t *ctx)
Definition: qspi_io.h:842
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)
Definition: qspi_io.h:406
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)
Definition: qspi_io.h:457
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)
Definition: qspi_io.h:769
qspi_io_transfer_mode_t
Definition: qspi_io.h:41
void qspi_io_miso_poll(const qspi_io_ctx_t *ctx, const uint8_t mask, const uint8_t val, uint32_t start_time)
Definition: qspi_io.h:809
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)
Definition: qspi_io.h:491
uint32_t qspi_io_nibble_swap(uint32_t word)
Definition: qspi_io.h:294
void qspi_io_start_transaction(qspi_io_ctx_t *ctx, uint32_t first_word, size_t len, qspi_io_transaction_type_t transaction_type)
Definition: qspi_io.h:351
qspi_io_source_clock_t
Definition: qspi_io.h:33
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)
Definition: qspi_io.h:639
qspi_io_transaction_type_t
Definition: qspi_io.h:51
uint32_t qspi_io_byte_to_mosi(uint32_t x)
Definition: qspi_io.h:241
qspi_io_sample_edge_t
Definition: qspi_io.h:25
uint32_t qspi_io_miso_to_byte(uint32_t x)
Definition: qspi_io.h:271
void qspi_io_sio_direction_input(qspi_io_ctx_t *ctx)
Definition: qspi_io.h:529
void qspi_io_deinit(const qspi_io_ctx_t *ctx)
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)
Definition: qspi_io.h:729
@ qspi_io_transfer_normal
Definition: qspi_io.h:42
@ qspi_io_transfer_nibble_swap
Definition: qspi_io.h:43
@ qspi_io_source_clock_ref
Definition: qspi_io.h:34
@ qspi_io_source_clock_xcore
Definition: qspi_io.h:35
@ qspi_io_full_speed
Definition: qspi_io.h:52
@ qspi_io_spi_read
Definition: qspi_io.h:53
@ qspi_io_sample_edge_falling
Definition: qspi_io.h:27
@ qspi_io_sample_edge_rising
Definition: qspi_io.h:26
int spi_read_clk_divisor
Definition: qspi_io.h:156
qspi_io_sample_edge_t full_speed_sclk_sample_edge
Definition: qspi_io.h:188
port_t sio_port
Definition: qspi_io.h:124
uint32_t full_speed_sio_pad_delay
Definition: qspi_io.h:208
qspi_io_sample_edge_t spi_read_sclk_sample_edge
Definition: qspi_io.h:198
port_t sclk_port
Definition: qspi_io.h:116
port_t cs_port
Definition: qspi_io.h:108
uint32_t spi_read_sclk_sample_delay
Definition: qspi_io.h:178
int full_speed_clk_divisor
Definition: qspi_io.h:137
xclock_t clock_block
Definition: qspi_io.h:100
uint32_t spi_read_sio_pad_delay
Definition: qspi_io.h:218
uint32_t full_speed_sclk_sample_delay
Definition: qspi_io.h:167