Hacker-Jeopardy/Button/Button/Spi.hpp
2013-11-12 17:10:21 +00:00

102 lines
2.2 KiB
C++

/*
* Spi.h
*
* Created: 06.11.2013 15:41:34
* Author: netz
*/
#ifndef SPI_H_
#define SPI_H_
#include "config.h"
#include <avr/io.h>
#include <util/delay.h>
#include "pin.hpp"
template <typename Port, int cspin, int misopin, int mosipin, int sckpin, int mode, typename uart>
class Spi {
public:
Spi() {
init();
}
void CSOn() {
cs::make_low();
}
void CSOff() {
cs::make_high();
}
uint8_t send(uint8_t data) {
char t[50];
sprintf(t, "-> 0x%02x", data);
u.send(t);
uint8_t r;
if(mode == 0) {
r = send_hard(data);
}
r = send_soft(data);
sprintf(t, " <- 0x%02x\r\n", r);
u.send(t);
return r;
}
private:
uart u;
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() {
init_port();
if(mode == 0) {
init_spi();
}
}
void init_port() {
mosi::make_output();
mosi::make_low();
sck::make_output();
sck::make_low();
cs::make_output();
cs::make_high();
miso::make_input();
miso::make_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 a=8; a>0; a--) { //das Byte wird Bitweise nacheinander Gesendet MSB zuerst
datain<<=1; //Schieben um das Richtige Bit zusetzen
sck::make_low(); // Clock auf LOW
if (data & 0x80) { //Ist Bit a in Byte gesetzt
mosi::make_high(); //Set Output High
}
else{
mosi::make_low(); //Set Output Low
}
_delay_us(1);
if(miso::read()) //Lesen des Pegels
{
datain |= 1;
}
_delay_us(1);
sck::make_high(); // Clock auf High
_delay_us(2);
data<<=1; //Schiebe um nächstes Bit zusenden
}
return datain;
}
uint8_t send_hard(uint8_t data) {
// Sendet ein Byte
SPDR = data;
// Wartet bis Byte gesendet wurde
loop_until_bit_is_set(SPSR, SPIF);
return SPDR;
}
};
#endif /* SPI_H_ */