A very simple software SPI library for the MAX32630FTHR board. It was designed to support the max31865 and RadioHead libraries I ported for my Rocket mbed project.
swspi.cpp@0:8a4db0f083fc, 2017-06-11 (annotated)
- Committer:
- danjulio
- Date:
- Sun Jun 11 04:04:19 2017 +0000
- Revision:
- 0:8a4db0f083fc
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
danjulio | 0:8a4db0f083fc | 1 | // Software (bit-banged) SPI Module supporting two modes. |
danjulio | 0:8a4db0f083fc | 2 | // Each mode consists of a CS and CPHA mode |
danjulio | 0:8a4db0f083fc | 3 | // |
danjulio | 0:8a4db0f083fc | 4 | |
danjulio | 0:8a4db0f083fc | 5 | #include <swspi.h> |
danjulio | 0:8a4db0f083fc | 6 | #include "mbed.h" |
danjulio | 0:8a4db0f083fc | 7 | |
danjulio | 0:8a4db0f083fc | 8 | |
danjulio | 0:8a4db0f083fc | 9 | swspi::swspi(PinName mosiPin, PinName misoPin, PinName sckPin, PinName ss1Pin, PinName ss2Pin) |
danjulio | 0:8a4db0f083fc | 10 | { |
danjulio | 0:8a4db0f083fc | 11 | mosiP = new DigitalOut(mosiPin); |
danjulio | 0:8a4db0f083fc | 12 | misoP = new DigitalIn(misoPin); |
danjulio | 0:8a4db0f083fc | 13 | sckP = new DigitalOut(sckPin); |
danjulio | 0:8a4db0f083fc | 14 | ss1P = new DigitalOut(ss1Pin); |
danjulio | 0:8a4db0f083fc | 15 | ss2P = new DigitalOut(ss2Pin); |
danjulio | 0:8a4db0f083fc | 16 | } |
danjulio | 0:8a4db0f083fc | 17 | |
danjulio | 0:8a4db0f083fc | 18 | void swspi::init() |
danjulio | 0:8a4db0f083fc | 19 | { |
danjulio | 0:8a4db0f083fc | 20 | sckP->write(0); |
danjulio | 0:8a4db0f083fc | 21 | mosiP->write(0); |
danjulio | 0:8a4db0f083fc | 22 | ss1P->write(1); |
danjulio | 0:8a4db0f083fc | 23 | ss2P->write(1); |
danjulio | 0:8a4db0f083fc | 24 | } |
danjulio | 0:8a4db0f083fc | 25 | |
danjulio | 0:8a4db0f083fc | 26 | uint8_t swspi::spiRead(uint8_t reg, int cpha, int ss) |
danjulio | 0:8a4db0f083fc | 27 | { |
danjulio | 0:8a4db0f083fc | 28 | uint8_t val; |
danjulio | 0:8a4db0f083fc | 29 | |
danjulio | 0:8a4db0f083fc | 30 | _spi_mutex.lock(); |
danjulio | 0:8a4db0f083fc | 31 | _cpha = cpha; |
danjulio | 0:8a4db0f083fc | 32 | _ss = ss; |
danjulio | 0:8a4db0f083fc | 33 | _setSlaveSelect(0); |
danjulio | 0:8a4db0f083fc | 34 | _transfer(reg & ~SPI_WRITE_MASK); // Send the address with the write mask off |
danjulio | 0:8a4db0f083fc | 35 | val = _transfer(0); // The written value is ignored, reg value is read |
danjulio | 0:8a4db0f083fc | 36 | _setSlaveSelect(1); |
danjulio | 0:8a4db0f083fc | 37 | _spi_mutex.unlock(); |
danjulio | 0:8a4db0f083fc | 38 | |
danjulio | 0:8a4db0f083fc | 39 | return val; |
danjulio | 0:8a4db0f083fc | 40 | } |
danjulio | 0:8a4db0f083fc | 41 | |
danjulio | 0:8a4db0f083fc | 42 | uint8_t swspi::spiWrite(uint8_t reg, uint8_t val, int cpha, int ss) |
danjulio | 0:8a4db0f083fc | 43 | { |
danjulio | 0:8a4db0f083fc | 44 | uint8_t status = 0; |
danjulio | 0:8a4db0f083fc | 45 | |
danjulio | 0:8a4db0f083fc | 46 | _spi_mutex.lock(); |
danjulio | 0:8a4db0f083fc | 47 | _cpha = cpha; |
danjulio | 0:8a4db0f083fc | 48 | _ss = ss; |
danjulio | 0:8a4db0f083fc | 49 | _setSlaveSelect(0); |
danjulio | 0:8a4db0f083fc | 50 | status = _transfer(reg | SPI_WRITE_MASK); // Send the address with the write mask on |
danjulio | 0:8a4db0f083fc | 51 | _transfer(val); // New value follows |
danjulio | 0:8a4db0f083fc | 52 | _setSlaveSelect(1); |
danjulio | 0:8a4db0f083fc | 53 | _spi_mutex.unlock(); |
danjulio | 0:8a4db0f083fc | 54 | |
danjulio | 0:8a4db0f083fc | 55 | return status; |
danjulio | 0:8a4db0f083fc | 56 | } |
danjulio | 0:8a4db0f083fc | 57 | |
danjulio | 0:8a4db0f083fc | 58 | uint8_t swspi::spiBurstRead(uint8_t reg, uint8_t* dest, uint8_t len, int cpha, int ss) |
danjulio | 0:8a4db0f083fc | 59 | { |
danjulio | 0:8a4db0f083fc | 60 | uint8_t status = 0; |
danjulio | 0:8a4db0f083fc | 61 | |
danjulio | 0:8a4db0f083fc | 62 | _spi_mutex.lock(); |
danjulio | 0:8a4db0f083fc | 63 | _cpha = cpha; |
danjulio | 0:8a4db0f083fc | 64 | _ss = ss; |
danjulio | 0:8a4db0f083fc | 65 | _setSlaveSelect(0); |
danjulio | 0:8a4db0f083fc | 66 | status = _transfer(reg & ~SPI_WRITE_MASK); // Send the start address with the write mask off |
danjulio | 0:8a4db0f083fc | 67 | while (len--) |
danjulio | 0:8a4db0f083fc | 68 | *dest++ = _transfer(0); |
danjulio | 0:8a4db0f083fc | 69 | _setSlaveSelect(1); |
danjulio | 0:8a4db0f083fc | 70 | _spi_mutex.unlock(); |
danjulio | 0:8a4db0f083fc | 71 | |
danjulio | 0:8a4db0f083fc | 72 | return status; |
danjulio | 0:8a4db0f083fc | 73 | } |
danjulio | 0:8a4db0f083fc | 74 | |
danjulio | 0:8a4db0f083fc | 75 | uint8_t swspi::spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len, int cpha, int ss) |
danjulio | 0:8a4db0f083fc | 76 | { |
danjulio | 0:8a4db0f083fc | 77 | uint8_t status = 0; |
danjulio | 0:8a4db0f083fc | 78 | |
danjulio | 0:8a4db0f083fc | 79 | _spi_mutex.lock(); |
danjulio | 0:8a4db0f083fc | 80 | _cpha = cpha; |
danjulio | 0:8a4db0f083fc | 81 | _ss = ss; |
danjulio | 0:8a4db0f083fc | 82 | _setSlaveSelect(0); |
danjulio | 0:8a4db0f083fc | 83 | status = _transfer(reg | SPI_WRITE_MASK); // Send the start address with the write mask on |
danjulio | 0:8a4db0f083fc | 84 | while (len--) |
danjulio | 0:8a4db0f083fc | 85 | _transfer(*src++); |
danjulio | 0:8a4db0f083fc | 86 | _setSlaveSelect(1); |
danjulio | 0:8a4db0f083fc | 87 | _spi_mutex.unlock(); |
danjulio | 0:8a4db0f083fc | 88 | |
danjulio | 0:8a4db0f083fc | 89 | return status; |
danjulio | 0:8a4db0f083fc | 90 | } |
danjulio | 0:8a4db0f083fc | 91 | |
danjulio | 0:8a4db0f083fc | 92 | void swspi::_setSlaveSelect(int v) |
danjulio | 0:8a4db0f083fc | 93 | { |
danjulio | 0:8a4db0f083fc | 94 | if (_ss == 1) |
danjulio | 0:8a4db0f083fc | 95 | ss1P->write(v); |
danjulio | 0:8a4db0f083fc | 96 | else |
danjulio | 0:8a4db0f083fc | 97 | ss2P->write(v); |
danjulio | 0:8a4db0f083fc | 98 | } |
danjulio | 0:8a4db0f083fc | 99 | |
danjulio | 0:8a4db0f083fc | 100 | uint8_t swspi::_transfer(uint8_t v) |
danjulio | 0:8a4db0f083fc | 101 | { |
danjulio | 0:8a4db0f083fc | 102 | uint8_t reply = 0; |
danjulio | 0:8a4db0f083fc | 103 | |
danjulio | 0:8a4db0f083fc | 104 | if (_cpha == 0) { |
danjulio | 0:8a4db0f083fc | 105 | // Sample on rising clock edge |
danjulio | 0:8a4db0f083fc | 106 | for (int i=7; i>=0; i--) { |
danjulio | 0:8a4db0f083fc | 107 | reply <<= 1; |
danjulio | 0:8a4db0f083fc | 108 | mosiP->write( (v & (1<<i)) != 0 ? 1 : 0 ); |
danjulio | 0:8a4db0f083fc | 109 | sckP->write(1); |
danjulio | 0:8a4db0f083fc | 110 | if (misoP->read() == 1) reply |= 1; |
danjulio | 0:8a4db0f083fc | 111 | sckP->write(0); |
danjulio | 0:8a4db0f083fc | 112 | } |
danjulio | 0:8a4db0f083fc | 113 | } else { |
danjulio | 0:8a4db0f083fc | 114 | // Sample on falling clock edge |
danjulio | 0:8a4db0f083fc | 115 | for (int i=7; i>=0; i--) { |
danjulio | 0:8a4db0f083fc | 116 | reply <<= 1; |
danjulio | 0:8a4db0f083fc | 117 | sckP->write(1); |
danjulio | 0:8a4db0f083fc | 118 | mosiP->write( (v & (1<<i)) != 0 ? 1 : 0 ); |
danjulio | 0:8a4db0f083fc | 119 | sckP->write(0); |
danjulio | 0:8a4db0f083fc | 120 | if (misoP->read() == 1) reply |= 1; |
danjulio | 0:8a4db0f083fc | 121 | } |
danjulio | 0:8a4db0f083fc | 122 | } |
danjulio | 0:8a4db0f083fc | 123 | |
danjulio | 0:8a4db0f083fc | 124 | return reply; |
danjulio | 0:8a4db0f083fc | 125 | } |