:o Got 4 different 1BPP OLED displays from https://www.buydisplay.com/ and must admit I like these displays.
I found their sample code very good and their startup code usually worked first time once I ironed my bugs out.
I've got these to work well with the Mega2650 and the Arduino Due in both 8 bit parallel and software SPI.
The software SPI speed is acceptable depending on what you're doing as I maintain an off-screen buffer and refresh either the entire display or partial.
128*64 @1BPP was refreshing ~ 60 times a second off memory.
Parallel is definitely a pain in the butt to wire up however the speedup is ~ 4x and not the "expected" 8x as there is a bit of fiddling overhead to bitshift and prepare each byte before sending however if speed is critical then it's a good boost (especially on the Mega that has easy/fast 8-bit port writes and no DMA option)
I finally lashed out and allowed for DMA on the Due... and well 156uS to refresh the entire screen 128*64 @1BPP was the result.
I'm thinking about getting a 128*128 1351 type OLED now that supports color and hooking it up with SPI via DMA as the speed boost should support near instant refresh rates.
Now, I know it would be better for my code to init the DMA transfer then ... do something else... then check if the transfer is done. However I kept it simple as possible for starters and may allow for optional waiting later.
:o I struck 1 minor problem with the DMA code
ATM the transfer sends from the start of the buffer to the end and increments the source address by 1.
However I need the option to do the reverse which... failed miserably after trying several approaches. Changing the source address works fine as does the count, it seems to not decrement the source address when I use DMAC_CTRLB_SRC_INCR_DECREMENTING. I tested and used DMAC_CTRLB_SRC_INCR_FIXED which seemed to change it.
Anyone else have any suggestions? Maybe this is not possible? For my MAX7219 code I need to send the buffer in reverse order.
static void due_dma_spiDmaTX(const uint8_t *src, uint16_t count, bool reverse)
{
static uint8_t ff = 0xff;
uint32_t src_incr;
if (!src)
{
src = &ff;
src_incr = DMAC_CTRLB_SRC_INCR_FIXED;
}
else if (reverse)
{
source += (count - 1);
src_incr = DMAC_CTRLB_SRC_INCR_DECREMENTING;
}
else
{
src_incr = DMAC_CTRLB_SRC_INCR_INCREMENTING;
}
due_dma_dmac_channel_disable(DUE_DMA_SPI_DMAC_TX_CH);
DMAC->DMAC_CH_NUM[DUE_DMA_SPI_DMAC_TX_CH].DMAC_DSCR = 0;
DMAC->DMAC_CH_NUM[DUE_DMA_SPI_DMAC_TX_CH].DMAC_SADDR = (uint32_t)src;
DMAC->DMAC_CH_NUM[DUE_DMA_SPI_DMAC_TX_CH].DMAC_DADDR = (uint32_t)&SPI0->SPI_TDR;
DMAC->DMAC_CH_NUM[DUE_DMA_SPI_DMAC_TX_CH].DMAC_CTRLA = count | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_BYTE;
DMAC->DMAC_CH_NUM[DUE_DMA_SPI_DMAC_TX_CH].DMAC_CTRLB = DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | src_incr | DMAC_CTRLB_DST_INCR_FIXED;
DMAC->DMAC_CH_NUM[DUE_DMA_SPI_DMAC_TX_CH].DMAC_CFG = DMAC_CFG_DST_PER(DUE_DMA_SPI_TX_IDX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG;
due_dma_dmac_channel_enable(DUE_DMA_SPI_DMAC_TX_CH);
Shifting the src address had an effect however it seems the src_incr had no effect.