LT_SPI
Revision 0:516e11acba42, committed 2017-11-12
- Comitter:
- roger5641
- Date:
- Sun Nov 12 01:21:36 2017 +0000
- Commit message:
- ver1
Changed in this revision
LT_SPI.cpp | Show annotated file Show diff for this revision Revisions of this file |
LT_SPI.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 516e11acba42 LT_SPI.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LT_SPI.cpp Sun Nov 12 01:21:36 2017 +0000 @@ -0,0 +1,310 @@ +//! @todo Review this document. +/*! +LT_SPI: Routines to communicate with ATmega328P's hardware SPI port. + +@verbatim + +LT_SPI implements the low level master SPI bus routines using +the hardware SPI port. + +SPI Frequency = (CPU Clock frequency)/(16+2(TWBR)*Prescaler) +SPCR = SPI Control Register (SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0) +SPSR = SPI Status Register (SPIF WCOL - - - - - SPI2X) + +Data Modes: +CPOL CPHA Leading Edge Trailing Edge +0 0 sample rising setup falling +0 1 setup rising sample falling +1 0 sample falling setup rising +1 1 sample rising setup rising + +CPU Frequency = 16MHz on Arduino Uno +SCK Frequency +SPI2X SPR1 SPR0 Frequency Uno_Frequency + 0 0 0 fosc/4 4 MHz + 0 0 1 fosc/16 1 MHz + 0 1 0 fosc/64 250 kHz + 0 1 1 fosc/128 125 kHz + 0 0 0 fosc/2 8 MHz + 0 0 1 fosc/8 2 MHz + 0 1 0 fosc/32 500 kHz + +@endverbatim + +REVISION HISTORY +$Revision: 6237 $ +$Date: 2016-12-20 15:09:16 -0800 (Tue, 20 Dec 2016) $ + +Copyright (c) 2013, Linear Technology Corp.(LTC) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of Linear Technology Corp. + +The Linear Technology Linduino is not affiliated with the official Arduino team. +However, the Linduino is only possible because of the Arduino team's commitment +to the open-source community. Please, visit http://www.arduino.cc and +http://store.arduino.cc , and consider a purchase that will help fund their +ongoing work. +*/ + +//! @ingroup Linduino +//! @{ +//! @defgroup LT_SPI LT_SPI: Routines to communicate with ATmega328P's hardware SPI port. +//! @} + +/*! @file + @ingroup LT_SPI + Library for LT_SPI: Routines to communicate with ATmega328P's hardware SPI port. +*/ +#include <stdint.h> +#include "LT_SPI.h" + +//DigitalOut QUIKEVAL_GPIO D9; //!< Linduino QuikEval GPIO pin (QuikEval connector pin 14) connects to Arduino pin 9 +//DigitalOut QUIKEVAL_CS A3; //!< QuikEval CS pin (SPI chip select on QuikEval connector pin 6) connects to Arduino SS pin. +//DigitalInOut QUIKEVAL_MUX_MODE_PIN(8,output); /*!< QUIKEVAL_MUX_MODE_PIN defines the control pin for the QuikEval MUX. +//The I2C port's SCL and the SPI port's SCK signals share the same pin on the Linduino's QuikEval connector. +//Additionally, the I2C port's SDA and the SPI port's MOSI signals share the same pin on the Linduino's QuikEval connector. +//The pair of pins connected to the QuikEval connector is switched using a MUX on the Linduino board. +//The control pin to switch the MUX is defined as QUIKEVAL_MUX_MODE_PIN (Arduino pin 8). */ + +void output_low(uint8_t pin) +{ + pin = 0; +} +void output_high(uint8_t pin) +{ + pin = 1; +} + + +// Reads and sends a byte +// Return 0 if successful, 1 if failed +void spi_transfer_byte(uint8_t cs_pin, uint8_t tx, uint8_t *rx) +{ + output_low(cs_pin); //! 1) Pull CS low + + *rx = spi.write(tx); //! 2) Read byte and send byte + + output_high(cs_pin); //! 3) Pull CS high +} + +// Reads and sends a word +// Return 0 if successful, 1 if failed +void spi_transfer_word(uint8_t cs_pin, uint16_t tx, uint16_t *rx) +{ + union + { + uint8_t b[2]; + uint16_t w; + } data_tx; + + union + { + uint8_t b[2]; + uint16_t w; + } data_rx; + + data_tx.w = tx; + + output_low(cs_pin); //! 1) Pull CS low + + data_rx.b[1] = spi.write(data_tx.b[1]); //! 2) Read MSB and send MSB + data_rx.b[0] = spi.write(data_tx.b[0]); //! 3) Read LSB and send LSB + + *rx = data_rx.w; + + output_high(cs_pin); //! 4) Pull CS high +} + +// Reads and sends a byte array +void spi_transfer_block(uint8_t cs_pin, uint8_t *tx, uint8_t *rx, uint8_t length) +{ + int8_t i; + + output_low(cs_pin); //! 1) Pull CS low + + for (i=(length-1); i >= 0; i--) + rx[i] = spi.write(tx[i]); //! 2) Read and send byte array + + output_high(cs_pin); //! 3) Pull CS high +} + +// Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C. +//void quikeval_SPI_connect() +//{ +// output_high(QUIKEVAL_CS); //! 1) Pull Chip Select High +// +// //! 2) Enable Main SPI +// pinMode(QUIKEVAL_MUX_MODE_PIN, OUTPUT); +// QUIKEVAL_MUX_MODE_PIN = 0; +//} + +// Configure the SPI port for 4MHz SCK. +// This function or spi_enable() must be called +// before using the other SPI routines. +//void quikeval_SPI_init(void) // Initializes SPI +//{ +// spi_enable(SPI_CLOCK_DIV16); //! 1) Configure the spi port for 4MHz SCK +//} + +// Setup the processor for hardware SPI communication. +// Must be called before using the other SPI routines. +// Alternatively, call quikeval_SPI_connect(), which automatically +// calls this function. +void spi_enable(void) // Configures SCK frequency. Use constant defined in header file. +{ + //pinMode(SCK, OUTPUT); //! 1) Setup SCK as output + //pinMode(MOSI, OUTPUT); //! 2) Setup MOSI as output + //pinMode(QUIKEVAL_CS, OUTPUT); //! 3) Setup CS as output + spi.format(16,3); + spi.frequency(1000000); +} + +// Disable the SPI hardware port +//void spi_disable() +//{ +// spi.end(); +//} + +// Write a data byte using the SPI hardware +//void spi_write(int8_t data) // Byte to be written to SPI port +//{ +// SPDR = data; //! 1) Start the SPI transfer +// while (!(SPSR & _BV(SPIF))); //! 2) Wait until transfer complete +//} + +// Read and write a data byte using the SPI hardware +// Returns the data byte read +//int8_t spi_read(int8_t data) //!The data byte to be written +//{ +// SPDR = data; //! 1) Start the SPI transfer +// while (!(SPSR & _BV(SPIF))); //! 2) Wait until transfer complete +// return SPDR; //! 3) Return the data read +//} + +// Below are implementations of spi_read, etc. that do not use the +// Arduino SPI library. To use these functions, uncomment them and comment out +// the correcsponding function above. +// +// // Reads and sends a byte +// // Return 0 if successful, 1 if failed +// uint8_t spi_transfer_byte(uint8_t cs_pin, uint8_t tx, uint8_t *rx) +// { +// output_low(cs_pin); //! 1) Pull CS low +// +// *rx = spi_read(tx); //! 2) Read byte and send byte +// +// output_high(cs_pin); //! 3) Pull CS high +// +// return(0); +// } +// +// // Reads and sends a word +// // Return 0 if successful, 1 if failed +// uint8_t spi_transfer_word(uint8_t cs_pin, uint16_t tx, uint16_t *rx) +// { +// union +// { +// uint8_t b[2]; +// uint16_t w; +// } data_tx; +// +// union +// { +// uint8_t b[2]; +// uint16_t w; +// } data_rx; +// +// data_tx.w = tx; +// +// output_low(cs_pin); //! 1) Pull CS low +// +// data_rx.b[1] = spi_read(data_tx.b[1]); //! 2) Read MSB and send MSB +// data_rx.b[0] = spi_read(data_tx.b[0]); //! 3) Read LSB and send LSB +// *rx = data_rx.w; +// +// output_high(cs_pin); //! 4) Pull CS high +// +// return(0); +// } +// +// // Reads and sends a byte array +// // Return 0 if successful, 1 if failed +// uint8_t spi_transfer_block(uint8_t cs_pin, uint8_t *tx, uint8_t *rx, uint8_t length) +// { +// int8_t i; +// +// output_low(cs_pin); //! 1) Pull CS low +// +// for(i=0; i < length; i++) +// rx[i] = spi_read(tx[i]); //! 2) Read and send byte array +// +// output_high(cs_pin); //! 3) Pull CS high +// +// return(0); +// } +// +// // Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C. +// void quikeval_SPI_connect() +// { +// output_high(QUIKEVAL_CS); //! 1) Pull Chip Select High +// +// //! 2) Enable Main SPI +// pinMode(QUIKEVAL_MUX_MODE_PIN, OUTPUT); +// digitalWrite(QUIKEVAL_MUX_MODE_PIN, LOW); +// } +// +// // Configure the SPI port for 4MHz SCK. +// // This function or spi_enable() must be called +// // before using the other SPI routines. +// void quikeval_SPI_init(void) // Initializes SPI +// { +// spi_enable(SPI_CLOCK_DIV32); //! 2) Configure the spi port for 4MHz SCK +// } +// +// // Setup the processor for hardware SPI communication. +// // Must be called before using the other SPI routines. +// // Alternatively, call quikeval_SPI_connect(), which automatically +// // calls this function. +// void spi_enable(uint8_t spi_clock_divider) // Configures SCK frequency. Use constant defined in header file. +// { +// pinMode(SCK, OUTPUT); //! 1) Setup SCK as output +// pinMode(MOSI, OUTPUT); //! 2) Setup MOSI as output +// pinMode(QUIKEVAL_CS, OUTPUT); //! 3) Setup CS as output +// output_low(SCK); +// output_low(MOSI); +// output_high(QUIKEVAL_CS); +// SPCR |= _BV(MSTR); //! 4) Set the SPI port to master mode +// //! 5) Set the SPI hardware rate +// SPCR = (SPCR & ~SPI_CLOCK_MASK) | (spi_clock_divider & SPI_CLOCK_MASK); +// SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((spi_clock_divider >> 2) & SPI_2XCLOCK_MASK); +// SPCR |= _BV(SPE); //! 5) Enable the SPI port +// } +// +// // Disable the SPI hardware port +// void spi_disable() +// { +// SPCR &= ~_BV(SPE); +// } \ No newline at end of file
diff -r 000000000000 -r 516e11acba42 LT_SPI.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LT_SPI.h Sun Nov 12 01:21:36 2017 +0000 @@ -0,0 +1,131 @@ +//! @todo Review this document. +/*! +LT_SPI: Routines to communicate with ATmega328P's hardware SPI port. + +REVISION HISTORY +$Revision: 3659 $ +$Date: 2015-07-01 10:19:20 -0700 (Wed, 01 Jul 2015) $ + +Copyright (c) 2013, Linear Technology Corp.(LTC) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of Linear Technology Corp. + +The Linear Technology Linduino is not affiliated with the official Arduino team. +However, the Linduino is only possible because of the Arduino team's commitment +to the open-source community. Please, visit http://www.arduino.cc and +http://store.arduino.cc , and consider a purchase that will help fund their +ongoing work. +*/ + +/*! @file + @ingroup LT_SPI + Library Header File for LT_SPI: Routines to communicate with ATmega328P's hardware SPI port. +*/ + +#ifndef LT_SPI_H +#define LT_SPI_H + +#include "mbed.h" + +SPI spi(A6,A5,A4,A3); +// Uncomment the following to use functions that implement LTC SPI routines + +// //! @name SPI CLOCK DIVIDER CONSTANTS +// //! @{ +// #define SPI_CLOCK_DIV4 0x00 // 4 Mhz +// #define SPI_CLOCK_DIV16 0x01 // 1 Mhz +// #define SPI_CLOCK_DIV64 0x02 // 250 khz +// #define SPI_CLOCK_DIV128 0x03 // 125 khz +// #define SPI_CLOCK_DIV2 0x04 // 8 Mhz +// #define SPI_CLOCK_DIV8 0x05 // 2 Mhz +// #define SPI_CLOCK_DIV32 0x06 // 500 khz +// //! @} +// +// //! @name SPI HARDWARE MODE CONSTANTS +// //! @{ +// #define SPI_MODE0 0x00 +// #define SPI_MODE1 0x04 +// // #define SPI_MODE2 0x08 +// #define SPI_MODE3 0x0C +// //! @} +// +// //! @name SPI SET MASKS +//! @{ +// #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR +// #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR +// #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR +// //! @} + +//! Reads and sends a byte +//! @return void +void spi_transfer_byte(uint8_t cs_pin, //!< Chip select pin + uint8_t tx, //!< Byte to be transmitted + uint8_t *rx //!< Byte to be received + ); + +//! Reads and sends a word +//! @return void +void spi_transfer_word(uint8_t cs_pin, //!< Chip select pin + uint16_t tx, //!< Byte to be transmitted + uint16_t *rx //!< Byte to be received + ); + +//! Reads and sends a byte array +//! @return void +void spi_transfer_block(uint8_t cs_pin, //!< Chip select pin + uint8_t *tx, //!< Byte array to be transmitted + uint8_t *rx, //!< Byte array to be received + uint8_t length //!< Length of array + ); + +//! Connect SPI pins to QuikEval connector through the Linduino MUX. This will disconnect I2C. +//void quikeval_SPI_connect(); + +//! Configure the SPI port for 4Mhz SCK. +//! This function or spi_enable() must be called +//! before using the other SPI routines. +//void quikeval_SPI_init(); + +//! Setup the processor for hardware SPI communication. +//! Must be called before using the other SPI routines. +//! Alternatively, call quikeval_SPI_connect(), which automatically +//! calls this function. +void spi_enable(void); //!< Configures SCK frequency. Use constant defined in header file. + + +//! Disable the SPI hardware port +//void spi_disable(); + +//! Write a data byte using the SPI hardware +//void spi_write(int8_t data //!< Byte to be written to SPI port +// ); + +//! Read and write a data byte using the SPI hardware +//! @return the data byte read +//int8_t spi_read(int8_t data //!< The data byte to be written +// ); + +#endif // LT_SPI_H \ No newline at end of file