mrfioc2  2.3.0
mrmspi.cpp
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2010 Brookhaven Science Associates, as Operator of
3 * Brookhaven National Laboratory.
4 * Copyright (c) 2015 Paul Scherrer Institute (PSI), Villigen, Switzerland
5 * mrfioc2 is distributed subject to a Software License Agreement found
6 * in file LICENSE that is included with this distribution.
7 \*************************************************************************/
8 /*
9  * Author: Michael Davidsaver <mdavidsaver@gmail.com>
10  */
11 
12 #include <stdio.h>
13 
14 #include <epicsThread.h>
15 
16 #include <mrfCommonIO.h>
17 #define epicsExportSharedSymbols
18 #include "mrmspi.h"
19 #include <epicsExport.h>
20 
21 
22 // Data and Ctrl registers are offsets from device specific base
23 #define U32_SPIDData 0x0
24 #define U32_SPIDCtrl 0x4
25 #define SPIDCtrl_Overrun 0x80
26 #define SPIDCtrl_RecvRdy 0x40
27 #define SPIDCtrl_SendRdy 0x20
28 #define SPIDCtrl_SendEpt 0x10
29 #define SPIDCtrl_TxOver 0x08
30 #define SPIDCtrl_RxOver 0x04
31 #define SPIDCtrl_OE 0x02
32 #define SPIDCtrl_SS 0x01
33 
35 
36 MRMSPI::MRMSPI(volatile unsigned char *base)
37  :base(base)
38 {}
39 
41 
42 
43 void MRMSPI::select(unsigned id)
44 {
45  if(mrmSPIDebug)
46  printf("SPI: select %u\n", id);
47 
48  if(id==0) {
49  // deselect
50  WRITE32(base, SPIDCtrl, SPIDCtrl_OE);
51  // wait a bit to ensure the chip sees deselect
52  epicsThreadSleep(0.001);
53  // disable drivers
54  WRITE32(base, SPIDCtrl, 0);
55  } else {
56  // drivers on w/ !SS
57  WRITE32(base, SPIDCtrl, SPIDCtrl_OE);
58  // wait a bit to ensure the chip sees deselect
59  epicsThreadSleep(0.001);
60  // select
61  WRITE32(base, SPIDCtrl, SPIDCtrl_OE|SPIDCtrl_SS);
62  }
63 }
64 
65 epicsUInt8 MRMSPI::cycle(epicsUInt8 in)
66 {
67  double timeout = this->timeout();
68 
69  if(mrmSPIDebug)
70  printf("SPI %02x ", int(in));
71 
72  // wait for send ready to be set
73  {
74  mrf::TimeoutCalculator T(timeout);
75  while(T.ok() && !(READ32(base, SPIDCtrl)&SPIDCtrl_SendRdy))
76  epicsThreadSleep(T.inc());
77  if(!T.ok())
78  throw std::runtime_error("SPI cycle timeout2");
79 
80  if(mrmSPIDebug)
81  printf("(%f) ", T.sofar());
82  }
83 
84  WRITE32(base, SPIDData, in);
85 
86  if(mrmSPIDebug)
87  printf("-> ");
88 
89  // wait for recv ready to be set
90  {
91  mrf::TimeoutCalculator T(timeout);
92  while(T.ok() && !(READ32(base, SPIDCtrl)&SPIDCtrl_RecvRdy))
93  epicsThreadSleep(T.inc());
94  if(!T.ok())
95  throw std::runtime_error("SPI cycle timeout2");
96 
97  if(mrmSPIDebug)
98  printf("(%f) ", T.sofar());
99  }
100 
101  epicsUInt8 ret = READ32(base, SPIDData)&0xff;
102 
103  if(mrmSPIDebug) {
104  printf("%02x\n", int(ret));
105  }
106  return ret;
107 }
108 
109 extern "C" {
111 }
double inc()
Definition: spi.h:88
#define SPIDCtrl_OE
Definition: mrmspi.cpp:31
#define READ32(base, offset)
Definition: mrfCommonIO.h:114
virtual epicsUInt8 cycle(epicsUInt8 in) OVERRIDE FINAL
Definition: mrmspi.cpp:65
bool ok() const
Definition: spi.h:87
MRMSPI(volatile unsigned char *base)
Definition: mrmspi.cpp:36
double timeout() const
timeout in seconds for an individual cycle()
Definition: spi.cpp:41
epicsExportAddress(int, mrmSPIDebug)
#define SPIDCtrl_RecvRdy
Definition: mrmspi.cpp:26
virtual ~MRMSPI()
Definition: mrmspi.cpp:40
#define SPIDCtrl_SS
Definition: mrmspi.cpp:32
int mrmSPIDebug
Definition: mrmspi.cpp:34
double sofar() const
Definition: spi.h:97
virtual void select(unsigned id) OVERRIDE FINAL
Select numbered device. 0 clears selection.
Definition: mrmspi.cpp:43
#define SPIDCtrl_SendRdy
Definition: mrmspi.cpp:27
#define WRITE32(base, offset, value)
Definition: mrfCommonIO.h:119