Building some sensor systems using this fairly new controller family. So far it's been very good for brute force sensor processing. Working out all of the details with a dev board but have all of the parts for my own PCB.
https://ww1.microchip.com/downloads...K1216GC41064-Family-Data-Sheet-DS70005592.pdf



Testing some DMA routines (leaving the processor free for single, double and fixed point number crunching) with a simple GLCD connected to the board @25MHz SCK on SPI1. SPI2 dedicated pins run at 50MHz.

Screen updates from graphic memory.

DMA state machine sending page commands and display data for that page.


PIC32AK DIMM in a dsPIC33A dev board for testing.
The machine hardware (DMA here with SRAM) is much like the MIPS PIC32 controllers but is simplified (no need for MMU or advanced OS capabilities) for easier coding for the expected types of programs. I can port most of the PIC32MK C code from other projects quickly.
https://ww1.microchip.com/downloads...K1216GC41064-Family-Data-Sheet-DS70005592.pdf



Testing some DMA routines (leaving the processor free for single, double and fixed point number crunching) with a simple GLCD connected to the board @25MHz SCK on SPI1. SPI2 dedicated pins run at 50MHz.

Screen updates from graphic memory.

DMA state machine sending page commands and display data for that page.


PIC32AK DIMM in a dsPIC33A dev board for testing.
The machine hardware (DMA here with SRAM) is much like the MIPS PIC32 controllers but is simplified (no need for MMU or advanced OS capabilities) for easier coding for the expected types of programs. I can port most of the PIC32MK C code from other projects quickly.
C:
int main(void)
{
/* Initialize all modules */
SYS_Initialize(NULL);
TMR1_CallbackRegister(timer_ms_tick, 0);
TMR1_InterruptEnable();
TMR1_Start(); // software timers counter
init_lcd_drv(D_INIT);
OledClearBuffer();
wait_lcd_done();
snprintf(buffer, 255, "Testing PIC32AK ");
eaDogM_WriteStringAtPos(15, 0, buffer);
OledUpdate();
StartTimer(TMR_TEST, 2);
while (true) {
static uint32_t loops=0;
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks();
RLED_Toggle();
if (TimerDone(TMR_TEST)) {
snprintf(buffer, 255, "Running %u ",loops++);
eaDogM_WriteStringAtPos(1, 0, buffer);
OledUpdate();
StartTimer(TMR_TEST, 2);
}
}
/* Execution should not come here during normal operation */
return( EXIT_FAILURE);
}
C:
void OledInit(void)
{
/* Init the memory variables used to control access to the
** display.
*/
OledDvrInit();
/*
* init DMA
*/
#ifdef USE_DMA
#ifdef DMA_STATE_M
DMA_ChannelCallbackRegister(DMA_CHANNEL_0, SPI1DmaChannelHandler_State, 0); // end of LCD buffer transfer interrupt function
#endif
DMA_ChannelCallbackRegister(DMA_CHANNEL_1, CBDmaChannelHandler, 0); // end of buffer clear transfer interrupt function
#endif
/* Clear the display.
*/
OledClear();
}
/*
* start a GLCD update: Called in user code with contextHandle set to DMA_MAGIC for a background screen update,
* during background transfers this function is used as the callback for DMA transfer complete events to
* sequence commands and data to the GLCD via the SPI port using the dstate ENUM variable
* dstate is set to 'D_idle' when the complete set of transfers is done.
*/
void SPI1DmaChannelHandler_State(DMA_TRANSFER_EVENT event, uintptr_t contextHandle)
{
static int32_t ipag = 0; // buffer page number
static uint8_t* pb; // buffer page address
// back to mainline code, GLCD updates in background using DMA and interrupts
LCD_UNSELECT();
if (contextHandle == DMA_MAGIC) { // re-init state machine for next GLCD update
dstate = D_init;
}
switch (dstate) {
case D_init:
ipag = 0;
if (disp_frame) { // select flipper buffer, only one page with PIC32A
pb = rgbOledBmp0;
} else {
pb = rgbOledBmp0;
}
/* FALLTHRU */
case D_page: // send the page address commands via DMA
LCD_SELECT(); // enable the GLCD chip for SPI transfers
dstate = D_buffer;
lcd_moveto_xy(ipag, 0); // calculate address data nibbles and store in rgbOledBmp_page array
/*
* DMA_ChannelCallbackRegister and SPI setup in OledInit
*/
LCD_CMD();
DMA_ChannelTransfer(DMA_CHANNEL_0, (const void *) rgbOledBmp_page, (const void*) &SPI1BUF, (size_t) 4);
break;
case D_buffer: // send the GLCD buffer data via DMA
ipag++;
if (ipag <= cpagOledMax) {
LCD_SELECT(); // enable the GLCD chip for SPI transfers
dstate = D_page;
LCD_DRAM();
DMA_ChannelTransfer(DMA_CHANNEL_0, (const void *) pb, (const void*) &SPI1BUF, (size_t) ccolOledMax);
pb += ccolOledMax;
} else {
dstate = D_idle;
LCD_UNSELECT(); // all done with the GLCD
}
break;
case D_idle:
default:
LCD_UNSELECT();
break;
}
}
Last edited:










































