00001 #include <iostream>
00002 #include "spisink.h"
00003
00004 using namespace std;
00005
00006 enum {
00007 SSBIT = 0,
00008 SCLKBIT = 1,
00009 MISOBIT = 2
00010 };
00011
00012 SpiSink::SpiSink( Net& ssNet,
00013 Net& sclkNet,
00014 Net& misoNet,
00015 bool clockIsIdleHigh,
00016 bool clockSampleOnLeadingEdge
00017 ) throw():
00018 _port(0),
00019 _ss( &_port, (unsigned char)(1<<SSBIT) ),
00020 _sclk( &_port, (unsigned char)(1<<SCLKBIT) ),
00021 _miso( &_port, (unsigned char)(1<<MISOBIT) ),
00022 _ssState(false),
00023 _sclkState(false),
00024 _misoState(false),
00025 _state(0),
00026 _sr(0),
00027 _clockIsIdleHigh(clockIsIdleHigh),
00028 _clockSampleOnLeadingEdge(clockSampleOnLeadingEdge),
00029 _prevClkState(clockIsIdleHigh),
00030 _prevSS(true)
00031 {
00032 _ss.outState = Pin::PULLUP;
00033 ssNet.Add(&_ss);
00034
00035 _sclk.outState = Pin::PULLUP;
00036 sclkNet.Add(&_sclk);
00037
00038 _miso.outState = Pin::PULLUP;
00039 misoNet.Add(&_miso);
00040 }
00041
00042 int SpiSink::Step(bool &trueHwStep, SystemClockOffset *timeToNextStepIn_ns){
00043 *timeToNextStepIn_ns = 1000;
00044 bool sample = false;
00045
00046 _ssState = (_port & (1<<SSBIT))?true:false;
00047 _sclkState = (_port & (1<<SCLKBIT))?true:false;
00048 _misoState = (_port & (1<<MISOBIT))?true:false;
00049
00050 if(!_ssState){
00051 if(_prevClkState != _sclkState){
00052 _prevClkState = _sclkState;
00053 if(_clockIsIdleHigh){
00054
00055 if(_clockSampleOnLeadingEdge){
00056
00057 sample = (_sclkState)?false:true;
00058 }
00059 else {
00060
00061 sample = (_sclkState)?true:false;
00062 }
00063 }
00064 else {
00065
00066 if(_clockSampleOnLeadingEdge){
00067
00068 sample = (_sclkState)?true:false;
00069 }
00070 else {
00071
00072 sample = (_sclkState)?false:true;
00073 }
00074 }
00075 }
00076 }
00077 else {
00078 _sr = 0;
00079 _state = 0;
00080 }
00081
00082 for(;;){
00083 switch(_state){
00084 case 0:
00085 if(!_ssState){
00086 _state = 1;
00087 continue;
00088 }
00089 break;
00090 case 1:
00091 case 2:
00092 case 3:
00093 case 4:
00094 case 5:
00095 case 6:
00096 case 7:
00097 if(sample){
00098 _sr <<= 1;
00099 if(_misoState){
00100 _sr |= 0x01;
00101 }
00102 ++_state;
00103 }
00104 break;
00105 case 8:
00106 if(sample){
00107 _sr <<= 1;
00108 if(_misoState){
00109 _sr |= 0x01;
00110 }
00111 _state = 1;
00112
00113 streamsize streamWidth = cout.width();
00114 ios_base::fmtflags saved = cout.flags();
00115 cout.setf(ios_base::hex,ios_base::basefield);
00116 cout.setf(ios_base::uppercase);
00117 cout.setf(ios_base::right);
00118 cout << "spisink: 0x";
00119 cout.width(2);
00120 cout.fill('0');
00121 cout << (unsigned long)_sr;
00122 cout << endl;
00123 cout.width(streamWidth);
00124 cout.flags(saved);
00125 }
00126 break;
00127 }
00128 break;
00129 }
00130
00131 if(_ssState != _prevSS){
00132 if(_ssState){
00133 cout << "spisink: /SS negated" << endl;
00134 }
00135 else {
00136 cout << "spisink: /SS asserted" << endl;
00137 }
00138 _prevSS = _ssState;
00139 }
00140
00141 return 0;
00142 }
00143