Zeitschaltung/V6/Program/rfm12_rs232/Zeitschaltung_V6/io/Spi.hpp

86 lines
1.7 KiB
C++
Raw Normal View History

2014-05-21 18:10:07 +02:00
/*
* Spi.h
*
* Created: 06.11.2013 15:41:34
* Author: netz
*/
#ifndef SPI_H_
#define SPI_H_
#include <avr/io.h>
#include <util/delay.h>
#include "hardware/pin.hpp"
template <typename Port, int cspin, int misopin, int mosipin, int sckpin, int mode>
class Spi {
public:
Spi() {
this->init();
}
void CSOn() {
cs::make_low();
}
void CSOff() {
cs::make_high();
}
uint8_t send(uint8_t data) {
if(mode == 0) {
return this->send_hard(data);
}
return this->send_soft(data);
}
uint8_t has_data() {
return !miso::read();
}
private:
const typedef avrlib::pin<Port, cspin> cs;
const typedef avrlib::pin<Port, misopin> miso;
const typedef avrlib::pin<Port, mosipin> mosi;
const typedef avrlib::pin<Port, sckpin> sck;
void init() {
this->init_port();
if(mode == 0) {
this->init_spi();
}
}
void init_port() {
mosi::make_low(); //output und low;
sck::make_low(); //output und low;
cs::make_high(); //output und low;
miso::make_input(); //input und low;
}
void init_spi() {
SPCR = (1<<SPE) | (1<<MSTR);
SPSR = (1<<SPI2X);
}
uint8_t send_soft(uint8_t data) {
uint8_t datain=0;
for (uint8_t i=0; i<8; i++)
{
if (data & 0x80) {
mosi::make_high();
}
else {
mosi::make_low();
}
datain <<= 1;
if(miso::read()) {
datain |= 1;
}
sck::make_high();
data<<=1;
_delay_us(0.3);
sck::make_low();
}
return datain;
}
uint8_t send_hard(uint8_t data) {
SPDR = data; // Sendet ein Byte
loop_until_bit_is_set(SPSR, SPIF); // Wartet bis Byte gesendet wurde
return SPDR;
}
};
#endif /* SPI_H_ */