136 lines
4.5 KiB
C++
136 lines
4.5 KiB
C++
/*
|
|
* Copyright (c) 2010 by Cristian Maglie <c.maglie@arduino.cc>
|
|
* Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
|
|
* Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
|
|
* Copyright (c) 2014 by Andrew J. Kroll <xxxajk@gmail.com> (atomicity fixes)
|
|
* SPI Master library for arduino.
|
|
*
|
|
* This file is free software; you can redistribute it and/or modify
|
|
* it under the terms of either the GNU General Public License version 2
|
|
* or the GNU Lesser General Public License version 2.1, both as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#ifndef _SPI_H_INCLUDED
|
|
#define _SPI_H_INCLUDED
|
|
|
|
#include <Arduino.h>
|
|
#include "mik32_hal_spi.h"
|
|
|
|
// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
|
|
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
|
|
#define SPI_HAS_TRANSACTION 1
|
|
|
|
// SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method
|
|
#define SPI_HAS_NOTUSINGINTERRUPT 1
|
|
|
|
// SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.
|
|
// This way when there is a bug fix you can check this define to alert users
|
|
// of your code if it uses better version of this library.
|
|
// This also implies everything that SPI_HAS_TRANSACTION as documented above is
|
|
// available too.
|
|
#define SPI_ATOMIC_VERSION 1
|
|
|
|
#define SPI_DEFAULT_SPEED 4000000
|
|
|
|
// dividers for setClockDivider()
|
|
#define SPI_CLOCK_DIV2 0x00 // 16 MHz
|
|
#define SPI_CLOCK_DIV4 0x01 // 8 MHz
|
|
#define SPI_CLOCK_DIV8 0x02 // 4 MHz
|
|
#define SPI_CLOCK_DIV16 0x03 // 2 MHz
|
|
#define SPI_CLOCK_DIV32 0x04 // 1 MHz
|
|
#define SPI_CLOCK_DIV64 0x05 // 500 kHz
|
|
#define SPI_CLOCK_DIV128 0x06 // 250 kHz
|
|
#define SPI_CLOCK_DIV256 0x07 // 125 kHz
|
|
|
|
// mode[1] - polarity, mode[0] - phase
|
|
#define SPI_MODE0 0b00
|
|
#define SPI_MODE1 0b01
|
|
#define SPI_MODE2 0b10
|
|
#define SPI_MODE3 0b11
|
|
|
|
class SPISettings {
|
|
public:
|
|
uint32_t speedMaximum;
|
|
uint8_t newDataOrder;
|
|
uint8_t newDataMode;
|
|
// save values from arguments
|
|
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t mode)
|
|
: speedMaximum(clock), newDataOrder(bitOrder), newDataMode(mode) {}
|
|
};
|
|
|
|
|
|
class SPIClass
|
|
{
|
|
private:
|
|
uint8_t _spiNum;
|
|
SPI_HandleTypeDef _hspi = {0};
|
|
uint32_t _speed = 0;
|
|
uint8_t _dataOrder = MSBFIRST;
|
|
uint8_t _dataMode = -1;
|
|
bool _isInited = false;
|
|
bool _newConfig = false;
|
|
bool _spiInUse = false;
|
|
uint8_t _interruptMode = 0; // 0=none, 1=mask
|
|
uint8_t _interruptMask = 0; // which interrupts to mask
|
|
|
|
void updateSettings(uint32_t speedMaximum, uint8_t dataOrder, uint8_t dataMode);
|
|
|
|
public:
|
|
inline SPIClass(uint8_t num)
|
|
{
|
|
// Set the SPI to be used
|
|
_spiNum = (num < SPI_COMMON_QTY) ? num : 1; // SPI1 by default
|
|
}
|
|
// Initialize the SPI library
|
|
void begin();
|
|
|
|
// If SPI is used from within an interrupt, this function registers
|
|
// that interrupt with the SPI library, so beginTransaction() can
|
|
// prevent conflicts. The input interruptNumber is the number used
|
|
// with attachInterrupt.
|
|
void usingInterrupt(uint8_t interruptNumber);
|
|
// And this does the opposite.
|
|
void notUsingInterrupt(uint8_t interruptNumber);
|
|
// Note: the usingInterrupt and notUsingInterrupt functions should
|
|
// not to be called from ISR context or inside a transaction.
|
|
// For details see:
|
|
// https://github.com/arduino/Arduino/pull/2381
|
|
// https://github.com/arduino/Arduino/pull/2449
|
|
|
|
// Before using SPI.transfer() or asserting chip select pins,
|
|
// this function is used to gain exclusive access to the SPI bus
|
|
// and configure the correct settings.
|
|
void beginTransaction(SPISettings settings);
|
|
|
|
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
|
|
uint8_t transfer(uint8_t data);
|
|
uint16_t transfer16(uint16_t data);
|
|
void transfer(void *buf, size_t count);
|
|
|
|
// After performing a group of transfers and releasing the chip select
|
|
// signal, this function allows others to access the SPI bus
|
|
void endTransaction(void);
|
|
|
|
// Disable the SPI bus
|
|
void end();
|
|
|
|
// This function is deprecated. New applications should use
|
|
// beginTransaction() to configure SPI settings.
|
|
void setBitOrder(uint8_t bitOrder);
|
|
|
|
// This function is deprecated. New applications should use
|
|
// beginTransaction() to configure SPI settings.
|
|
void setDataMode(uint8_t dataMode);
|
|
// This function is deprecated. New applications should use
|
|
// beginTransaction() to configure SPI settings.
|
|
void setClockDivider(uint8_t clockDiv);
|
|
};
|
|
|
|
extern SPIClass SPI;
|
|
#if SPI_COMMON_QTY > 1
|
|
extern SPIClass SPI1;
|
|
#endif
|
|
|
|
#endif
|