forked from kbr-net/sdrive-max
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspi.c
150 lines (134 loc) · 3.78 KB
/
spi.c
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*! \file spi.c \brief SPI interface driver. */
//*****************************************************************************
//
// File Name : 'spi.c'
// Title : SPI interface driver
// Author : Pascal Stang - Copyright (C) 2000-2002
// Created : 11/22/2000
// Revised : 06/06/2002
// Version : 0.6
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// ----------------------------------------------------------------------------
// 17.8.2008
// Bob!k & Raster, C.P.U.
// Original code was modified especially for the SDrive device.
// Some parts of code have been added, removed, rewrited or optimized due to
// lack of MCU AVR Atmega8 memory.
// ----------------------------------------------------------------------------
// 19.05.2014
// enhanced by kbr
// ----------------------------------------------------------------------------
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
//#include <avr/signal.h>
#include "spi.h"
// access routines
void spiInit()
{
#ifdef __AVR_ATmega128__
// setup SPI I/O pins
sbi(PORTB, 0); // SS high first
sbi(DDRB, 0); // SS must be output for Master mode to work
sbi(PORTB, 1); // set SCK hi
sbi(DDRB, 1); // set SCK as output
cbi(DDRB, 3); // set MISO as input
//sbi(PORTB, 3); // set MISO pullup !!! Now in hardware to 3.3V
sbi(DDRB, 2); // set MOSI as output
#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega168__)
// setup SPI I/O pins
sbi(PORTB, 2); // SS high first
sbi(DDRB, 2); // SS must be output for Master mode to work
sbi(PORTB, 5); // set SCK hi
sbi(DDRB, 5); // set SCK as output
cbi(DDRB, 4); // set MISO as input
//sbi(PORTB, 4); // set MISO pullup !!! Now in hardware to 3.3V
sbi(DDRB, 3); // set MOSI as output
#else // atmega32
// setup SPI I/O pins
sbi(PORTB, 4); // SS high first
sbi(DDRB, 4); // SS must be output for Master mode to work
sbi(PORTB, 7); // set SCK hi
sbi(DDRB, 7); // set SCK as output
cbi(DDRB, 6); // set MISO as input
//sbi(PORTB, 6); // set MISO pullup !!! Now in hardware to 3.3V
sbi(DDRB, 5); // set MOSI as output
#endif
// setup SPI interface :
// clock = f/128 slowest speed for Init
/*
cbi(SPSR, SPI2X);
sbi(SPCR, SPR0);
sbi(SPCR, SPR1);
// master mode
sbi(SPCR, MSTR);
// select clock phase positive-going in middle of data
cbi(SPCR, CPOL);
// Data order MSB first
cbi(SPCR,DORD);
// enable SPI
sbi(SPCR, SPE);
*/
SPSR &= ~_BV(SPI2X);
SPCR = (_BV(SPR0)|_BV(SPR1)|_BV(MSTR)|_BV(SPE));
// clear status
inb(SPSR);
//inb(SPDR);
}
void spiSendByte(u08 data)
{
// send a byte over SPI and ignore reply
while(!(inb(SPSR) & (1<<SPIF)));
outb(SPDR, data);
}
u08 spiTransferByte(u08 data)
{
// send the given data
outb(SPDR, data);
// wait for transfer to complete
while(!(inb(SPSR) & (1<<SPIF)));
// *** reading of the SPSR and SPDR are crucial
// *** to the clearing of the SPIF flag
// *** in non-interrupt mode
//inb(SPDR);
// return the received data
return inb(SPDR);
}
u08 spiTransferFF()
{
return spiTransferByte(0xFF);
}
//#define spiTransferTwoFF() { spiTransferFF(); spiTransferFF(); }
/*
void spiTransfer10xFF()
{
u08 num=10;
do
{
spiTransferFF();
num--;
}
while(num);
}
*/
/*
u16 spiTransferWord(u16 data)
{
u16 rxData = 0;
// send MS byte of given data
rxData = (spiTransferByte((data>>8) & 0x00FF))<<8;
// send LS byte of given data
rxData |= (spiTransferByte(data & 0x00FF));
// return the received data
return rxData;
}
*/