aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/avr8/lib/hardware/spi.frt
blob: 49dbd1941d1be2522bd08bfbaae6d5572194e70c (plain)
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
\ SPI routines

\ requires: 2rvalue (with further deps)
\           bitnames

#require 2rvalue.frt
#require bitnames.frt

\ definitions from application, matching the
\ SPI hardware pins
\ PORTB 1 portpin: spi.clk
\ PORTB 2 portpin: spi.mosi
\ PORTB 3 portpin: spi.miso

\ usage

\ specific slave select pin
\ PORTX PINY portpin: appl.ss_line
\ appl.ss_line to spi.ss

0. 2rvalue spi.ss

\ update spi.ss to the actual setup
\ +spi  -- turn on SPI module, sets up the pins as well
\ spi.modeX spi.setmode  -- switch clock polarity/clock phase
\ spi.f/X   spi.setspeed -- select spi clock rate relative to f_cpu
\ +spi.2x                -- double speed
\ -spi.2x                -- normal speed
\ -spi                   -- turn off SPI
\

\ following definitions are the same for all atmegas

SPSR 0 portpin: spi.2x

SPCR 6 portpin: spi.enable
SPCR 5 portpin: spi.dord
SPCR 4 portpin: spi.master
SPCR %00001100 bitmask: spi.mode
SPCR %00000011 bitmask: spi.speed

$0 constant spi.mode0  \ sample rising/--
$4 constant spi.mode1  \ --/sample falling
$8 constant spi.mode2  \ sample falling/--
$c constant spi.mode3  \ --/sample rising

0 constant spi.f/4
1 constant spi.f/16
2 constant spi.f/64
3 constant spi.f/128

: +spi
   \ Slave select *must* be *always* at a controlled level when SPI is activated.
   \ Changing a pin into output mode change its level to low. that makes a SPI think
   \ a communication has started which is not the case when this word is called.
   spi.ss high       \ deselect slave
   spi.ss pin_output \ possibly short low pulse
   spi.ss high       \ 

   \ now its save to turn on the SPI module
   spi.master high
   spi.enable high

   \ since spi.ss is HIGH, nobody will be confused
   spi.clk pin_output
   spi.mosi pin_output
   \ miso is controlled by SPI module internally
;

: -spi 0 SPCR c! ;

\ check SPI device datasheet for mode settings
: spi.setmode ( spi-mode -- )
  spi.mode pin!
;

\ speed relative to f_cpu, constants see above
: spi.setspeed ( spi.speed -- )
  spi.speed pin!
;

\ double speed mode
: +spi2x 
    spi.2x high
;


: -spi2x
    spi.2x low
;

\ send a byte, ignore recieved byte
: c!spi ( c -- )
    c!@spi drop
;

  \ receive a byte, send a dummy one
: c@spi ( -- c)
    0 c!@spi
;

\ send a cell, check data order for MSB/LSB
\ untested so far
: !@spi
  dup >< ( -- low high )
  spi.dord is_high? if swap then \ LSB first
  c!@spi swap c!@spi
  spi.dord is_low? if swap then  \ MSB was first
  >< or \ upper nibble is set to 0 automatically
;