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.

Dependents:   VirtualSPI

Committer:
Yajirushi
Date:
Sat May 30 12:57:17 2015 +0000
Revision:
0:1d153d73d37d
first commit

Who changed what in which revision?

UserRevisionLine numberNew 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 }