diff options
Diffstat (limited to 'core/comm')
| -rw-r--r-- | core/comm/HardwareSPI.cpp | 138 | ||||
| -rw-r--r-- | core/comm/HardwareSPI.h | 57 | 
2 files changed, 195 insertions, 0 deletions
| diff --git a/core/comm/HardwareSPI.cpp b/core/comm/HardwareSPI.cpp new file mode 100644 index 0000000..51093cb --- /dev/null +++ b/core/comm/HardwareSPI.cpp @@ -0,0 +1,138 @@ +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @brief HardwareSPI "wiring-like" api for SPI + */ + +/* NOTES: + * + * Speeds: + * ----------------------------------- + * Interface num:     SPI1        SPI2 + * Bus                APB2        APB1 + * ----------------------------------- + * Prescaler         Frequencies + * ----------------------------------- + * 2:                  N/A  18 000 000 + * 4:           18 000 000   9 000 000 + * 8:            9 000 000   4 500 000 + * 16:           4 500 000   2 250 000 + * 32:           2 250 000   1 125 000 + * 64:           1 125 000     562 500 + * 128:            562 500     281 250 + * 256:            281 250     140 625 + * + * TODO: Do the complementary PWM outputs mess up SPI2? + * */ + +#include "wiring.h" +#include "spi.h" +#include "HardwareSPI.h" + +static const uint32 prescaleFactors[MAX_SPI_FREQS] = { +   SPI_PRESCALE_2,               // SPI_18MHZ +   SPI_PRESCALE_4,               // SPI_9MHZ +   SPI_PRESCALE_8,               // SPI_4_5MHZ +   SPI_PRESCALE_16,              // SPI_2_25MHZ +   SPI_PRESCALE_32,              // SPI_1_125MHZ +   SPI_PRESCALE_64,              // SPI_562_500KHZ +   SPI_PRESCALE_128,             // SPI_281_250KHZ +   SPI_PRESCALE_256,             // SPI_140_625KHZ +}; + +/** + * @brief Initialize a SPI peripheral + * @param freq frequency to run at, must one of the following values: + *           - SPI_18MHZ + *           - SPI_9MHZ + *           - SPI_4_5MHZ + *           - SPI_2_25MHZ + *           - SPI_1_125MHZ + *           - SPI_562_500KHZ + *           - SPI_281_250KHZ + *           - SPI_140_625KHZ + * @param endianness endianness of the data frame, must be either LSBFIRST + *           or MSBFIRST + * @param mode SPI standard CPOL and CPHA levels + */ +void HardwareSPI::begin(SPIFrequency freq, uint32 endianness, uint32 mode) { +   uint32 spi_num    = this->spi_num; +   uint32 high_speed = 0; +   uint32 index; +   uint32 prescale; + +   if ((freq >= MAX_SPI_FREQS)     || +       !((endianness == LSBFIRST)  || +         (endianness == MSBFIRST)) || +       (mode >= 4)) { +      return; +   } + +   if (spi_num == 1) { +      /* SPI1 is too fast for 140625  */ +      if (freq == SPI_140_625KHZ) { +         return; +      } + +      /* Turn off PWM on shared pins */ +      timers_disable_channel(3, 2); +      timers_disable_channel(3, 1); +   } + +   endianness = (endianness == LSBFIRST) ? SPI_LSBFIRST : SPI_MSBFIRST; +   prescale = (spi_num == 1) ? prescaleFactors[freq + 1] : prescaleFactors[freq]; + +   spi_init(spi_num, prescale, endianness, 0); +} + +/** + * @brief Initialize a SPI peripheral with a default speed of 1.125 MHZ, MSBFIRST, + *      mode 0 + * @param mode SPI standard CPOL and CPHA levels + */ +void HardwareSPI::begin(void) { +   begin(SPI_1_125MHZ, MSBFIRST, 0); +} + +/** + * @brief send a byte out the spi peripheral + * @param data byte to send + */ +void HardwareSPI::send(uint8 data) { +   spi_tx(this->spi_num, data); +} + + +/** + * @brief read a byte from the spi peripheral + * @return byte in the buffer + */ +uint8 HardwareSPI::recv(void) { +   return spi_rx(this->spi_num); +} + +HardwareSPI::HardwareSPI(uint32 spi_num) { +   this->spi_num = spi_num; +} diff --git a/core/comm/HardwareSPI.h b/core/comm/HardwareSPI.h new file mode 100644 index 0000000..b974334 --- /dev/null +++ b/core/comm/HardwareSPI.h @@ -0,0 +1,57 @@ +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + +/** + * @brief HardwareSPI definitions + */ + +#ifndef _HARDWARESPI_H_ +#define _HARDWARESPI_H_ + +typedef enum SPIFrequency { +   SPI_18MHZ       = 0, +   SPI_9MHZ        = 1, +   SPI_4_5MHZ      = 2, +   SPI_2_25MHZ     = 3, +   SPI_1_125MHZ    = 4, +   SPI_562_500KHZ  = 5, +   SPI_281_250KHZ  = 6, +   SPI_140_625KHZ  = 7, +   MAX_SPI_FREQS   = 8, +} SPIFrequency; + +class HardwareSPI { +   private: +      uint32 spi_num; + +   public: +      HardwareSPI(uint32 spi_num); +      void begin(void); +      void begin(SPIFrequency freq, uint32 endianness, uint32 mode); +      void send(uint8 data); +      uint8 recv(void); +}; + +#endif + | 
