monome / aleph

open source sound computer
Other
79 stars 39 forks source link

restructure blackfin SPI processing #239

Open catfact opened 8 years ago

catfact commented 8 years ago

when blackfin receives SPI from avr32, it is processed in the SPI interrupt by reading directly from the rx register.

there's nothing really wrong with this, but we could probably arrange it so that all transfers are 16b or even 32b , and set up the blackfin SPI peripheral to use pingpong DMA and produce an interrupt only every 2 or 4 bytes. less interrupts would be nice.

alternately, we could switch the SPI mode to use larger trasnfers, but this would be a pain because during blackfin boot the transfers have to be 1B, and we'd have to reconfigure the avr32 peripheral to a different trasnfer size after booting. seems dangerous.

catfact commented 8 years ago

it might also be good to move processing out of the ISR altogether. i'm attempting to set it up so audio DMA is done on a per-block basis, the block is processed in the main loop, and the DMA interrupt only triggers a swapping of pointers. if this works out it might be worth going back to a FIFO model for control changes, where the SPI ISR just pushes changes to FIFO and the module executes control changes before/after audio block processing. see #33

electropourlaction commented 8 years ago

my brain will probably explode on this stuff but if there is anything I can do to help, just let me know!

catfact commented 8 years ago

audio block processing seems to be working basically OK. (branch block-process-test) so now is a good time to redesign SPI processing structure as well.

minimal effort might be:

[*] yes, it really does need to be a FIFO because order of param changes is often very significant. this also makes it hard to optimize by ignoring repeated changes to the same parameter. but maybe there is a clever way around that.

catfact commented 8 years ago

additionally, it would be great to reduce the number of SPI interrupts altogether. we can set up SPI DMA to only raise interrupts every N bytes, as is done in audio block processing.

problem is, the SPI protocol right now is defined per-byte, and different transactions have totally arbitrary byte lengths. for example, sending a param change takes 6 bytes: 1B command, 1B param selection, 4B data. what's worse, these transaction lengths are not actually defined anywhere but implicitly worked into the SPI master/slave state machines, in avr32_lib/src/bfin.c and bfin_llib/src/spi.c respectively.

i'd suggest reworking the SPI protocol so that all transactions are multiples of 4B, with dummy bytes as appropriate. there is little to be gained from minimizing bandwidth to the fullest, and much to be gained from e.g. reducing the number of interrupts per control change from 6, to 2. this would even allow increasing the SPI word size to 32b, which would help on the AVR32 side as well.