| @@ -0,0 +1,3 @@ | |||
| #SPI Library for Teensy# | |||
| http://www.pjrc.com/teensy/teensyduino.html | |||
| @@ -0,0 +1,68 @@ | |||
| /* | |||
| * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st> | |||
| * 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. | |||
| */ | |||
| #include "pins_arduino.h" | |||
| #include "SPI.h" | |||
| SPIClass SPI; | |||
| void SPIClass::begin() { | |||
| // Set SS to high so a connected chip will be "deselected" by default | |||
| digitalWrite(SS, HIGH); | |||
| // When the SS pin is set as OUTPUT, it can be used as | |||
| // a general purpose output port (it doesn't influence | |||
| // SPI operations). | |||
| pinMode(SS, OUTPUT); | |||
| // Warning: if the SS pin ever becomes a LOW INPUT then SPI | |||
| // automatically switches to Slave, so the data direction of | |||
| // the SS pin MUST be kept as OUTPUT. | |||
| SPCR |= _BV(MSTR); | |||
| SPCR |= _BV(SPE); | |||
| // Set direction register for SCK and MOSI pin. | |||
| // MISO pin automatically overrides to INPUT. | |||
| // By doing this AFTER enabling SPI, we avoid accidentally | |||
| // clocking in a single bit since the lines go directly | |||
| // from "input" to SPI control. | |||
| // http://code.google.com/p/arduino/issues/detail?id=888 | |||
| #ifdef __AVR__ | |||
| pinMode(SCK, OUTPUT); | |||
| pinMode(MOSI, OUTPUT); | |||
| #endif | |||
| } | |||
| void SPIClass::end() { | |||
| SPCR &= ~_BV(SPE); | |||
| } | |||
| void SPIClass::setBitOrder(uint8_t bitOrder) | |||
| { | |||
| if(bitOrder == LSBFIRST) { | |||
| SPCR |= _BV(DORD); | |||
| } else { | |||
| SPCR &= ~(_BV(DORD)); | |||
| } | |||
| } | |||
| void SPIClass::setDataMode(uint8_t mode) | |||
| { | |||
| SPCR = (SPCR & ~SPI_MODE_MASK) | mode; | |||
| } | |||
| void SPIClass::setClockDivider(uint8_t rate) | |||
| { | |||
| SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK); | |||
| SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK); | |||
| } | |||
| @@ -0,0 +1,75 @@ | |||
| /* | |||
| * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st> | |||
| * 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 <stdio.h> | |||
| #include <Arduino.h> | |||
| #include <avr/pgmspace.h> | |||
| #define SPI_CLOCK_DIV4 0x00 | |||
| #define SPI_CLOCK_DIV16 0x01 | |||
| #define SPI_CLOCK_DIV64 0x02 | |||
| #define SPI_CLOCK_DIV128 0x03 | |||
| #define SPI_CLOCK_DIV2 0x04 | |||
| #define SPI_CLOCK_DIV8 0x05 | |||
| #define SPI_CLOCK_DIV32 0x06 | |||
| //#define SPI_CLOCK_DIV64 0x07 | |||
| #define SPI_MODE0 0x00 | |||
| #define SPI_MODE1 0x04 | |||
| #define SPI_MODE2 0x08 | |||
| #define SPI_MODE3 0x0C | |||
| #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 | |||
| class SPIClass { | |||
| public: | |||
| inline static byte transfer(byte _data); | |||
| // SPI Configuration methods | |||
| inline static void attachInterrupt(); | |||
| inline static void detachInterrupt(); // Default | |||
| static void begin(); // Default | |||
| static void end(); | |||
| static void setBitOrder(uint8_t); | |||
| static void setDataMode(uint8_t); | |||
| static void setClockDivider(uint8_t); | |||
| #if defined(__arm__) && defined(CORE_TEENSY) | |||
| inline void setMOSI(uint8_t pin) __attribute__((always_inline)) { SPCR.setMOSI(pin); } | |||
| inline void setMISO(uint8_t pin) __attribute__((always_inline)) { SPCR.setMISO(pin); } | |||
| inline void setSCK(uint8_t pin) __attribute__((always_inline)) { SPCR.setSCK(pin); } | |||
| #endif | |||
| }; | |||
| extern SPIClass SPI; | |||
| byte SPIClass::transfer(byte _data) { | |||
| SPDR = _data; | |||
| while (!(SPSR & _BV(SPIF))) | |||
| ; | |||
| return SPDR; | |||
| } | |||
| void SPIClass::attachInterrupt() { | |||
| SPCR |= _BV(SPIE); | |||
| } | |||
| void SPIClass::detachInterrupt() { | |||
| SPCR &= ~_BV(SPIE); | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,143 @@ | |||
| /* | |||
| SCP1000 Barometric Pressure Sensor Display | |||
| Shows the output of a Barometric Pressure Sensor on a | |||
| Uses the SPI library. For details on the sensor, see: | |||
| http://www.sparkfun.com/commerce/product_info.php?products_id=8161 | |||
| http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ | |||
| This sketch adapted from Nathan Seidle's SCP1000 example for PIC: | |||
| http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip | |||
| Circuit: | |||
| SCP1000 sensor attached to pins 6, 7, 10 - 13: | |||
| DRDY: pin 6 | |||
| CSB: pin 7 | |||
| MOSI: pin 11 | |||
| MISO: pin 12 | |||
| SCK: pin 13 | |||
| created 31 July 2010 | |||
| modified 14 August 2010 | |||
| by Tom Igoe | |||
| */ | |||
| // the sensor communicates using SPI, so include the library: | |||
| #include <SPI.h> | |||
| //Sensor's memory register addresses: | |||
| const int PRESSURE = 0x1F; //3 most significant bits of pressure | |||
| const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure | |||
| const int TEMPERATURE = 0x21; //16 bit temperature reading | |||
| const byte READ = 0b11111100; // SCP1000's read command | |||
| const byte WRITE = 0b00000010; // SCP1000's write command | |||
| // pins used for the connection with the sensor | |||
| // the other you need are controlled by the SPI library): | |||
| const int dataReadyPin = 6; | |||
| const int chipSelectPin = 7; | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| // start the SPI library: | |||
| SPI.begin(); | |||
| // initalize the data ready and chip select pins: | |||
| pinMode(dataReadyPin, INPUT); | |||
| pinMode(chipSelectPin, OUTPUT); | |||
| //Configure SCP1000 for low noise configuration: | |||
| writeRegister(0x02, 0x2D); | |||
| writeRegister(0x01, 0x03); | |||
| writeRegister(0x03, 0x02); | |||
| // give the sensor time to set up: | |||
| delay(100); | |||
| } | |||
| void loop() { | |||
| //Select High Resolution Mode | |||
| writeRegister(0x03, 0x0A); | |||
| // don't do anything until the data ready pin is high: | |||
| if (digitalRead(dataReadyPin) == HIGH) { | |||
| //Read the temperature data | |||
| int tempData = readRegister(0x21, 2); | |||
| // convert the temperature to celsius and display it: | |||
| float realTemp = (float)tempData / 20.0; | |||
| Serial.print("Temp[C]="); | |||
| Serial.print(realTemp); | |||
| //Read the pressure data highest 3 bits: | |||
| byte pressure_data_high = readRegister(0x1F, 1); | |||
| pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 | |||
| //Read the pressure data lower 16 bits: | |||
| unsigned int pressure_data_low = readRegister(0x20, 2); | |||
| //combine the two parts into one 19-bit number: | |||
| long pressure = ((pressure_data_high << 16) | pressure_data_low)/4; | |||
| // display the temperature: | |||
| Serial.println("\tPressure [Pa]=" + String(pressure)); | |||
| } | |||
| } | |||
| //Read from or write to register from the SCP1000: | |||
| unsigned int readRegister(byte thisRegister, int bytesToRead ) { | |||
| byte inByte = 0; // incoming byte from the SPI | |||
| unsigned int result = 0; // result to return | |||
| Serial.print(thisRegister, BIN); | |||
| Serial.print("\t"); | |||
| // SCP1000 expects the register name in the upper 6 bits | |||
| // of the byte. So shift the bits left by two bits: | |||
| thisRegister = thisRegister << 2; | |||
| // now combine the address and the command into one byte | |||
| byte dataToSend = thisRegister & READ; | |||
| Serial.println(thisRegister, BIN); | |||
| // take the chip select low to select the device: | |||
| digitalWrite(chipSelectPin, LOW); | |||
| // send the device the register you want to read: | |||
| SPI.transfer(dataToSend); | |||
| // send a value of 0 to read the first byte returned: | |||
| result = SPI.transfer(0x00); | |||
| // decrement the number of bytes left to read: | |||
| bytesToRead--; | |||
| // if you still have another byte to read: | |||
| if (bytesToRead > 0) { | |||
| // shift the first byte left, then get the second byte: | |||
| result = result << 8; | |||
| inByte = SPI.transfer(0x00); | |||
| // combine the byte you just got with the previous one: | |||
| result = result | inByte; | |||
| // decrement the number of bytes left to read: | |||
| bytesToRead--; | |||
| } | |||
| // take the chip select high to de-select: | |||
| digitalWrite(chipSelectPin, HIGH); | |||
| // return the result: | |||
| return(result); | |||
| } | |||
| //Sends a write command to SCP1000 | |||
| void writeRegister(byte thisRegister, byte thisValue) { | |||
| // SCP1000 expects the register address in the upper 6 bits | |||
| // of the byte. So shift the bits left by two bits: | |||
| thisRegister = thisRegister << 2; | |||
| // now combine the register address and the command into one byte: | |||
| byte dataToSend = thisRegister | WRITE; | |||
| // take the chip select low to select the device: | |||
| digitalWrite(chipSelectPin, LOW); | |||
| SPI.transfer(dataToSend); //Send register location | |||
| SPI.transfer(thisValue); //Send value to record into register | |||
| // take the chip select high to de-select: | |||
| digitalWrite(chipSelectPin, HIGH); | |||
| } | |||
| @@ -0,0 +1,143 @@ | |||
| /* | |||
| SCP1000 Barometric Pressure Sensor Display | |||
| Shows the output of a Barometric Pressure Sensor on a | |||
| Uses the SPI library. For details on the sensor, see: | |||
| http://www.sparkfun.com/commerce/product_info.php?products_id=8161 | |||
| http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ | |||
| This sketch adapted from Nathan Seidle's SCP1000 example for PIC: | |||
| http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip | |||
| Circuit: | |||
| SCP1000 sensor attached to pins 6, 7, 10 - 13: | |||
| DRDY: pin 6 | |||
| CSB: pin 7 | |||
| MOSI: pin 11 | |||
| MISO: pin 12 | |||
| SCK: pin 13 | |||
| created 31 July 2010 | |||
| modified 14 August 2010 | |||
| by Tom Igoe | |||
| */ | |||
| // the sensor communicates using SPI, so include the library: | |||
| #include <SPI.h> | |||
| //Sensor's memory register addresses: | |||
| const int PRESSURE = 0x1F; //3 most significant bits of pressure | |||
| const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure | |||
| const int TEMPERATURE = 0x21; //16 bit temperature reading | |||
| cont byte READ = 0b00000000; // SCP1000's read command | |||
| const byte WRITE = 0b00000010; // SCP1000's write command | |||
| // pins used for the connection with the sensor | |||
| // the other you need are controlled by the SPI library): | |||
| const int dataReadyPin = 6; | |||
| const int chipSelectPin = 7; | |||
| void setup() { | |||
| Serial.begin(9600); | |||
| // start the SPI library: | |||
| SPI.begin(); | |||
| // initalize the data ready and chip select pins: | |||
| pinMode(dataReadyPin, INPUT); | |||
| pinMode(chipSelectPin, OUTPUT); | |||
| //Configure SCP1000 for low noise configuration: | |||
| writeRegister(0x02, 0x2D); | |||
| writeRegister(0x01, 0x03); | |||
| writeRegister(0x03, 0x02); | |||
| // give the sensor time to set up: | |||
| delay(100); | |||
| } | |||
| void loop() { | |||
| //Select High Resolution Mode | |||
| writeRegister(0x03, 0x0A); | |||
| // don't do anything until the data ready pin is high: | |||
| if (digitalRead(dataReadyPin) == HIGH) { | |||
| //Read the temperature data | |||
| int tempData = readRegister(0x21, 2); | |||
| // convert the temperature to celsius and display it: | |||
| float realTemp = (float)tempData / 20.0; | |||
| Serial.print("Temp[C]="); | |||
| Serial.print(realTemp); | |||
| //Read the pressure data highest 3 bits: | |||
| byte pressure_data_high = readRegister(0x1F, 1); | |||
| pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 | |||
| //Read the pressure data lower 16 bits: | |||
| unsigned int pressure_data_low = readRegister(0x20, 2); | |||
| //combine the two parts into one 19-bit number: | |||
| long pressure = ((pressure_data_high << 16) | pressure_data_low)/4; | |||
| // display the temperature: | |||
| Serial.println("\tPressure [Pa]=" + String(pressure)); | |||
| } | |||
| } | |||
| //Read from or write to register from the SCP1000: | |||
| unsigned int readRegister(byte thisRegister, int bytesToRead ) { | |||
| byte inByte = 0; // incoming byte from the SPI | |||
| unsigned int result = 0; // result to return | |||
| // SCP1000 expects the register name in the upper 6 bits | |||
| // of the byte. So shift the bits left by two bits: | |||
| thisRegister = thisRegister << 2; | |||
| // now combine the address and the command into one byte | |||
| dataToSend = thisRegister & READ; | |||
| // take the chip select low to select the device: | |||
| digitalWrite(chipSelectPin, LOW); | |||
| // send the device the register you want to read: | |||
| SPI.transfer(dataToSend); | |||
| // send a value of 0 to read the first byte returned: | |||
| result = SPI.transfer(0x00); | |||
| // decrement the number of bytes left to read: | |||
| bytesToRead--; | |||
| // if you still have another byte to read: | |||
| if (bytesToRead > 0) { | |||
| // shift the first byte left, then get the second byte: | |||
| result = result << 8; | |||
| inByte = SPI.transfer(0x00); | |||
| // combine the byte you just got with the previous one: | |||
| result = result | inByte; | |||
| // decrement the number of bytes left to read: | |||
| bytesToRead--; | |||
| } | |||
| // take the chip select high to de-select: | |||
| digitalWrite(chipSelectPin, HIGH); | |||
| // return the result: | |||
| return(result); | |||
| } | |||
| //Sends a write command to SCP1000 | |||
| void writeRegister(byte thisRegister, byte thisValue) { | |||
| // SCP1000 expects the register address in the upper 6 bits | |||
| // of the byte. So shift the bits left by two bits: | |||
| thisRegister = thisRegister << 2; | |||
| // now combine the register address and the command into one byte: | |||
| dataToSend = thisRegister | WRITE; | |||
| // take the chip select low to select the device: | |||
| digitalWrite(chipSelectPin, LOW); | |||
| SPI.transfer(dataToSend); //Send register location | |||
| SPI.transfer(thisValue); //Send value to record into register | |||
| // take the chip select high to de-select: | |||
| digitalWrite(chipSelectPin, HIGH); | |||
| } | |||
| @@ -0,0 +1,71 @@ | |||
| /* | |||
| Digital Pot Control | |||
| This example controls an Analog Devices AD5206 digital potentiometer. | |||
| The AD5206 has 6 potentiometer channels. Each channel's pins are labeled | |||
| A - connect this to voltage | |||
| W - this is the pot's wiper, which changes when you set it | |||
| B - connect this to ground. | |||
| The AD5206 is SPI-compatible,and to command it, you send two bytes, | |||
| one with the channel number (0 - 5) and one with the resistance value for the | |||
| channel (0 - 255). | |||
| The circuit: | |||
| * All A pins of AD5206 connected to +5V | |||
| * All B pins of AD5206 connected to ground | |||
| * An LED and a 220-ohm resisor in series connected from each W pin to ground | |||
| * CS - to digital pin 10 (SS pin) | |||
| * SDI - to digital pin 11 (MOSI pin) | |||
| * CLK - to digital pin 13 (SCK pin) | |||
| created 10 Aug 2010 | |||
| by Tom Igoe | |||
| Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 | |||
| */ | |||
| // inslude the SPI library: | |||
| #include <SPI.h> | |||
| // set pin 10 as the slave select for the digital pot: | |||
| const int slaveSelectPin = 10; | |||
| void setup() { | |||
| // set the slaveSelectPin as an output: | |||
| pinMode (slaveSelectPin, OUTPUT); | |||
| // initialize SPI: | |||
| SPI.begin(); | |||
| } | |||
| void loop() { | |||
| // go through the six channels of the digital pot: | |||
| for (int channel = 0; channel < 6; channel++) { | |||
| // change the resistance on this channel from min to max: | |||
| for (int level = 0; level < 255; level++) { | |||
| digitalPotWrite(channel, level); | |||
| delay(10); | |||
| } | |||
| // wait a second at the top: | |||
| delay(100); | |||
| // change the resistance on this channel from max to min: | |||
| for (int level = 0; level < 255; level++) { | |||
| digitalPotWrite(channel, 255 - level); | |||
| delay(10); | |||
| } | |||
| } | |||
| } | |||
| void digitalPotWrite(int address, int value) { | |||
| // take the SS pin low to select the chip: | |||
| digitalWrite(slaveSelectPin,LOW); | |||
| // send in the address and value via SPI: | |||
| SPI.transfer(address); | |||
| SPI.transfer(value); | |||
| // take the SS pin high to de-select the chip: | |||
| digitalWrite(slaveSelectPin,HIGH); | |||
| } | |||
| @@ -0,0 +1,39 @@ | |||
| ####################################### | |||
| # Syntax Coloring Map SPI | |||
| ####################################### | |||
| ####################################### | |||
| # Datatypes (KEYWORD1) | |||
| ####################################### | |||
| SPI KEYWORD1 | |||
| ####################################### | |||
| # Methods and Functions (KEYWORD2) | |||
| ####################################### | |||
| begin KEYWORD2 | |||
| end KEYWORD2 | |||
| transfer KEYWORD2 | |||
| setBitOrder KEYWORD2 | |||
| setDataMode KEYWORD2 | |||
| setClockDivider KEYWORD2 | |||
| setMOSI KEYWORD2 | |||
| setMISO KEYWORD2 | |||
| setSCK KEYWORD2 | |||
| ####################################### | |||
| # Constants (LITERAL1) | |||
| ####################################### | |||
| SPI_CLOCK_DIV4 LITERAL1 | |||
| SPI_CLOCK_DIV16 LITERAL1 | |||
| SPI_CLOCK_DIV64 LITERAL1 | |||
| SPI_CLOCK_DIV128 LITERAL1 | |||
| SPI_CLOCK_DIV2 LITERAL1 | |||
| SPI_CLOCK_DIV8 LITERAL1 | |||
| SPI_CLOCK_DIV32 LITERAL1 | |||
| SPI_CLOCK_DIV64 LITERAL1 | |||
| SPI_MODE0 LITERAL1 | |||
| SPI_MODE1 LITERAL1 | |||
| SPI_MODE2 LITERAL1 | |||
| SPI_MODE3 LITERAL1 | |||