spi.c 1.59 KB
Newer Older
Petter Breedveld's avatar
Petter Breedveld committed
1
2
3
//
// spi.c
//
4

Petter Breedveld's avatar
Petter Breedveld committed
5
6
7
8
9
10
11

// System headers
#include <avr/io.h>

// Project headers
#include "spi.h"

Petter Breedveld's avatar
Petter Breedveld committed
12

Petter Breedveld's avatar
Petter Breedveld committed
13

14
//Oled is connected to alternate SPI pins
Petter Breedveld's avatar
Petter Breedveld committed
15
16
#define MOSI_bm 1<<2 //on port C
#define SCK_bm 1<<0 //on port C
Petter Breedveld's avatar
Petter Breedveld committed
17
#define SS_bm 1<<3 //on port A
Petter Breedveld's avatar
Petter Breedveld committed
18
#define SPI_PORT PORTC //We can now use SPI_PORT.DIR, .OUT etc.
Petter Breedveld's avatar
Petter Breedveld committed
19
#define SS_PORT PORTA //SS is on a different port
Petter Breedveld's avatar
Petter Breedveld committed
20

Petter Breedveld's avatar
Petter Breedveld committed
21
//We could also have defined bit positions for MOSI, SCL and SS.
Petter Breedveld's avatar
Petter Breedveld committed
22
23
24
25
26



void SPI_MasterInit()
{
27
28
29
	// Initialize the SPI port as master
	// You will need to set MOSI, SCK, SS (slave select) as outputs
	
Petter Breedveld's avatar
Petter Breedveld committed
30
31
	//Connect OLED to EXT3
	
Petter Breedveld's avatar
Petter Breedveld committed
32
	PORTMUX.CTRLB |= PORTMUX_SPI0_bm; //To use alternative SPI pins
33
	
Petter Breedveld's avatar
Petter Breedveld committed
34
35
	SPI_PORT.DIR |= MOSI_bm | SCK_bm; //Set pins as output
	SS_PORT.DIR |= SS_bm;
36

Petter Breedveld's avatar
Petter Breedveld committed
37
	SS_PORT.OUTSET = SS_bm; //Set SS high -> OLED inactive
38
	
Petter Breedveld's avatar
Petter Breedveld committed
39
	
40
	// Now enable SPI, Master and set clock rate
Petter Breedveld's avatar
Petter Breedveld committed
41
	
Petter Breedveld's avatar
Petter Breedveld committed
42
	SPI0.CTRLA |= SPI_ENABLE_bm | SPI_MASTER_bm; //Default clock divisor of 4 is fine
Petter Breedveld's avatar
Petter Breedveld committed
43
44
	
	
45

Petter Breedveld's avatar
Petter Breedveld committed
46
47
	//Make sure SS does not disable master mode (Possibly not required)
	SPI0.CTRLB |= SPI_SSD_bm;
Petter Breedveld's avatar
Petter Breedveld committed
48
49
50
51
52
}


void SPI_MasterTransmit(char cData)
{
Petter Breedveld's avatar
Petter Breedveld committed
53
	// First select the correct slave by setting its slave select (SS) LOW
Petter Breedveld's avatar
Petter Breedveld committed
54
	SS_PORT.OUTCLR = SS_bm;
Petter Breedveld's avatar
Petter Breedveld committed
55
56

	// Then start the transmission by assigning the data to the SPI data register
57
	SPI0.DATA = cData;
Petter Breedveld's avatar
Petter Breedveld committed
58

59
	// Now wait for the data transmission to complete by periodically checking the SPI status register
Petter Breedveld's avatar
Petter Breedveld committed
60
61
62
63
	//the SPI_IF and SPI_WRCOL is the only interrupt flag with a function in non-buffered mode.
	while(!(SPI0.INTFLAGS & SPI_IF_bm)){
		
	}
64
	SPI0.DATA; //Dummy read to clear flag
Petter Breedveld's avatar
Petter Breedveld committed
65
66

	// Finally set the slave select bit HIGH before leaving the function
Petter Breedveld's avatar
Petter Breedveld committed
67
	SS_PORT.OUTSET = SS_bm;
Petter Breedveld's avatar
Petter Breedveld committed
68
}