Generic mbed Extensions used by STM Expansion Board Firmware Packages.

Dependents:   X_NUCLEO_IKS01A1 X_NUCLEO_6180XA1 1-DoorCloser 1-DoorCloser ... more

Fork of X_NUCLEO_COMMON by ST Expansion SW Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DevSPI.h Source File

DevSPI.h

Go to the documentation of this file.
00001 /**
00002  ******************************************************************************
00003  * @file    DevSPI.h
00004  * @author  AST / Software Platforms and Cloud / EST
00005  * @version V1.2.1
00006  * @date    19-February-2016
00007  * @brief   Header file for a special SPI class DevSPI which provides some
00008  *          helper functions for on-board communication.
00009  ******************************************************************************
00010  * @attention
00011  *
00012  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00013  *
00014  * Redistribution and use in source and binary forms, with or without modification,
00015  * are permitted provided that the following conditions are met:
00016  *   1. Redistributions of source code must retain the above copyright notice,
00017  *      this list of conditions and the following disclaimer.
00018  *   2. Redistributions in binary form must reproduce the above copyright notice,
00019  *      this list of conditions and the following disclaimer in the documentation
00020  *      and/or other materials provided with the distribution.
00021  *   3. Neither the name of STMicroelectronics nor the names of its contributors
00022  *      may be used to endorse or promote products derived from this software
00023  *      without specific prior written permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00028  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00029  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00033  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  ******************************************************************************
00037  */
00038 
00039 /* Define to prevent from recursive inclusion --------------------------------*/
00040 #ifndef __DEV_SPI_H
00041 #define __DEV_SPI_H
00042 
00043 /* Includes ------------------------------------------------------------------*/
00044 #include "mbed.h"
00045 
00046 /* Macros --------------------------------------------------------------------*/
00047 #if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) /* GCC */ || \
00048     (defined(G_BYTE_ORDER) && (G_BYTE_ORDER == G_BIG_ENDIAN)) /* IAR */ || \
00049     (defined(__BIG_ENDIAN)) /* ARM */
00050 #define __DEV_SPI_BIG_ENDIAN
00051 #endif
00052 
00053 /* Classes -------------------------------------------------------------------*/
00054 /** Helper class DevSPI providing functions for synchronous SPI communication
00055  *  common for a series of SPI devices.
00056  */
00057 class DevSPI : public SPI
00058 {
00059  public:
00060     /*
00061      * Create a DevSPI interface.
00062      * @param mosi pin name of the MOSI pin of the SPI device to be used for communication.
00063      * @param miso pin name of the MISO pin of the SPI device to be used for communication.
00064      * @param sclk pin name of the SCLK pin of the SPI device to be used for communication.
00065      */
00066     DevSPI(PinName mosi, PinName miso, PinName sclk) : SPI(mosi, miso, sclk)
00067     {
00068         /* Set default configuration. */
00069         setup(8, 3, 1E6);
00070     }
00071 
00072     /*
00073      * Setup the spi.
00074      * Typically:
00075      *  + 8 bit data;
00076      *  + high steady state clock;
00077      *  + second edge capture;
00078      *  + 1MHz clock rate.
00079      *
00080      * @param bits         Number of bits per SPI frame (4 - 16)
00081      * @param mode         Clock polarity and phase mode (0 - 3)
00082      * @param frequency_hz SCLK frequency in hz (default = 1MHz)
00083      *
00084      * @code
00085      * mode | POL PHA
00086      * -----+--------
00087      *   0  |  0   0
00088      *   1  |  0   1
00089      *   2  |  1   0
00090      *   3  |  1   1
00091      * @endcode
00092      */
00093     void setup(int bits, int mode = 0, int frequency_hz = 1E6)
00094     {
00095         /* Set given configuration. */
00096         format(bits, mode);
00097         frequency(frequency_hz);
00098     }
00099 
00100     /**
00101      * @brief      Writes a buffer to the SPI peripheral device in 8-bit data mode 
00102      *             using synchronous SPI communication.
00103      * @param[in]  pBuffer pointer to the buffer of data to send.
00104      * @param[in]  ssel GPIO of the SSEL pin of the SPI device to be used for communication.
00105      * @param[in]  NumBytesToWrite number of bytes to write.
00106      * @retval     0 if ok.
00107      * @retval     -1 if data format error.
00108      * @note       When using the SPI in Interrupt-mode, remember to disable interrupts
00109      *             before calling this function and to enable them again after.
00110      */
00111     int spi_write(uint8_t* pBuffer, DigitalOut &ssel, uint16_t NumBytesToWrite)
00112     {
00113     /* Check data format */
00114     if(_bits != 8) return -1;
00115 
00116         /* Select the chip. */
00117         ssel = 0;
00118         
00119         /* Write data. */
00120     for (int i = 0; i < NumBytesToWrite; i++) {
00121             write(pBuffer[i]);
00122     }
00123 
00124         /* Unselect the chip. */
00125         ssel = 1;
00126 
00127         return 0;
00128     }
00129 
00130     /**
00131      * @brief      Reads a buffer from the SPI peripheral device in 8-bit data mode 
00132      *             using synchronous SPI communication.
00133      * @param[out] pBuffer pointer to the buffer to read data into.
00134      * @param[in]  ssel GPIO of the SSEL pin of the SPI device to be used for communication.
00135      * @param[in]  NumBytesToRead number of bytes to read.
00136      * @retval     0 if ok.
00137      * @retval     -1 if data format error.
00138      * @note       When using the SPI in Interrupt-mode, remember to disable interrupts
00139      *             before calling this function and to enable them again after.
00140      */
00141     int spi_read(uint8_t* pBuffer, DigitalOut &ssel, uint16_t NumBytesToRead)
00142     {
00143     /* Check data format */
00144     if(_bits != 8) return -1;
00145 
00146         /* Select the chip. */
00147         ssel = 0;
00148         
00149         /* Read data. */
00150     for (int i = 0; i < NumBytesToRead; i++) {
00151         pBuffer[i] = write(0);
00152     }
00153 
00154         /* Unselect the chip. */
00155         ssel = 1;
00156 
00157         return 0;
00158     }
00159 
00160     /**
00161      * @brief      Reads and write a buffer from/to the SPI peripheral device at the same time 
00162      *             in 8-bit data mode using synchronous SPI communication.
00163      * @param[out] pBufferToRead pointer to the buffer to read data into.
00164      * @param[in]  pBufferToWrite pointer to the buffer of data to send.
00165      * @param[in]  ssel GPIO of the SSEL pin of the SPI device to be used for communication.
00166      * @param[in]  NumBytes number of bytes to read and write.
00167      * @retval     0 if ok.
00168      * @retval     -1 if data format error.
00169      * @note       When using the SPI in Interrupt-mode, remember to disable interrupts
00170      *             before calling this function and to enable them again after.
00171      */
00172     int spi_read_write(uint8_t* pBufferToRead, uint8_t* pBufferToWrite, DigitalOut &ssel, uint16_t NumBytes)
00173     {
00174     /* Check data format */
00175     if(_bits != 8) return -1;
00176 
00177         /* Select the chip. */
00178         ssel = 0;
00179         
00180         /* Read and write data at the same time. */
00181     for (int i = 0; i < NumBytes; i++) {
00182             pBufferToRead[i] = write(pBufferToWrite[i]);
00183     }
00184 
00185         /* Unselect the chip. */
00186         ssel = 1;
00187 
00188         return 0;
00189     }
00190 
00191     /**
00192      * @brief      Writes a buffer to the SPI peripheral device in 16-bit data mode 
00193      *             using synchronous SPI communication.
00194      * @param[in]  pBuffer pointer to the buffer of data to send.
00195      * @param[in]  ssel GPIO of the SSEL pin of the SPI device to be used for communication.
00196      * @param[in]  NumValuesToWrite number of 16-bit values to write.
00197      * @retval     0 if ok.
00198      * @retval     -1 if data format error.
00199      * @note       When using the SPI in Interrupt-mode, remember to disable interrupts
00200      *             before calling this function and to enable them again after.
00201      * @note       In order to guarantee this method to work correctly you have to
00202      *             pass buffers which are correctly aligned.
00203      */
00204     int spi_write(uint16_t* pBuffer, DigitalOut &ssel, uint16_t NumValuesToWrite)
00205     {
00206     /* Check data format */
00207     if(_bits != 16) return -1;
00208 
00209         /* Select the chip. */
00210         ssel = 0;
00211         
00212         /* Write data. */
00213     for (int i = 0; i < NumValuesToWrite; i++) {
00214         write(htons(pBuffer[i]));
00215     }
00216 
00217         /* Unselect the chip. */
00218         ssel = 1;
00219 
00220         return 0;
00221     }
00222 
00223     /**
00224      * @brief      Reads a buffer from the SPI peripheral device in 16-bit data mode 
00225      *             using synchronous SPI communication.
00226      * @param[out] pBuffer pointer to the buffer to read data into.
00227      * @param[in]  ssel GPIO of the SSEL pin of the SPI device to be used for communication.
00228      * @param[in]  NumValuesToRead number of 16-bit values to read.
00229      * @retval     0 if ok.
00230      * @retval     -1 if data format error.
00231      * @note       When using the SPI in Interrupt-mode, remember to disable interrupts
00232      *             before calling this function and to enable them again after.
00233      * @note       In order to guarantee this method to work correctly you have to
00234      *             pass buffers which are correctly aligned.
00235      */
00236     int spi_read(uint16_t* pBuffer, DigitalOut &ssel, uint16_t NumValuesToRead)
00237     {
00238     /* Check data format */
00239     if(_bits != 16) return -1;
00240 
00241         /* Select the chip. */
00242         ssel = 0;
00243         
00244         /* Read data. */
00245     for (int i = 0; i < NumValuesToRead; i++) {
00246         pBuffer[i] = ntohs((uint16_t)write(0));
00247     }
00248 
00249         /* Unselect the chip. */
00250         ssel = 1;
00251 
00252         return 0;
00253     }
00254 
00255     /**
00256      * @brief      Reads and write a buffer from/to the SPI peripheral device at the same time 
00257      *             in 16-bit data mode using synchronous SPI communication.
00258      * @param[out] pBufferToRead pointer to the buffer to read data into.
00259      * @param[in]  pBufferToWrite pointer to the buffer of data to send.
00260      * @param[in]  ssel GPIO of the SSEL pin of the SPI device to be used for communication.
00261      * @param[in]  NumValues number of 16-bit values to read and write.
00262      * @retval     0 if ok.
00263      * @retval     -1 if data format error.
00264      * @note       When using the SPI in Interrupt-mode, remember to disable interrupts
00265      *             before calling this function and to enable them again after.
00266      * @note       In order to guarantee this method to work correctly you have to
00267      *             pass buffers which are correctly aligned.
00268      */
00269     int spi_read_write(uint16_t* pBufferToRead, uint16_t* pBufferToWrite, DigitalOut &ssel, uint16_t NumValues)
00270     {
00271     /* Check data format */
00272     if(_bits != 16) return -1;
00273 
00274     /* Select the chip. */
00275         ssel = 0;
00276         
00277         /* Read and write data at the same time. */
00278     for (int i = 0; i < NumValues; i++) {
00279         pBufferToRead[i] = ntohs((uint16_t)write(htons(pBufferToWrite[i])));
00280     }
00281 
00282         /* Unselect the chip. */
00283         ssel = 1;
00284 
00285         return 0;
00286     }
00287 
00288 protected:
00289     inline uint16_t htons(uint16_t x) {
00290 #ifndef __DEV_SPI_BIG_ENDIAN
00291     return (((x)<<8)|((x)>>8));
00292 #else  // __DEV_SPI_BIG_ENDIAN
00293     return (x);
00294 #endif // __DEV_SPI_BIG_ENDIAN
00295     }
00296 
00297     inline uint16_t ntohs(uint16_t x) {
00298     return htons(x);
00299     }
00300 };
00301 
00302 #endif /* __DEV_SPI_H */