@@ -192,9 +192,9 @@ namespace pimoroni {
192
192
void APS6404::read (uint32_t addr, uint32_t * read_buf, uint32_t len_in_words) {
193
193
start_read (read_buf, len_in_words);
194
194
195
- uint32_t first_page_len = (PAGE_SIZE - (addr & (PAGE_SIZE - 1 ))) >> 2 ;
195
+ uint32_t first_page_len = (PAGE_SIZE - (addr & (PAGE_SIZE - 1 )));
196
196
197
- if (first_page_len >= len_in_words) {
197
+ if (first_page_len >= len_in_words << 2 ) {
198
198
pio_sm_put_blocking (pio, pio_sm, (len_in_words * 8 ) - 4 );
199
199
pio_sm_put_blocking (pio, pio_sm, 0xeb000000u | addr);
200
200
pio_sm_put_blocking (pio, pio_sm, pio_offset + sram_offset_do_read);
@@ -261,19 +261,33 @@ namespace pimoroni {
261
261
}
262
262
263
263
uint32_t * APS6404::add_read_to_cmd_buffer (uint32_t * cmd_buf, uint32_t addr, uint32_t len_in_words) {
264
- uint32_t len = (PAGE_SIZE - (addr & (PAGE_SIZE - 1 ))) >> 2 ;
264
+ int32_t len_remaining = len_in_words << 2 ;
265
+ uint32_t len = std::min ((PAGE_SIZE - (addr & (PAGE_SIZE - 1 ))), (uint32_t )len_remaining);
266
+ bool clear_isr = false ;
265
267
266
268
while (true ) {
267
- *cmd_buf++ = (len * 8 ) - 4 ;
269
+ if (len < 2 ) {
270
+ // This is guaranteed to leave at least one byte in the ISR,
271
+ // which we then clear with an additional command
272
+ len = 2 ;
273
+ clear_isr = true ;
274
+ }
275
+ *cmd_buf++ = (len * 2 ) - 4 ;
268
276
*cmd_buf++ = 0xeb000000u | addr;
269
277
*cmd_buf++ = pio_offset + sram_offset_do_read;
270
- len_in_words -= len;
271
- addr += len << 2 ;
278
+ len_remaining -= len;
279
+ addr += len;
272
280
273
- if (len_in_words = = 0 ) break ;
281
+ if (len_remaining < = 0 ) break ;
274
282
275
- len = len_in_words;
276
- if (len > (PAGE_SIZE >> 2 )) len = PAGE_SIZE >> 2 ;
283
+ len = len_remaining;
284
+ if (len > PAGE_SIZE) len = PAGE_SIZE;
285
+ }
286
+
287
+ if (clear_isr) {
288
+ *cmd_buf++ = 0 ;
289
+ *cmd_buf++ = 0xeb000000u | addr;
290
+ *cmd_buf++ = pio_offset + sram_offset_do_clear;
277
291
}
278
292
279
293
return cmd_buf;
0 commit comments