// // spi.c // // System headers #include // Project headers #include "spi.h" // In this file, you will need to write the contents of the SPI communication routines. // You need to setup SPI communication in SPI_MasterInit() and // transmit data in SPI_MasterTransmit(...). // // HINT: Check out the , and as always: // RTFD //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 C #define SPI_PORT PORTC //We can now use SPI_PORT.DIR, .OUT etc. //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 PORTMUX.CTRLB |= PORTMUX_SPI0_bm; //To use alternative SPI pins SPI_PORT.DIR |= MOSI_bm | SCK_bm | SS_bm; //Set pins as output SPI_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 SPI_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 SPI_PORT.OUTSET = SS_bm; }