/* * Copyright (c) 2010 by Cristian Maglie * Copyright (c) 2014 by Paul Stoffregen (Transaction API) * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) * Copyright (c) 2014 by Andrew J. Kroll (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 #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