Move master branch from from mios git repo

This commit is contained in:
hek
2014-01-23 00:23:15 +01:00
commit 609d9e5be9
352 changed files with 53418 additions and 0 deletions
+63
View File
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2009 Andrew Smallbone <andrew@rocketnumbernine.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <ds1305.h>
#ifdef __cplusplus
extern "C"{
#endif
unsigned char ds1305_transfer(unsigned char address, unsigned char data)
{
select_ds1305();
send_spi(address);
unsigned char out = send_spi(data);
deselect_ds1305();
return out;
}
void ds1305_write_block(unsigned char address, unsigned char *data, int length)
{
select_ds1305();
send_spi(address+DS1305_WRITE);
int i;
for (i=0; i<length; i++) {
send_spi(*data++);
}
deselect_ds1305();
}
void ds1305_read_block(unsigned char address, unsigned char *data, int length)
{
select_ds1305();
send_spi(address);
int i;
for (i=0; i<length; i++) {
*(data+i) = send_spi(0xFF);
}
deselect_ds1305();
}
#ifdef __cplusplus
} // extern "C"
#endif
+115
View File
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2009 Andrew Smallbone <andrew@rocketnumbernine.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _ds1305_h__
#define _ds1305_h__
#include <spi.h>
#ifdef __cplusplus
extern "C"{
#endif
// these should be defined to the operation used to select/deselect the DS1305
void select_ds1305(void);
void deselect_ds1305(void);
#define DS1305_WRITE 0x80
#define DS1305_TIME 0x00
#define DS1305_ALARM0 0x07
#define DS1305_ALARM1 0x0B
#define DS1305_CONTROL 0x0F
#define DS1305_STATUS 0x010
#define DS1305_CHARGER 0x11
#define DS1305_USERRAM 0x20
#define DS1305_ALARM_SET 0x80
// send the address and a byte and returns the byte returned by the DS1305
unsigned char ds1305_transfer(unsigned char address, unsigned char data);
// write a block of bytes - will add 0x80 to the address
void ds1305_write_block(unsigned char address, unsigned char *data, int length);
// read a block of bytes
void ds1305_read_block(unsigned char address, unsigned char *data, int length);
typedef struct _DS1305_DATETIME
{
unsigned char seconds;
unsigned char minutes;
unsigned char hours;
unsigned char dayofweek;
unsigned char date;
unsigned char month;
unsigned char year;
} DS1305_DATETIME;
/* set/get the current time/date passed the address of a DS1305_DATETIME struct
To set the current time/date to "20:11:32 Sunday 29/07/2009"
DS1305_DATETIME current = {0x32, 0x11, 0x20, 0x01, 0x29, 0x05, 0x09};
set_time(&current);
*/
#define set_time(datetime) ds1305_write_block(DS1305_TIME, (unsigned char *)datetime, 7)
#define get_time(datetime) ds1305_read_block(DS1305_TIME, (unsigned char *)datetime, 7)
/* set/get the time of alarm0/alarm1 passed the address of a DS1305_DATETIME struct,
although only the seconds/minutes/hours/dayofweek are sent/received
*/
#define set_alarm0(time) ds1305_write_block(DS1305_ALARM0, (unsigned char *)time, 4)
#define get_alarm0(time) ds1305_read_block(DS1305_ALARM0, (unsigned char *)time, 4)
#define set_alarm1(time) ds1305_write_block(DS1305_ALARM1, (unsigned char *)time, 4)
#define get_alarm1(time) ds1305_read_block(DS1305_ALARM1, (unsigned char *)time, 4)
// flags used in set_control/get_control
#define DS1305_EOSC 0x80 // enable oscillator, note this is inverse of ^EOSC bit value on chip
#define DS1305_WP 0x40 // write protect
#define DS1305_INTCN 0x04 // enable interrupts
#define DS1305_AIE1 0x02 // alarm0 interrupt enable
#define DS1305_AIE0 0x01 // alarm1 interrupt enable
/* get/set the control register. To enable the oscillator, turn on write protection
and enable all interrupts the following would be used:
set_control(DS1305_EOSC | DS1305_WP | DS1305_INTCN | DS1305_AIE1 | DS1305_AIE0);
*/
#define set_control(data) ds1305_transfer(DS1305_CONTROL+DS1305_WRITE, (data) ^ DS1305_EOSC)
#define get_control(data) (ds1305_transfer(DS1305_CONTROL, 0xFF) ^ DS1305_EOSC)
// flags used in get_status
#define DS1305_IRQF0 0x01 // interrupt 0 request flag - current time has matched alarm 0
#define DS1305_IRQF1 0x02 // interrupt 1 request flag - current time has matched alarm 1
#define get_status(data) ds1305_transfer(DS1305_STATUS, 0xFF)
// flags used in set_charger/get_charger
#define DS1305_CHARGER_OFF 0x5C // no charge - don't combine with other values
#define DS1305_CHARGER_1D2K 0xA5 // 1 diode 2K resistor
#define DS1305_CHARGER_1D4K 0xA6 // 1 diode 4K resistor
#define DS1305_CHARGER_1D8K 0xA7 // 1 diode 8K resistor
#define DS1305_CHARGER_2D2K 0xA1 // 2 diode 2K resistor
#define DS1305_CHARGER_2D4K 0xA2 // 2 diode 4K resistor
#define DS1305_CHARGER_2D8K 0xA3 // 2 diode 8K resistor
/* get/set the charger register */
#define set_charger(data) ds1305_transfer(DS1305_CHARGE+DS1305_WRITE, data)
#define get_charger(data) ds1305_transfer(DS1305_CHARGE, 0xFF)
#ifdef __cplusplus
} // extern "C"
#endif
#endif
+53
View File
@@ -0,0 +1,53 @@
#######################################
# Syntax Coloring Map For SPI
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
DS1305_DATETIME KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
select_ds1305 KEYWORD2
deselect_ds1305 KEYWORD2
set_time KEYWORD2
get_time KEYWORD2
set_control KEYWORD2
get_control KEYWORD2
set_charger KEYWORD2
get_charger KEYWORD2
get_alarm0 KEYWORD2
set_alarm1 KEYWORD2
get_alarm1 KEYWORD2
get_status KEYWORD2
#######################################
# Constants KEYWORD2
#######################################
DS1305_WRITE LITERAL1
DS1305_TIME LITERAL1
DS1305_ALARM0 LITERAL1
DS1305_ALARM1 LITERAL1
DS1305_CONTROL LITERAL1
DS1305_STATUS LITERAL1
DS1305_CHARGER LITERAL1
DS1305_USERRAM LITERAL1
DS1305_ALARM_SET LITERAL1
DS1305_EOSC LITERAL1
DS1305_WP LITERAL1
DS1305_INTCN LITERAL1
DS1305_AIE1 LITERAL1
DS1305_AIE0 LITERAL1
DS1305_IRQF0 LITERAL1
DS1305_IRQF1 LITERAL1
DS1305_CHARGER_OFF LITERAL1
DS1305_CHARGER_1D2K LITERAL1
DS1305_CHARGER_1D4K LITERAL1
DS1305_CHARGER_1D8K LITERAL1
DS1305_CHARGER_2D2K LITERAL1
DS1305_CHARGER_2D4K LITERAL1
DS1305_CHARGER_2D8K LITERAL1
@@ -0,0 +1,79 @@
#include <spi.h>
#include <ds1305.h>
#define DS1305_PIN 4
#define LED_PIN 3
// following two methods required by DS1305 library to select/deselect device
void select_ds1305(void)
{
digitalWrite(DS1305_PIN, HIGH);
}
void deselect_ds1305(void)
{
digitalWrite(DS1305_PIN, LOW);
}
// flash led that's connected to pin 3
void flash_led(void)
{
pinMode(LED_PIN, OUTPUT);
for (int i=0; i<10; i++) {
digitalWrite(LED_PIN, i%2==0);
delay(50);
}
}
// called when pin INT0 goes from 1 to 0
ISR(INT0_vect)
{
// get alarm value to clear alarm interrupt flag on DS1305
DS1305_DATETIME alarm;
get_alarm0(&alarm);
flash_led();
}
void setup()
{
// flash LED at start to indicate were about to start
flash_led();
flash_led();
// pin used to enable DS1305
pinMode(DS1305_PIN, OUTPUT);
// Make sure ADC is unselected and setup spi
deselect_ds1305();
setup_spi(SPI_MODE_1, SPI_MSB, SPI_NO_INTERRUPT, SPI_MSTR_CLK16);
set_control(0);
// set current date/time to Thursday 06/05/09 20:32:30
DS1305_DATETIME current = {0x30, 0x32, 0x20, 0x05, 0x06, 0x05, 0x09};
set_time(&current);
// change the value of alarm to the required time/granularity:
// raise alarm every day (at 20:32:00):
// DS1305_DATETIME alarm = {0x00, 0x32, 0x20, 0x00 | DS1305_ALARM_SET};
// raise alarm every minute (when seconds = 00):
// DS1305_DATETIME alarm = {0x00, 0x32 | DS1305_ALARM_SET,
// 0x20 | DS1305_ALARM_SET, 0x05 | DS1305_ALARM_SET};
// raise alarm every second:
DS1305_DATETIME alarm = {0x55 | DS1305_ALARM_SET, 0x32 | DS1305_ALARM_SET,
0x20 | DS1305_ALARM_SET, 0x05 | DS1305_ALARM_SET};
set_alarm0(&alarm);
// turn on timer and make alarm0 lower INT0 pin when alarm is triggered
set_control(DS1305_EOSC | DS1305_INTCN | DS1305_AIE0);
// raise interrupt when INT0 pin falls (pin PD0 at AT90usbXXX, pin PD2 on ATmegaXXX (arduino pin 2))
// the code in ISR(INT0_vect) above will be called
EICRA = (1<<ISC01) | (0<<ISC00);
// enable interrupts
EIMSK = (1<<INT0);
sei();
}
void loop()
{
// do nothing - all action happens in interrupt
}
@@ -0,0 +1,38 @@
#include <spi.h>
// MAX6675 connected to pin D9
#define MAX6675_SELECT_PIN 8
#define DESELECT_MAX6675 digitalWrite(MAX6675_SELECT_PIN, HIGH)
#define SELECT_MAX6675 digitalWrite(MAX6675_SELECT_PIN, LOW)
void setup()
{
pinMode(MAX6675_SELECT_PIN, OUTPUT);
DESELECT_MAX6675;
setup_spi(SPI_MODE_1, SPI_MSB, SPI_NO_INTERRUPT, SPI_MSTR_CLK8);
Serial.begin(19200);
}
void loop()
{
delay(500);
// select the device, wait > 100nS, read two bytes, deselect
SELECT_MAX6675;
delayMicroseconds(1);
unsigned char highByte = send_spi(0);
unsigned char lowByte = send_spi(0);
DESELECT_MAX6675;
// if bit 3 is high thermocouple is unconnected
if (lowByte & (1<<2)) {
Serial.print("Not connected ");
Serial.print(highByte, HEX); Serial.print(" ");
Serial.println(lowByte, HEX);
} else {
// temperature value is in bits 6-0 of highByte and 7-2 of lowByte
short value = (highByte << 5 | lowByte>>3);
// 1 bit is 0.25 degree 'divide' by 4 to show degrees
Serial.print(value/4); Serial.print("."); Serial.println(value%4 *25);
}
}
@@ -0,0 +1,32 @@
#include <spi.h>
#define SELECT_ADC digitalWrite(8, LOW);
#define DESELECT_ADC digitalWrite(8, HIGH);
unsigned short read_adc(void)
{
// select ADC wait 100microseconds then read two bytes
SELECT_ADC;
unsigned char one = send_spi(0xFF);
unsigned char two = send_spi(0xFF);
DESELECT_ADC;
// 12 bits of ADC value is bottom 5 bits of first
// byte and top 7 bits of second, move into 16 bit int
return ((0x1F & one) << 7) | (two >> 1);
}
void setup()
{
pinMode(8, OUTPUT);
Serial.begin(19200);
// make sure ADC is not selected and setup spi
DESELECT_ADC;
setup_spi(SPI_MODE_0, SPI_MSB, SPI_NO_INTERRUPT, SPI_MSTR_CLK16);
}
void loop()
{
unsigned short num = read_adc();
Serial.println(num);
delay(1000);
}
@@ -0,0 +1,91 @@
#include <spi.h>
#include <util/delay.h>
#define BUTTON_PIN 2
#define LED_PIN 3
#define FLASH_LED_COMMAND 0x01
#define OTHER_SELECT_PIN 7
#define SELECT_OTHER digitalWrite(OTHER_SELECT_PIN, LOW);
#define DESELECT_OTHER digitalWrite(OTHER_SELECT_PIN, HIGH);
#define BUFSIZE 20
volatile unsigned char incoming[BUFSIZE];
volatile short int received=0;
// flash led that's connected to pin PD7
void flash_led(int count)
{
pinMode(LED_PIN, OUTPUT);
for (int i=0; i<count*2; i++) {
digitalWrite(LED_PIN, i%2==0);
_delay_ms(75);
}
}
// send a SPI message to the other device - 3 bytes then go back into
// slave mode
void send_message()
{
setup_spi(SPI_MODE_1, SPI_MSB, SPI_NO_INTERRUPT, SPI_MSTR_CLK8);
if (SPCR & (1<<MSTR)) { // if we are still in master mode
SELECT_OTHER; // tell other device to flash LED twice
send_spi(FLASH_LED_COMMAND); send_spi(0x02); send_spi(0x00);
DESELECT_OTHER;
}
setup_spi(SPI_MODE_1, SPI_MSB, SPI_INTERRUPT, SPI_SLAVE);
}
// called when button pushed and pin INT0 goes from 1 to 0
void button_pressed()
{
send_message();
_delay_ms(500); // 'debounce'
}
// parse the data received from the other device
// currently just knows about the FLASH_LED_COMMAND
void parse_message()
{
switch(incoming[0]) {
case FLASH_LED_COMMAND:
flash_led(incoming[1]);
break;
default:
flash_led(20);
}
}
// called by the SPI system when there is data ready.
// Just store the incoming data in a buffer, when we receive a
// terminating byte (0x00) call parse_message to process the data received
ISR(SPI_STC_vect)
{
incoming[received++] = received_from_spi(0x00);
if (received == BUFSIZE || incoming[received-1] == 0x00) {
parse_message();
received = 0;
}
}
void setup()
{
// make sure other device is unselected (pin is HIGH) and setup spi
DESELECT_OTHER;
pinMode(OTHER_SELECT_PIN, OUTPUT);
setup_spi(SPI_MODE_1, SPI_MSB, SPI_INTERRUPT, SPI_SLAVE);
// raise interrupt when INT0 pin falls (arduino pin 2))
// the function button_pressed will be called
attachInterrupt(0, button_pressed, FALLING);
// flash LED at start to indicate were ready
flash_led(1);
}
void loop()
{
// do nothing
}
@@ -0,0 +1,62 @@
/**
* First stab at a test suite for spi lib.
*/
#include <spi.h>
void reportError(int line, char *message, uint8_t expected, uint8_t actual)
{
Serial.print("Test "); Serial.print(message);
Serial.print(" failed at line "); Serial.print(line-3);
Serial.print(", expected="); Serial.print(expected, BIN);
Serial.print(", actual="); Serial.println(actual, BIN);
}
#define assertEquals(message, expected, actual) \
if (expected != actual) { reportError(__LINE__, message, expected, actual); return; }
#define test_setup_spi(message, eSPCR, eSPSR, mode, dord, interrupt, clock) \
setup_spi(mode, dord, interrupt, clock); \
assertEquals(message, eSPCR, SPCR); \
assertEquals(message, eSPSR, SPSR & 0x01);
void test_registers()
{
// top 4 bits of SPCR - enabled, interrupt, lsb/msb, master/slave
disable_spi();
assertEquals("0", 0x00, SPCR);
test_setup_spi("1", 0xE0, 0x00, SPI_MODE_0, SPI_LSB, SPI_INTERRUPT, SPI_SLAVE);
test_setup_spi("2", 0x60, 0x00, SPI_MODE_0, SPI_LSB, SPI_NO_INTERRUPT, SPI_SLAVE);
test_setup_spi("3", 0x40, 0x00, SPI_MODE_0, SPI_MSB, SPI_NO_INTERRUPT, SPI_SLAVE);
// CPOL/CPHA bits - timing mode
test_setup_spi("4", 0x40, 0x00, SPI_MODE_0, SPI_MSB, SPI_NO_INTERRUPT, SPI_SLAVE);
test_setup_spi("5", 0x44, 0x00, SPI_MODE_1, SPI_MSB, SPI_NO_INTERRUPT, SPI_SLAVE);
test_setup_spi("6", 0x48, 0x00, SPI_MODE_2, SPI_MSB, SPI_NO_INTERRUPT, SPI_SLAVE);
test_setup_spi("7", 0x4C, 0x00, SPI_MODE_3, SPI_MSB, SPI_NO_INTERRUPT, SPI_SLAVE);
// clock
test_setup_spi("9", 0xE0, 1, SPI_MODE_0, SPI_LSB, SPI_INTERRUPT, SPI_MSTR_CLK2);
test_setup_spi("10", 0xE0, 0, SPI_MODE_0, SPI_LSB, SPI_INTERRUPT, SPI_MSTR_CLK4);
test_setup_spi("11", 0xE1, 1, SPI_MODE_0, SPI_LSB, SPI_INTERRUPT, SPI_MSTR_CLK8);
test_setup_spi("12", 0xE1, 0, SPI_MODE_0, SPI_LSB, SPI_INTERRUPT, SPI_MSTR_CLK16);
test_setup_spi("13", 0xE2, 1, SPI_MODE_0, SPI_LSB, SPI_INTERRUPT, SPI_MSTR_CLK32);
test_setup_spi("14", 0xE2, 0, SPI_MODE_0, SPI_LSB, SPI_INTERRUPT, SPI_MSTR_CLK64);
test_setup_spi("15", 0xE3, 0, SPI_MODE_0, SPI_LSB, SPI_INTERRUPT, SPI_MSTR_CLK128);
}
void setup()
{
Serial.begin(19200);
}
void loop()
{
delay(5000);
Serial.println("Running tests");
test_registers();
Serial.println("Run tests");
while(true);
}
+39
View File
@@ -0,0 +1,39 @@
#######################################
# Syntax Coloring Map For SPI
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
#######################################
# Methods and Functions (KEYWORD2)
#######################################
setup_spi KEYWORD2
disable_spi KEYWORD2
send_spi KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
SPI_SS_PIN LITERAL1
SPI_SCK_PIN LITERAL1
SPI_MOSI_PIN LITERAL1
SPI_MISO_PIN LITERAL1
SPI_MODE_0 LITERAL1
SPI_MODE_1 LITERAL1
SPI_MODE_2 LITERAL1
SPI_MODE_3 LITERAL1
SPI_LSB LITERAL1
SPI_MSB LITERAL1
SPI_NO_INTERRUPT LITERAL1
SPI_INTERRUPT LITERAL1
SPI_SLAVE LITERAL1
SPI_MSTR_CLK2 LITERAL1
SPI_MSTR_CLK4 LITERAL1
SPI_MSTR_CLK8 LITERAL1
SPI_MSTR_CLK16 LITERAL1
SPI_MSTR_CLK32 LITERAL1
SPI_MSTR_CLK64 LITERAL1
SPI_MSTR_CLK128 LITERAL1
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2009 Andrew Smallbone <andrew@rocketnumbernine.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <spi.h>
#ifdef __cplusplus
extern "C"{
#endif
#ifdef __ARDUINO__
#include <wiring.h>
#endif
void setup_spi(uint8_t mode, int dord, int interrupt, uint8_t clock)
{
// specify pin directions for SPI pins on port B
if (clock == SPI_SLAVE) { // if slave SS and SCK is input
DDRB &= ~(1<<SPI_MOSI_PIN); // input
DDRB |= (1<<SPI_MISO_PIN); // output
DDRB &= ~(1<<SPI_SS_PIN); // input
DDRB &= ~(1<<SPI_SCK_PIN);// input
} else {
DDRB |= (1<<SPI_MOSI_PIN); // output
DDRB &= ~(1<<SPI_MISO_PIN); // input
DDRB |= (1<<SPI_SCK_PIN);// output
DDRB |= (1<<SPI_SS_PIN);// output
}
SPCR = ((interrupt ? 1 : 0)<<SPIE) // interrupt enabled
| (1<<SPE) // enable SPI
| (dord<<DORD) // LSB or MSB
| (((clock != SPI_SLAVE) ? 1 : 0) <<MSTR) // Slave or Master
| (((mode & 0x02) == 2) << CPOL) // clock timing mode CPOL
| (((mode & 0x01)) << CPHA) // clock timing mode CPHA
| (((clock & 0x02) == 2) << SPR1) // cpu clock divisor SPR1
| ((clock & 0x01) << SPR0); // cpu clock divisor SPR0
SPSR = (((clock & 0x04) == 4) << SPI2X); // clock divisor SPI2X
}
void disable_spi()
{
SPCR = 0;
}
uint8_t send_spi(uint8_t out)
{
SPDR = out;
while (!(SPSR & (1<<SPIF)));
return SPDR;
}
uint8_t received_from_spi(uint8_t data)
{
SPDR = data;
return SPDR;
}
+94
View File
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2009 Andrew Smallbone <andrew@rocketnumbernine.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _spi_h__
#define _spi_h__
#include <avr/io.h>
#ifdef __cplusplus
extern "C"{
#endif
// create alias for the different SPI chip pins - code assumes all on port B
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__))
#define SPI_SS_PIN PORTB0
#define SPI_SCK_PIN PORTB1
#define SPI_MOSI_PIN PORTB2
#define SPI_MISO_PIN PORTB3
#elif (defined(__AVR_ATmega48__) || defined(_AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__))
#define SPI_SS_PIN PORTB2
#define SPI_SCK_PIN PORTB5
#define SPI_MOSI_PIN PORTB3
#define SPI_MISO_PIN PORTB4
#else
#error unknown processor - add to spi.h
#endif
// SPI clock modes
#define SPI_MODE_0 0x00 /* Sample (Rising) Setup (Falling) CPOL=0, CPHA=0 */
#define SPI_MODE_1 0x01 /* Setup (Rising) Sample (Falling) CPOL=0, CPHA=1 */
#define SPI_MODE_2 0x02 /* Sample (Falling) Setup (Rising) CPOL=1, CPHA=0 */
#define SPI_MODE_3 0x03 /* Setup (Falling) Sample (Rising) CPOL=1, CPHA=1 */
// data direction
#define SPI_LSB 1 /* send least significant bit (bit 0) first */
#define SPI_MSB 0 /* send most significant bit (bit 7) first */
// whether to raise interrupt when data received (SPIF bit received)
#define SPI_NO_INTERRUPT 0
#define SPI_INTERRUPT 1
// slave or master with clock diviser
#define SPI_SLAVE 0xF0
#define SPI_MSTR_CLK4 0x00 /* chip clock/4 */
#define SPI_MSTR_CLK16 0x01 /* chip clock/16 */
#define SPI_MSTR_CLK64 0x02 /* chip clock/64 */
#define SPI_MSTR_CLK128 0x03 /* chip clock/128 */
#define SPI_MSTR_CLK2 0x04 /* chip clock/2 */
#define SPI_MSTR_CLK8 0x05 /* chip clock/8 */
#define SPI_MSTR_CLK32 0x06 /* chip clock/32 */
// setup spi
void setup_spi(uint8_t mode, // timing mode SPI_MODE[0-4]
int dord, // data direction SPI_LSB|SPI_MSB
int interrupt, // whether to raise interrupt on recieve
uint8_t clock); // clock diviser
// disable spi
void disable_spi(void);
// send and receive a byte of data (master mode)
uint8_t send_spi(uint8_t out);
// receive the byte of data waiting on the SPI buffer and
// set the next byte to transfer - for use in slave mode
// when interrupts are enabled.
uint8_t received_from_spi(uint8_t out);
#ifdef __cplusplus
} // extern "C"
#endif
#endif