1
1
from artiq .language .core import *
2
2
from artiq .language .types import *
3
-
4
-
5
- @syscall
6
- def spi_write (time_mu : TInt64 , channel : TInt32 , addr : TInt32 , data : TInt32
7
- ) -> TNone :
8
- raise NotImplementedError ("syscall not simulated" )
9
-
10
-
11
- @syscall
12
- def spi_read (time_mu : TInt64 , channel : TInt32 , addr : TInt32 ) -> TInt32 :
13
- raise NotImplementedError ("syscall not simulated" )
3
+ from artiq .coredevice .rt2wb import *
14
4
15
5
16
6
SPI_DATA_ADDR , SPI_XFER_ADDR , SPI_CONFIG_ADDR = range (3 )
@@ -34,55 +24,56 @@ class SPIMaster:
34
24
"""
35
25
def __init__ (self , dmgr , ref_period , channel ):
36
26
self .core = dmgr .get ("core" )
37
- self .ref_period_mu = int ( seconds_to_mu (ref_period , self .core ), 64 )
27
+ self .ref_period_mu = seconds_to_mu (ref_period , self .core )
38
28
self .channel = channel
39
29
self .write_div = 0
40
30
self .read_div = 0
41
31
# a full transfer takes prep_mu + xfer_mu
42
- self .prep_mu = int ( 0 , 64 )
43
- # chaned transfers can happen every xfer_mu
44
- self .xfer_mu = int ( 0 , 64 )
32
+ self .prep_mu = 0
33
+ # chained transfers can happen every xfer_mu
34
+ self .xfer_mu = 0
45
35
# The second transfer of a chain be written ref_period_mu
46
36
# after the first. Read data is available every xfer_mu starting
47
37
# a bit before prep_mu + xfer_mu.
48
38
49
39
@portable
50
40
def predict_xfer_mu (self , write_length , read_length ):
51
41
# this is only the intrinsic bit cycle duration
52
- return self .ref_period_mu * (
42
+ return int ( self .ref_period_mu * (
53
43
write_length * self .write_div +
54
- read_length * self .read_div )
44
+ read_length * self .read_div ))
55
45
56
46
@portable
57
47
def predict_prep_mu (self , write_div ):
58
- return self .ref_period_mu * (
48
+ return int ( self .ref_period_mu * (
59
49
2 + # intermediate transfers
60
50
# one write_div for the wait+idle cycle
61
- self .write_div )
51
+ self .write_div ))
62
52
63
53
@kernel
64
54
def set_config (self , flags = 0 , write_div = 6 , read_div = 6 ):
65
55
self .write_div = write_div
66
56
self .read_div = read_div
67
57
self .prep_mu = self .predict_prep_mu (write_div )
68
- spi_write (now_mu (), self .channel , SPI_CONFIG_ADDR , flags |
69
- ((write_div - 2 ) << 8 ) | ((read_div - 2 ) << 20 ))
58
+ rt2wb_write (now_mu (), self .channel , SPI_CONFIG_ADDR , flags |
59
+ ((write_div - 2 ) << 8 ) | ((read_div - 2 ) << 20 ))
70
60
delay_mu (self .ref_period_mu )
71
61
72
62
@kernel
73
63
def set_xfer (self , chip_select = 0 , write_length = 0 , read_length = 0 ):
74
64
self .xfer_mu = self .predict_xfer_mu (write_length , read_length )
75
- spi_write (now_mu (), self .channel , SPI_XFER_ADDR ,
76
- chip_select | (write_length << 16 ) | (read_length << 24 ))
65
+ rt2wb_write (now_mu (), self .channel , SPI_XFER_ADDR ,
66
+ chip_select | (write_length << 16 ) | (read_length << 24 ))
77
67
delay_mu (self .ref_period_mu )
78
68
79
69
@kernel
80
70
def write (self , data ):
81
- spi_write (now_mu (), self .channel , SPI_DATA_ADDR , data )
82
- delay_mu (self .prep_mu + self .xfer_mu )
71
+ rt2wb_write (now_mu (), self .channel , SPI_DATA_ADDR , data )
72
+ delay_mu (int ( self .prep_mu + self .xfer_mu ) )
83
73
84
74
@kernel
85
- def read (self ):
86
- r = spi_read (now_mu (), self .channel , SPI_DATA_ADDR )
75
+ def read_sync (self ):
76
+ r = rt2wb_read_sync (now_mu (), self .channel , SPI_DATA_ADDR ,
77
+ int (self .ref_period_mu ))
87
78
delay_mu (self .ref_period_mu )
88
79
return r
4 commit comments
sbourdeauducq commentedon Feb 29, 2016
Wishbone is a gateware implementation detail. I would make it transparent to the Python layers.
jordens commentedon Feb 29, 2016
RT2WB is not transparent because of how it handles reads. They can be pipelined or handled asynchronously.
sbourdeauducq commentedon Feb 29, 2016
Are you going to rewrite the DDS code as well so it uses this, then?
jordens commentedon Feb 29, 2016
yes