Virtual SPI interface library. SPI専用ピンを使わず、通常のIOピンを使用してSPI通信を偽装します。 使い方は通常のSPIと同じようなものですが、frequency(周波数)の設定があまり厳密ではないので実験用途でデバッグしたいとき等にご使用ください。 「SPI専用のピンが壊れているのではないのか?」というときの確認に便利です。 Implement the SPI communication in the "only general purpose IO pin" without a SPI pin.
VSPI.cpp@0:1d153d73d37d, 2015-05-30 (annotated)
- Committer:
- Yajirushi
- Date:
- Sat May 30 12:57:17 2015 +0000
- Revision:
- 0:1d153d73d37d
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Yajirushi | 0:1d153d73d37d | 1 | #include "VSPI.h" |
Yajirushi | 0:1d153d73d37d | 2 | |
Yajirushi | 0:1d153d73d37d | 3 | VSPI::VSPI(PinName mosi, PinName sclk){ |
Yajirushi | 0:1d153d73d37d | 4 | hasInput = false; |
Yajirushi | 0:1d153d73d37d | 5 | hasSelect = false; |
Yajirushi | 0:1d153d73d37d | 6 | VSPI(mosi, NC, sclk, NC); |
Yajirushi | 0:1d153d73d37d | 7 | } |
Yajirushi | 0:1d153d73d37d | 8 | |
Yajirushi | 0:1d153d73d37d | 9 | VSPI::VSPI(PinName mosi, PinName miso, PinName sclk){ |
Yajirushi | 0:1d153d73d37d | 10 | hasSelect = false; |
Yajirushi | 0:1d153d73d37d | 11 | VSPI(mosi, miso, sclk, NC); |
Yajirushi | 0:1d153d73d37d | 12 | } |
Yajirushi | 0:1d153d73d37d | 13 | |
Yajirushi | 0:1d153d73d37d | 14 | VSPI::VSPI(PinName mosi, PinName miso, PinName sclk, PinName csel){ |
Yajirushi | 0:1d153d73d37d | 15 | mo = new DigitalOut(mosi); |
Yajirushi | 0:1d153d73d37d | 16 | mi = new DigitalIn(miso); |
Yajirushi | 0:1d153d73d37d | 17 | cl = new DigitalOut(sclk); |
Yajirushi | 0:1d153d73d37d | 18 | cs = new DigitalOut(csel); |
Yajirushi | 0:1d153d73d37d | 19 | |
Yajirushi | 0:1d153d73d37d | 20 | hasInput = !(miso == NC); |
Yajirushi | 0:1d153d73d37d | 21 | hasSelect = !(csel == NC); |
Yajirushi | 0:1d153d73d37d | 22 | |
Yajirushi | 0:1d153d73d37d | 23 | freq = 1000000; |
Yajirushi | 0:1d153d73d37d | 24 | w_us = 1; |
Yajirushi | 0:1d153d73d37d | 25 | mode = 0; |
Yajirushi | 0:1d153d73d37d | 26 | bits = 8; |
Yajirushi | 0:1d153d73d37d | 27 | activeLow = true; |
Yajirushi | 0:1d153d73d37d | 28 | msbf = true; |
Yajirushi | 0:1d153d73d37d | 29 | isHigh = false; |
Yajirushi | 0:1d153d73d37d | 30 | } |
Yajirushi | 0:1d153d73d37d | 31 | |
Yajirushi | 0:1d153d73d37d | 32 | void VSPI::format(unsigned char bits, unsigned char mode){ |
Yajirushi | 0:1d153d73d37d | 33 | bits = (bits > 32)? 32:(bits<8)? 8:bits; |
Yajirushi | 0:1d153d73d37d | 34 | mode = (mode > 4)? 0:mode; |
Yajirushi | 0:1d153d73d37d | 35 | this->bits = bits; |
Yajirushi | 0:1d153d73d37d | 36 | this->mode = mode; |
Yajirushi | 0:1d153d73d37d | 37 | } |
Yajirushi | 0:1d153d73d37d | 38 | |
Yajirushi | 0:1d153d73d37d | 39 | void VSPI::frequency(unsigned int hz){ |
Yajirushi | 0:1d153d73d37d | 40 | freq = (hz>1000000)? 1000000:(hz<10000)? 10000:hz; |
Yajirushi | 0:1d153d73d37d | 41 | w_us = (unsigned int)(1000000/(freq*2)); |
Yajirushi | 0:1d153d73d37d | 42 | } |
Yajirushi | 0:1d153d73d37d | 43 | |
Yajirushi | 0:1d153d73d37d | 44 | int VSPI::write(int value){ |
Yajirushi | 0:1d153d73d37d | 45 | int rv = 0; |
Yajirushi | 0:1d153d73d37d | 46 | |
Yajirushi | 0:1d153d73d37d | 47 | if(msbf) value = __rbit(value)>>(32 - bits); |
Yajirushi | 0:1d153d73d37d | 48 | /* |
Yajirushi | 0:1d153d73d37d | 49 | if(msbf){ |
Yajirushi | 0:1d153d73d37d | 50 | value = ((value&0xAAAAAAAA)>>1) | ((value&0x55555555)<<1); |
Yajirushi | 0:1d153d73d37d | 51 | value = ((value&0xCCCCCCCC)>>2) | ((value&0x33333333)<<2); |
Yajirushi | 0:1d153d73d37d | 52 | value = ((value&0xF0F0F0F0)>>4) | ((value&0x0F0F0F0F)<<4); |
Yajirushi | 0:1d153d73d37d | 53 | value = ((value&0xFF00FF00)>>8) | ((value&0x00FF00FF)<<8); |
Yajirushi | 0:1d153d73d37d | 54 | value = ((value&0xFFFF0000)>>16) | ((value&0x0000FFFF)<<16); |
Yajirushi | 0:1d153d73d37d | 55 | value >>= (32 - bits); |
Yajirushi | 0:1d153d73d37d | 56 | } |
Yajirushi | 0:1d153d73d37d | 57 | */ |
Yajirushi | 0:1d153d73d37d | 58 | |
Yajirushi | 0:1d153d73d37d | 59 | switch(mode){ |
Yajirushi | 0:1d153d73d37d | 60 | case 0: //CPOL=0 CPHA=0 |
Yajirushi | 0:1d153d73d37d | 61 | for(unsigned char i=0; i<bits; i++){ |
Yajirushi | 0:1d153d73d37d | 62 | mo->write((value>>i)&1); |
Yajirushi | 0:1d153d73d37d | 63 | rv |= mi->read(); |
Yajirushi | 0:1d153d73d37d | 64 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 65 | cl->write(1); |
Yajirushi | 0:1d153d73d37d | 66 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 67 | cl->write(0); |
Yajirushi | 0:1d153d73d37d | 68 | } |
Yajirushi | 0:1d153d73d37d | 69 | break; |
Yajirushi | 0:1d153d73d37d | 70 | |
Yajirushi | 0:1d153d73d37d | 71 | case 1: //CPOL=0 CPHA=1 |
Yajirushi | 0:1d153d73d37d | 72 | for(unsigned char i=0; i<bits; i++){ |
Yajirushi | 0:1d153d73d37d | 73 | cl->write(1); |
Yajirushi | 0:1d153d73d37d | 74 | mo->write((value>>i)&1); |
Yajirushi | 0:1d153d73d37d | 75 | rv |= mi->read(); |
Yajirushi | 0:1d153d73d37d | 76 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 77 | cl->write(0); |
Yajirushi | 0:1d153d73d37d | 78 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 79 | } |
Yajirushi | 0:1d153d73d37d | 80 | break; |
Yajirushi | 0:1d153d73d37d | 81 | |
Yajirushi | 0:1d153d73d37d | 82 | case 2: //CPOL=1 CPHA=0 |
Yajirushi | 0:1d153d73d37d | 83 | for(unsigned char i=0; i<bits; i++){ |
Yajirushi | 0:1d153d73d37d | 84 | mo->write((value>>i)&1); |
Yajirushi | 0:1d153d73d37d | 85 | rv |= mi->read(); |
Yajirushi | 0:1d153d73d37d | 86 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 87 | cl->write(0); |
Yajirushi | 0:1d153d73d37d | 88 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 89 | cl->write(1); |
Yajirushi | 0:1d153d73d37d | 90 | } |
Yajirushi | 0:1d153d73d37d | 91 | break; |
Yajirushi | 0:1d153d73d37d | 92 | |
Yajirushi | 0:1d153d73d37d | 93 | case 3: //CPOL=1 CPHA=1 |
Yajirushi | 0:1d153d73d37d | 94 | for(unsigned char i=0; i<bits; i++){ |
Yajirushi | 0:1d153d73d37d | 95 | cl->write(0); |
Yajirushi | 0:1d153d73d37d | 96 | mo->write((value>>i)&1); |
Yajirushi | 0:1d153d73d37d | 97 | rv |= mi->read(); |
Yajirushi | 0:1d153d73d37d | 98 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 99 | cl->write(1); |
Yajirushi | 0:1d153d73d37d | 100 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 101 | } |
Yajirushi | 0:1d153d73d37d | 102 | break; |
Yajirushi | 0:1d153d73d37d | 103 | } |
Yajirushi | 0:1d153d73d37d | 104 | |
Yajirushi | 0:1d153d73d37d | 105 | if(!msbf) rv = __rbit(rv<<(32 - bits)); |
Yajirushi | 0:1d153d73d37d | 106 | /* |
Yajirushi | 0:1d153d73d37d | 107 | if(hasInput && !msbf){ |
Yajirushi | 0:1d153d73d37d | 108 | rv <<= (32 - bits); |
Yajirushi | 0:1d153d73d37d | 109 | rv = ((rv&0xAAAAAAAA)>>1) | ((rv&0x55555555)<<1); |
Yajirushi | 0:1d153d73d37d | 110 | rv = ((rv&0xCCCCCCCC)>>2) | ((rv&0x33333333)<<2); |
Yajirushi | 0:1d153d73d37d | 111 | rv = ((rv&0xF0F0F0F0)>>4) | ((rv&0x0F0F0F0F)<<4); |
Yajirushi | 0:1d153d73d37d | 112 | rv = ((rv&0xFF00FF00)>>8) | ((rv&0x00FF00FF)<<8); |
Yajirushi | 0:1d153d73d37d | 113 | rv = ((rv&0xFFFF0000)>>16) | ((rv&0x0000FFFF)<<16); |
Yajirushi | 0:1d153d73d37d | 114 | } |
Yajirushi | 0:1d153d73d37d | 115 | */ |
Yajirushi | 0:1d153d73d37d | 116 | |
Yajirushi | 0:1d153d73d37d | 117 | return rv; |
Yajirushi | 0:1d153d73d37d | 118 | } |
Yajirushi | 0:1d153d73d37d | 119 | |
Yajirushi | 0:1d153d73d37d | 120 | int VSPI::wwcs(int value){ |
Yajirushi | 0:1d153d73d37d | 121 | if(!hasSelect) return 0; |
Yajirushi | 0:1d153d73d37d | 122 | |
Yajirushi | 0:1d153d73d37d | 123 | cs->write(activeLow? 0:1); |
Yajirushi | 0:1d153d73d37d | 124 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 125 | |
Yajirushi | 0:1d153d73d37d | 126 | int rv = write(value); |
Yajirushi | 0:1d153d73d37d | 127 | |
Yajirushi | 0:1d153d73d37d | 128 | wait_us(w_us); |
Yajirushi | 0:1d153d73d37d | 129 | cs->write(activeLow? 1:0); |
Yajirushi | 0:1d153d73d37d | 130 | isHigh = activeLow? 1:0; |
Yajirushi | 0:1d153d73d37d | 131 | |
Yajirushi | 0:1d153d73d37d | 132 | return rv; |
Yajirushi | 0:1d153d73d37d | 133 | } |
Yajirushi | 0:1d153d73d37d | 134 | |
Yajirushi | 0:1d153d73d37d | 135 | int VSPI::wwcs(int value, unsigned int waitMicros){ |
Yajirushi | 0:1d153d73d37d | 136 | if(!hasSelect) return 0; |
Yajirushi | 0:1d153d73d37d | 137 | |
Yajirushi | 0:1d153d73d37d | 138 | cs->write(activeLow? 0:1); |
Yajirushi | 0:1d153d73d37d | 139 | wait_us(waitMicros); |
Yajirushi | 0:1d153d73d37d | 140 | |
Yajirushi | 0:1d153d73d37d | 141 | int rv = write(value); |
Yajirushi | 0:1d153d73d37d | 142 | |
Yajirushi | 0:1d153d73d37d | 143 | wait_us(waitMicros); |
Yajirushi | 0:1d153d73d37d | 144 | cs->write(activeLow? 1:0); |
Yajirushi | 0:1d153d73d37d | 145 | isHigh = activeLow? 1:0; |
Yajirushi | 0:1d153d73d37d | 146 | |
Yajirushi | 0:1d153d73d37d | 147 | return rv; |
Yajirushi | 0:1d153d73d37d | 148 | } |
Yajirushi | 0:1d153d73d37d | 149 | |
Yajirushi | 0:1d153d73d37d | 150 | void VSPI::setBitOrder(bool isMSBfirst){ |
Yajirushi | 0:1d153d73d37d | 151 | msbf = isMSBfirst; |
Yajirushi | 0:1d153d73d37d | 152 | } |
Yajirushi | 0:1d153d73d37d | 153 | |
Yajirushi | 0:1d153d73d37d | 154 | void VSPI::setCSmode(bool isActiveLow){ |
Yajirushi | 0:1d153d73d37d | 155 | activeLow = isActiveLow; |
Yajirushi | 0:1d153d73d37d | 156 | cs->write(activeLow? 1:0); |
Yajirushi | 0:1d153d73d37d | 157 | isHigh = activeLow? 1:0; |
Yajirushi | 0:1d153d73d37d | 158 | } |
Yajirushi | 0:1d153d73d37d | 159 | |
Yajirushi | 0:1d153d73d37d | 160 | void VSPI::setCS(bool H){ |
Yajirushi | 0:1d153d73d37d | 161 | cs->write(H? 1:0); |
Yajirushi | 0:1d153d73d37d | 162 | isHigh = H; |
Yajirushi | 0:1d153d73d37d | 163 | } |
Yajirushi | 0:1d153d73d37d | 164 | |
Yajirushi | 0:1d153d73d37d | 165 | bool VSPI::getCS(){ |
Yajirushi | 0:1d153d73d37d | 166 | return isHigh; |
Yajirushi | 0:1d153d73d37d | 167 | } |
Yajirushi | 0:1d153d73d37d | 168 | |
Yajirushi | 0:1d153d73d37d | 169 | bool VSPI::csInvert(){ |
Yajirushi | 0:1d153d73d37d | 170 | cs->write(isHigh? 0:1); |
Yajirushi | 0:1d153d73d37d | 171 | isHigh = !isHigh; |
Yajirushi | 0:1d153d73d37d | 172 | return isHigh? 0:1; |
Yajirushi | 0:1d153d73d37d | 173 | } |