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.

Dependents:   Rocket

swspi.cpp

Committer:
danjulio
Date:
2017-06-11
Revision:
0:8a4db0f083fc

File content as of revision 0:8a4db0f083fc:

// Software (bit-banged) SPI Module supporting two modes.
// Each mode consists of a CS and CPHA mode 
//

#include <swspi.h>
#include "mbed.h"


swspi::swspi(PinName mosiPin, PinName misoPin, PinName sckPin, PinName ss1Pin, PinName ss2Pin)
{
    mosiP = new DigitalOut(mosiPin);
    misoP = new DigitalIn(misoPin);
    sckP = new DigitalOut(sckPin);
    ss1P = new DigitalOut(ss1Pin);
    ss2P = new DigitalOut(ss2Pin);
}

void swspi::init()
{
    sckP->write(0);
    mosiP->write(0);
    ss1P->write(1);
    ss2P->write(1);
}

uint8_t swspi::spiRead(uint8_t reg, int cpha, int ss)
{
    uint8_t val;
    
    _spi_mutex.lock();
    _cpha = cpha;
    _ss = ss;
    _setSlaveSelect(0);
    _transfer(reg & ~SPI_WRITE_MASK); // Send the address with the write mask off
    val = _transfer(0); // The written value is ignored, reg value is read
    _setSlaveSelect(1);
    _spi_mutex.unlock();
    
    return val;
}

uint8_t swspi::spiWrite(uint8_t reg, uint8_t val, int cpha, int ss)
{
    uint8_t status = 0;
    
    _spi_mutex.lock();
    _cpha = cpha;
    _ss = ss;
    _setSlaveSelect(0);
    status = _transfer(reg | SPI_WRITE_MASK); // Send the address with the write mask on
    _transfer(val); // New value follows
    _setSlaveSelect(1);
    _spi_mutex.unlock();
    
    return status;
}

uint8_t swspi::spiBurstRead(uint8_t reg, uint8_t* dest, uint8_t len, int cpha, int ss)
{
    uint8_t status = 0;
    
    _spi_mutex.lock();
    _cpha = cpha;
    _ss = ss;
    _setSlaveSelect(0);
    status = _transfer(reg & ~SPI_WRITE_MASK); // Send the start address with the write mask off
    while (len--)
        *dest++ = _transfer(0);
    _setSlaveSelect(1);
    _spi_mutex.unlock();
    
    return status;
}

uint8_t swspi::spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len, int cpha, int ss)
{
    uint8_t status = 0;
    
    _spi_mutex.lock();
    _cpha = cpha;
    _ss = ss;
    _setSlaveSelect(0);
    status = _transfer(reg | SPI_WRITE_MASK); // Send the start address with the write mask on
    while (len--)
        _transfer(*src++);
    _setSlaveSelect(1);
    _spi_mutex.unlock();
    
    return status;
}

void swspi::_setSlaveSelect(int v)
{
    if (_ss == 1)
      ss1P->write(v);
    else
      ss2P->write(v);
}

uint8_t swspi::_transfer(uint8_t v)
{
    uint8_t reply = 0;

    if (_cpha == 0) {
        // Sample on rising clock edge
        for (int i=7; i>=0; i--) {
            reply <<= 1;
            mosiP->write( (v & (1<<i)) != 0 ? 1 : 0 );
            sckP->write(1);
            if (misoP->read() == 1) reply |= 1;
            sckP->write(0);
        }
    } else {
        // Sample on falling clock edge
        for (int i=7; i>=0; i--) {
            reply <<= 1;
            sckP->write(1);
            mosiP->write( (v & (1<<i)) != 0 ? 1 : 0 );
            sckP->write(0);
            if (misoP->read() == 1) reply |= 1;
        }
    }

    return reply;
}