102 lines
2.2 KiB
C++
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_ */ |