|
10 | 10 | */
|
11 | 11 |
|
12 | 12 | #include "pico/stdlib.h"
|
| 13 | +#include "pico/time.h" |
13 | 14 | #include "hardware/spi.h"
|
14 | 15 | #include "tusb.h"
|
15 | 16 | #include "serprog.h"
|
|
22 | 23 | #define SPI_MISO 4
|
23 | 24 | #define SPI_MOSI 3
|
24 | 25 | #define SPI_SCK 2
|
| 26 | +#define MAX_BUFFER_SIZE 4096 |
| 27 | +#define MAX_OPBUF_SIZE 4096 |
| 28 | + |
| 29 | +// Define a global operation buffer and a pointer to track the current position |
| 30 | +uint8_t opbuf[MAX_OPBUF_SIZE]; |
| 31 | +uint32_t opbuf_pos = 0; |
25 | 32 |
|
26 | 33 | static void enable_spi(uint baud)
|
27 | 34 | {
|
@@ -55,18 +62,16 @@ static void disable_spi()
|
55 | 62 | spi_deinit(SPI_IF);
|
56 | 63 | }
|
57 | 64 |
|
58 |
| -static inline void cs_select(uint cs_pin) |
59 |
| -{ |
60 |
| - asm volatile("nop \n nop \n nop"); // FIXME |
| 65 | +static inline void cs_select(uint cs_pin) { |
| 66 | + sleep_us(1); // 1 microsecond delay; adjust as needed |
61 | 67 | gpio_put(cs_pin, 0);
|
62 |
| - asm volatile("nop \n nop \n nop"); // FIXME |
| 68 | + sleep_us(1); // Additional delay after CS is pulled low |
63 | 69 | }
|
64 | 70 |
|
65 |
| -static inline void cs_deselect(uint cs_pin) |
66 |
| -{ |
67 |
| - asm volatile("nop \n nop \n nop"); // FIXME |
| 71 | +static inline void cs_deselect(uint cs_pin) { |
| 72 | + sleep_us(1); // Delay before pulling CS high |
68 | 73 | gpio_put(cs_pin, 1);
|
69 |
| - asm volatile("nop \n nop \n nop"); // FIXME |
| 74 | + sleep_us(1); // Additional delay after CS is pulled high |
70 | 75 | }
|
71 | 76 |
|
72 | 77 | static void wait_for_read(void)
|
@@ -232,6 +237,93 @@ static void command_loop(void)
|
232 | 237 | disable_spi();
|
233 | 238 | sendbyte_blocking(S_ACK);
|
234 | 239 | break;
|
| 240 | + case S_CMD_R_BYTE: |
| 241 | + { |
| 242 | + uint32_t addr; |
| 243 | + readbytes_blocking(&addr, 3); |
| 244 | + uint8_t data; |
| 245 | + |
| 246 | + cs_select(SPI_CS); |
| 247 | + spi_write_blocking(SPI_IF, (uint8_t*)&addr, 3); // Send address |
| 248 | + spi_read_blocking(SPI_IF, 0, &data, 1); // Read one byte |
| 249 | + cs_deselect(SPI_CS); |
| 250 | + |
| 251 | + sendbyte_blocking(S_ACK); |
| 252 | + sendbyte_blocking(data); |
| 253 | + break; |
| 254 | + } |
| 255 | + case S_CMD_R_NBYTES: |
| 256 | + { |
| 257 | + uint32_t addr, len; |
| 258 | + readbytes_blocking(&addr, 3); |
| 259 | + readbytes_blocking(&len, 3); |
| 260 | + |
| 261 | + uint8_t buffer[MAX_BUFFER_SIZE]; // Define MAX_BUFFER_SIZE based on your hardware capability |
| 262 | + |
| 263 | + cs_select(SPI_CS); |
| 264 | + spi_write_blocking(SPI_IF, (uint8_t*)&addr, 3); // Send address |
| 265 | + |
| 266 | + while (len > 0) { |
| 267 | + uint32_t chunk_size = (len < MAX_BUFFER_SIZE) ? len : MAX_BUFFER_SIZE; |
| 268 | + spi_read_blocking(SPI_IF, 0, buffer, chunk_size); |
| 269 | + sendbytes_blocking(buffer, chunk_size); |
| 270 | + len -= chunk_size; |
| 271 | + } |
| 272 | + |
| 273 | + cs_deselect(SPI_CS); |
| 274 | + |
| 275 | + sendbyte_blocking(S_ACK); |
| 276 | + break; |
| 277 | + } |
| 278 | + case S_CMD_O_WRITEB: |
| 279 | + { |
| 280 | + if (opbuf_pos + 5 > MAX_OPBUF_SIZE) { |
| 281 | + sendbyte_blocking(S_NAK); |
| 282 | + break; |
| 283 | + } |
| 284 | + |
| 285 | + uint32_t addr; |
| 286 | + uint8_t byte; |
| 287 | + readbytes_blocking(&addr, 3); |
| 288 | + byte = readbyte_blocking(); |
| 289 | + |
| 290 | + // Store in operation buffer (assuming format: 1-byte command, 3-byte address, 1-byte data) |
| 291 | + opbuf[opbuf_pos++] = S_CMD_O_WRITEB; |
| 292 | + memcpy(&opbuf[opbuf_pos], &addr, 3); |
| 293 | + opbuf_pos += 3; |
| 294 | + opbuf[opbuf_pos++] = byte; |
| 295 | + |
| 296 | + sendbyte_blocking(S_ACK); |
| 297 | + break; |
| 298 | + } |
| 299 | + case S_CMD_O_WRITEB: |
| 300 | + { |
| 301 | + if (opbuf_pos + 5 > MAX_OPBUF_SIZE) { |
| 302 | + sendbyte_blocking(S_NAK); |
| 303 | + break; |
| 304 | + } |
| 305 | + |
| 306 | + uint32_t addr; |
| 307 | + uint8_t byte; |
| 308 | + readbytes_blocking(&addr, 3); |
| 309 | + byte = readbyte_blocking(); |
| 310 | + |
| 311 | + // Store in operation buffer (assuming format: 1-byte command, 3-byte address, 1-byte data) |
| 312 | + opbuf[opbuf_pos++] = S_CMD_O_WRITEB; |
| 313 | + memcpy(&opbuf[opbuf_pos], &addr, 3); |
| 314 | + opbuf_pos += 3; |
| 315 | + opbuf[opbuf_pos++] = byte; |
| 316 | + |
| 317 | + sendbyte_blocking(S_ACK); |
| 318 | + break; |
| 319 | + } |
| 320 | + case S_CMD_O_INIT: |
| 321 | + { |
| 322 | + opbuf_pos = 0; // Reset the operation buffer position |
| 323 | + memset(opbuf, 0, MAX_OPBUF_SIZE); // Clear the buffer (optional) |
| 324 | + sendbyte_blocking(S_ACK); |
| 325 | + break; |
| 326 | + } |
235 | 327 | default:
|
236 | 328 | sendbyte_blocking(S_NAK);
|
237 | 329 | break;
|
|
0 commit comments