-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathspi-base-avr-v2.txt
147 lines (134 loc) · 3.66 KB
/
spi-base-avr-v2.txt
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
\ *********************************************************************
\ Words to drive the SPI module on the ATmega2560
\ Filename: spi-base-avr-v2.txt.txt
\ PJ 31-Jan-2016: initial listing spi-base-avr.txt
\ adaptation MP 04-nov-2019
\ Date: 18/11/2019
\ MCU: ARDUINO all models
\ GNU General Public License
\ *********************************************************************
-spi-base
marker -spi-base
\ Registers of interest
$24 constant DDRB \ Port B Data Direction Register
$25 constant PORTB \ Port B Data Register
$4c constant SPCR \ SPI Control Register
$4d constant SPSR \ SPI Status Register
$4e constant SPDR \ SPI Data Register
\ bit masks for ARDUINO MEGA
%00000001 constant mSS1 ( PB0 )
%00000010 constant mSCK ( PB1 )
%00000100 constant mMOSI ( PB2 )
%00001000 constant mMISO ( PB3 )
\ %00010000 constant mRST ( PB4 )
$80 constant mSPIF \ SPI Interrupt Flag
$40 constant mWCOL \ Write Collision Flag
: slave.select ( mSSx -- ) \ select slave x in mSSx constant
dup DDRB mset \ SS as output
PORTB mclr \ deselect
;
: slave.deselect ( mSSx -- ) \ unselect slave
dup DDRB mset \ SS as output
PORTB mset \ deselect
;
%01000000 constant SPCR_SPE \ SPI Enable
: spi.enable ( ---)
SPCR_SPE SPCR mset ;
: spi.disable ( ---)
SPCR_SPE SPCR mclr ;
%00100000 constant SPCR_DORD \ Data Order
: LSB.first ( --- ) \ select LOW Signifiant Bit first
SPCR_DORD SPCR mset ;
: MSB.first ( --- ) \ select MOST Signifiant Bit first
SPCR_DORD SPCR mclr ;
%00010000 constant SPCR_MSTR \ Master/Slave Select
: Master.mode
SPCR_MSTR SPCR mset ;
: Slave.mode
SPCR_MSTR SPCR mclr ;
\ SPI mode
%00000100 constant SPCR_CPHA \ Clock Phase
%00001000 constant SPCR_CPOL \ Clock Polarity
: Mode0
SPCR_CPHA SPCR mclr \ Idle CLK = 0
SPCR_CPOL SPCR mclr \ Sample on leading edge
;
: Mode1
SPCR_CPHA SPCR mclr \ Idle CLK = 0
SPCR_CPOL SPCR mset \ Sample on trailing edge
;
: Mode2
SPCR_CPHA SPCR mset \ Idle CLK = 1
SPCR_CPOL SPCR mclr \ Sample on trailing edge
;
: Mode3
SPCR_CPHA SPCR mset \ Idle CLK = 1
SPCR_CPOL SPCR mset \ Sample on leading edge
;
\ SPI clock speed
%00000010 constant SPCR_SPR1 \ SPI Clock Rate Selects
%00000001 constant SPCR_SPR0 \ SPI Clock Rate Selects
%00000001 constant SPSR_SPI2x \ Double SPI Speed
: spi2X.off ( --- )
SPSR_SPI2x SPSR mclr
;
: spi2X.on ( --- )
SPSR_SPI2x SPSR mset
;
: fosc/4
SPCR_SPR1 SPCR mclr
SPCR_SPR0 SPCR mclr
spi2X.off
;
: fosc/16
SPCR_SPR1 SPCR mclr
SPCR_SPR0 SPCR mset
spi2X.off
;
: fosc/64
SPCR_SPR1 SPCR mset
SPCR_SPR0 SPCR mclr
spi2X.off
;
: fosc/128
SPCR_SPR1 SPCR mset
SPCR_SPR0 SPCR mset
spi2X.off
;
: spi.init ( -- )
mSCK DDRB mset \ SCK as output
mSCK PORTB mclr \ clock idles low
mMOSI DDRB mset \ MOSI as output
mMISO DDRB mclr \ MISO as input
mMISO PORTB mset \ activate pull-up on MISO
mSS1 DDRB mset \ SS as output
mSS1 PORTB mset \ deselect
spi.enable
Master.mode
Mode0
fosc/16
SPSR c@ drop SPDR c@ drop \ will clear SPIF
;
: spi.close ( -- )
$00 SPCR c!
;
: spi.wait ( -- )
begin
mSPIF SPSR mtst
until
;
: spi.cexch ( c1 -- c2 )
SPDR c!
spi.wait
SPDR c@
;
: spi.csend ( c1 -- )
spi.cexch drop
;
: spi.test ( -- )
mSS1 slave.select
spi.init
$1c spi.csend \ an arbitrary byte
mSS1 slave.deselect
spi.close
;