spi.c 1.72 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//
// spi.c
//


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

// 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 defines in the file defines.h to see defines
// such as data direction registers and bit positions, and as always:
// RTFD




#define MOSI_bm (1 << 4) //on port A
#define SCK_bm (1 << 6) //on port A
#define SPI_PORT PORTA //

27
#define CS_bm (1 << 6) //on port C
28
29
#define CS_PORT PORTC //

30
#define SPI_IF_ENABLE_bp 0
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

void SPI_MasterInit()
{
	// Initialize the SPI port as master
	// You will need to set MOSI, SCK, CS (slave select) as outputs
	
	
	SPI_PORT.DIRSET = (MOSI_bm) | (SCK_bm); //Set pins as output
	CS_PORT.DIRSET = (CS_bm);

	CS_PORT.OUTSET = (CS_bm); //Set CS 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 CS does not disable master mode
	SPI0.CTRLB |= (SPI_SSD_bm);
49
	SPI0.INTCTRL |= (1<<SPI_IF_ENABLE_bp);
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
}


void SPI_MasterTransmit(char cData)
{
	// First select the correct slave by setting the slave select (SS) bit LOW
	CS_PORT.OUTCLR = (CS_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 is the only interupt 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
	CS_PORT.OUTSET = (CS_bm);
}