Ultra fast and direct SPI library for some STM32 micros.

Dependents:   DirectSPI-test wave_player_super_lite

DirectSPI.cpp

Committer:
mimi3
Date:
2017-02-23
Revision:
1:576dbeb04958
Child:
2:1faa28f1a5bb

File content as of revision 1:576dbeb04958:

#include "DirectSPI.h"

#define isTXE(spi)     (spi->SR & SPI_SR_TXE)
#define isRXNE(spi)    (spi->SR & SPI_SR_RXNE)
#define SPIBUF8(spi)   *(__IO uint8_t  *)&spi->DR
#define SPIBUF16(spi)  spi->DR

#if DEVICE_SPI_ASYNCH
    #define SPI_S(obj)    (( struct spi_s *)(obj))
    //#define SPI_S(obj)    (( struct spi_s *)(&(obj->spi)))
#else
    #define SPI_S(obj)    (( struct spi_s *)(obj))
#endif

DirectSPI::DirectSPI(PinName mosi, PinName miso, PinName sclk) : SPI(mosi, miso, sclk) {
    spi = spi_get_id(mosi, miso, sclk, NC);
#if TODO
    struct spi_s *spiobj = SPI_S(spi);
    SPI_HandleTypeDef *handle = &(spiobj->handle);
    is16bit = (handle->Init.DataSize == SPI_DATASIZE_16BIT);
    spiSend = is16bit ? &DirectSPI::spiSend16 : &DirectSPI::spiSend8;
#endif
}

#if TODO
uint16_t DirectSPI::directWrite(uint16_t data) {
    if(is16bit){
        while(!isTXE(spi));
        SPIBUF16(spi) = data;
        while(!isRXNE(spi));
        return SPIBUF16(spi);
    } else {
        while(!isTXE(spi));
        SPIBUF8(spi) = data;
        while(!isRXNE(spi));
        return SPIBUF8(spi);
    }
}
#endif

uint16_t DirectSPI::directWrite8(uint16_t data) {
    while(!isTXE(spi));
    SPIBUF8(spi) = data;
    while(!isRXNE(spi));
    return SPIBUF8(spi);
}

uint16_t DirectSPI::directWrite16(uint16_t data) {
    while(!isTXE(spi));
    SPIBUF16(spi) = data;
    while(!isRXNE(spi));
    return SPIBUF16(spi);
}

SPI_TypeDef *DirectSPI::spi_get_id( PinName mosi, PinName miso, PinName sclk, PinName ssel) {
    // Determine the SPI to use
    SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
    SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
    SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
    SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);

    SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
    SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);

    return (SPI_TypeDef *) ( (SPIName)pinmap_merge(spi_data, spi_cntl) );
}