[136] | 1 | /*
|
---|
| 2 | * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
|
---|
| 3 | * SPI Master library for arduino.
|
---|
| 4 | *
|
---|
| 5 | * This file is free software; you can redistribute it and/or modify
|
---|
| 6 | * it under the terms of either the GNU General Public License version 2
|
---|
| 7 | * or the GNU Lesser General Public License version 2.1, both as
|
---|
| 8 | * published by the Free Software Foundation.
|
---|
| 9 | */
|
---|
| 10 |
|
---|
| 11 | #ifndef _SPI_H_INCLUDED
|
---|
| 12 | #define _SPI_H_INCLUDED
|
---|
| 13 |
|
---|
| 14 | #include "variant.h"
|
---|
| 15 | #include "wiring_constants.h"
|
---|
[224] | 16 | #include <Arduino.h>
|
---|
| 17 |
|
---|
| 18 | //#define LSBFIRST 0 //already defined in wiring_constants.h
|
---|
| 19 | //#define MSBFIRST 1
|
---|
[136] | 20 |
|
---|
| 21 | #define SPI_MODE0 0x02
|
---|
| 22 | #define SPI_MODE1 0x00
|
---|
| 23 | #define SPI_MODE2 0x03
|
---|
| 24 | #define SPI_MODE3 0x01
|
---|
| 25 |
|
---|
[224] | 26 |
|
---|
| 27 | #define SPI_CLOCK_DIV2 6 //8 MHz
|
---|
| 28 | #define SPI_CLOCK_DIV4 12 //4 MHz
|
---|
| 29 | #define SPI_CLOCK_DIV8 24 //2 MHz
|
---|
| 30 | #define SPI_CLOCK_DIV16 48 //1 MHz
|
---|
| 31 | #define SPI_CLOCK_DIV32 96 //500 KHz
|
---|
| 32 | #define SPI_CLOCK_DIV64 192 //250 KHz
|
---|
| 33 | #define SPI_CLOCK_DIV128 384 //125 KHz
|
---|
| 34 |
|
---|
| 35 | #ifndef intStatus
|
---|
| 36 | #define intStatus() __intStatus()
|
---|
| 37 | static inline unsigned char __intStatus(void) __attribute__((always_inline, unused));
|
---|
| 38 | static inline unsigned char __intStatus(void) {
|
---|
| 39 | unsigned int primask, faultmask;
|
---|
| 40 | asm volatile ("mrs %0, primask" : "=r" (primask));
|
---|
| 41 | if (primask) return 0;
|
---|
| 42 | asm volatile ("mrs %0, faultmask" : "=r" (faultmask));
|
---|
| 43 | if (faultmask) return 0;
|
---|
| 44 | return 1;
|
---|
| 45 | }
|
---|
| 46 | #endif
|
---|
| 47 |
|
---|
| 48 | class SPISettings {
|
---|
| 49 | public:
|
---|
| 50 | SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
|
---|
| 51 | {
|
---|
| 52 | interface_clock = clock;
|
---|
| 53 | bit_order = bitOrder;
|
---|
| 54 | data_mode = dataMode;
|
---|
| 55 |
|
---|
| 56 | /*Serial.print("clock: ");
|
---|
| 57 | Serial.println(interface_clock);
|
---|
| 58 | Serial.print("bit order: ");
|
---|
| 59 | Serial.println(bit_order);
|
---|
| 60 | Serial.print("data mode: ");
|
---|
| 61 | Serial.println(data_mode);*/
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | SPISettings(void)
|
---|
| 65 | {
|
---|
| 66 | interface_clock = 4000000;
|
---|
| 67 | bit_order = MSBFIRST;
|
---|
| 68 | data_mode = SPI_MODE0;
|
---|
| 69 |
|
---|
| 70 | /*Serial.print("clock: ");
|
---|
| 71 | Serial.println(interface_clock);
|
---|
| 72 | Serial.print("bit order: ");
|
---|
| 73 | Serial.println(bit_order);
|
---|
| 74 | Serial.print("data mode: ");
|
---|
| 75 | Serial.println(data_mode);*/
|
---|
| 76 | }
|
---|
| 77 | private:
|
---|
| 78 | uint32_t interface_clock;
|
---|
| 79 | uint8_t bit_order;
|
---|
| 80 | uint8_t data_mode;
|
---|
| 81 |
|
---|
| 82 | friend class SPIClass;
|
---|
| 83 | };
|
---|
| 84 |
|
---|
| 85 |
|
---|
[136] | 86 | class SPIClass {
|
---|
| 87 | public:
|
---|
| 88 | SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI);
|
---|
| 89 |
|
---|
| 90 | byte transfer(uint8_t data);
|
---|
[224] | 91 | void transfer(void *data, size_t count);
|
---|
| 92 | byte read(void);
|
---|
| 93 | uint16_t transfer16(uint16_t data);
|
---|
| 94 | void write(uint8_t data);
|
---|
[136] | 95 | // SPI Configuration methods
|
---|
[224] | 96 | void beginTransaction(SPISettings settings);
|
---|
| 97 | void endTransaction(void);
|
---|
| 98 |
|
---|
[136] | 99 | void attachInterrupt();
|
---|
| 100 | void detachInterrupt();
|
---|
[224] | 101 |
|
---|
| 102 | void usingInterrupt(uint8_t interruptNumber);
|
---|
[136] | 103 |
|
---|
| 104 | void begin();
|
---|
[224] | 105 | void beginSlave();
|
---|
[136] | 106 | void end();
|
---|
| 107 |
|
---|
| 108 | void setBitOrder(BitOrder order);
|
---|
| 109 | void setDataMode(uint8_t uc_mode);
|
---|
[224] | 110 | void setClockDivider(uint16_t uc_div);
|
---|
[136] | 111 |
|
---|
| 112 | private:
|
---|
| 113 | SERCOM *_p_sercom;
|
---|
| 114 | uint8_t _uc_pinMiso;
|
---|
| 115 | uint8_t _uc_pinMosi;
|
---|
| 116 | uint8_t _uc_pinSCK;
|
---|
[224] | 117 | uint8_t interruptMode;
|
---|
| 118 | uint32_t interruptMask;
|
---|
| 119 | uint8_t interruptSave;
|
---|
| 120 | uint8_t inTransactionFlag;
|
---|
[136] | 121 | };
|
---|
| 122 |
|
---|
| 123 | #if SPI_INTERFACES_COUNT > 0
|
---|
| 124 | extern SPIClass SPI;
|
---|
| 125 | #endif
|
---|
| 126 |
|
---|
[224] | 127 | #endif
|
---|