// // spi.c // // System headers #include // Project headers #include "spi.h" //Oled is connected to alternate SPI pins #define MOSI_bm 1<<2 //on port C #define SCK_bm 1<<0 //on port C #define SS_bm 1<<3 //on port A #define SPI_PORT PORTC //We can now use SPI_PORT.DIR, .OUT etc. #define SS_PORT PORTA //SS is on a different port //We could also have defined bit positions for MOSI, SCL and SS. void SPI_MasterInit() { // Initialize the SPI port as master // You will need to set MOSI, SCK, SS (slave select) as outputs //Connect OLED to EXT3 PORTMUX.CTRLB |= PORTMUX_SPI0_bm; //To use alternative SPI pins SPI_PORT.DIR |= MOSI_bm | SCK_bm; //Set pins as output SS_PORT.DIR |= SS_bm; SS_PORT.OUTSET = SS_bm; //Set SS high -> OLED inactive // Now enable SPI, Master and set clock rate SPI0.CTRLA |= SPI_ENABLE_bm | SPI_MASTER_bm; //Default clock divisor of 4 is fine //Make sure SS does not disable master mode (Possibly not required) SPI0.CTRLB |= SPI_SSD_bm; } void SPI_MasterTransmit(char cData) { // First select the correct slave by setting its slave select (SS) LOW SS_PORT.OUTCLR = SS_bm; // Then start the transmission by assigning the data to the SPI data register SPI0.DATA = cData; // Now wait for the data transmission to complete by periodically checking the SPI status register //the SPI_IF and SPI_WRCOL is the only interrupt flag with a function in non-buffered mode. while(!(SPI0.INTFLAGS & SPI_IF_bm)){ } SPI0.DATA; //Dummy read to clear flag // Finally set the slave select bit HIGH before leaving the function SS_PORT.OUTSET = SS_bm; }