|
40 | 40 | (1 << S_CMD_S_BUSTYPE) | \
|
41 | 41 | (1 << S_CMD_S_SPI_FREQ) | \
|
42 | 42 | (1 << S_CMD_S_PIN_STATE) | \
|
43 |
| - (1 << S_CMD_S_SPI_CS) \ |
| 43 | + (1 << S_CMD_S_SPI_CS) | \ |
| 44 | + (1 << S_CMD_S_SPI_MODE) \ |
44 | 45 | )
|
45 | 46 |
|
| 47 | +enum spi_mode { |
| 48 | + SPI_MODE_HALF_DUPLEX = 0, |
| 49 | + SPI_MODE_FULL_DUPLEX = 1, |
| 50 | + SPI_MODE_MAX = SPI_MODE_FULL_DUPLEX, |
| 51 | +}; |
| 52 | + |
| 53 | +enum spi_mode current_spi_mode = SPI_MODE_HALF_DUPLEX; |
| 54 | + |
46 | 55 | uint active_cs_pin = 0;
|
47 | 56 | #define NUM_CS_AVAILABLE 4 // Number of usable chip selects
|
48 | 57 | uint8_t cs_pins[NUM_CS_AVAILABLE] = { PIN_CS_0, PIN_CS_1, PIN_CS_2, PIN_CS_3 };
|
@@ -110,6 +119,33 @@ void spi_half_duplex(const pio_spi_inst_t *spi, uint32_t wlen, uint32_t rlen) {
|
110 | 119 | }
|
111 | 120 | }
|
112 | 121 |
|
| 122 | +void spi_full_duplex(const pio_spi_inst_t *spi, uint32_t wlen, uint32_t rlen) { |
| 123 | + uint8_t buffer[128]; |
| 124 | + |
| 125 | + putchar(S_ACK); |
| 126 | + |
| 127 | + while (wlen || rlen) { |
| 128 | + size_t len = MIN(rlen, wlen); |
| 129 | + size_t chunk_size = MIN(sizeof(buffer), len); |
| 130 | + memset(buffer, 0, chunk_size); |
| 131 | + |
| 132 | + if (wlen) { |
| 133 | + size_t chunk = MIN(wlen, chunk_size); |
| 134 | + fread(buffer, 1, chunk, stdin); |
| 135 | + wlen -= chunk; |
| 136 | + } |
| 137 | + |
| 138 | + pio_spi_write8_read8_blocking(spi, buffer, buffer, chunk_size); |
| 139 | + |
| 140 | + if (rlen) { |
| 141 | + size_t chunk = MIN(rlen, chunk_size); |
| 142 | + fwrite(buffer, 1, chunk, stdout); |
| 143 | + rlen -= chunk; |
| 144 | + } |
| 145 | + } |
| 146 | + fflush(stdout); |
| 147 | +} |
| 148 | + |
113 | 149 | void process(const pio_spi_inst_t *spi, int command) {
|
114 | 150 | static bool pin_state = false;
|
115 | 151 |
|
@@ -165,7 +201,16 @@ void process(const pio_spi_inst_t *spi, int command) {
|
165 | 201 | uint32_t rlen = getu24();
|
166 | 202 |
|
167 | 203 | cs_select(active_cs_pin);
|
168 |
| - spi_half_duplex(spi, wlen, rlen); |
| 204 | + switch (current_spi_mode) { |
| 205 | + case SPI_MODE_HALF_DUPLEX: |
| 206 | + spi_half_duplex(spi, wlen, rlen); |
| 207 | + break; |
| 208 | + case SPI_MODE_FULL_DUPLEX: |
| 209 | + spi_full_duplex(spi, wlen, rlen); |
| 210 | + break; |
| 211 | + default: |
| 212 | + break; |
| 213 | + } |
169 | 214 | cs_deselect(active_cs_pin);
|
170 | 215 | }
|
171 | 216 | break;
|
@@ -197,6 +242,17 @@ void process(const pio_spi_inst_t *spi, int command) {
|
197 | 242 | }
|
198 | 243 | break;
|
199 | 244 | }
|
| 245 | + case S_CMD_S_SPI_MODE: |
| 246 | + { |
| 247 | + uint8_t spi_mode = getchar(); |
| 248 | + if (spi_mode <= SPI_MODE_MAX) { |
| 249 | + current_spi_mode = spi_mode; |
| 250 | + putchar(S_ACK); |
| 251 | + } else { |
| 252 | + putchar(S_NAK); |
| 253 | + } |
| 254 | + break; |
| 255 | + } |
200 | 256 | default:
|
201 | 257 | putchar(S_NAK);
|
202 | 258 | }
|
|
0 commit comments