Skip to content

Instantly share code, notes, and snippets.

@xqms
Created November 5, 2011 16:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xqms/1341745 to your computer and use it in GitHub Desktop.
Save xqms/1341745 to your computer and use it in GitHub Desktop.
avr-g++ -mmcu=atmega32 -fno-exceptions -fno-rtti -O2 -o file.elf file.cpp
void spi_bb_init(void)
{
/* Drive CS high (inactive) */
SPI_BB_CS_PORT |= (1 << SPI_BB_CS_NUM);
SPI_BB_CLOCK_PORT &= ~(1 << SPI_BB_CLOCK_NUM);
/* Set pins as output */
SPI_BB_CS_DDR |= (1 << SPI_BB_CS_NUM);
SPI_BB_DATA_DDR |= (1 << SPI_BB_DATA_NUM);
SPI_BB_CLOCK_DDR |= (1 << SPI_BB_CLOCK_DDR);
}
void spi_bb_write(uint8_t value)
{
uint8_t i;
SPI_BB_CS_PORT &= ~(1 << SPI_BB_CS_NUM);
for(i = 0; i < 8; ++i)
{
if(value & (1 << i))
SPI_BB_DATA_PORT |= (1 << SPI_BB_DATA_NUM);
else
SPI_BB_DATA_PORT &= ~(1 << SPI_BB_DATA_NUM);
/* Well, we would need delays or something here, but just
pretend our slave can deal with our fast irregular output */
SPI_BB_CLOCK_PORT |= (1 << SPI_BB_CLOCK_NUM);
SPI_BB_CLOCK_PORT &= ~(1 << SPI_BB_CLOCK_NUM);
}
SPI_BB_CS_PORT |= (1 << SPI_BB_CS_NUM);
}
#define SPI_BB_CLOCK_PORT PORTA
#define SPI_BB_CLOCK_DDR DDRA
#define SPI_BB_CLOCK_NUM 4
#define SPI_BB_DATA_PORT PORTA
#define SPI_BB_DATA_DDR DDRA
#define SPI_BB_DATA_NUM 5
#define SPI_BB_CS_PORT PORTA
#define SPI_BB_CS_DDR DDRA
#define SPI_BB_CS_NUM 6
void spi_bb_init(void);
void spi_bb_write(uint8_t value);
#include <avrlib/portdef.h>
template<class ClockPin, class DataPin, class CSPin>
class SPIBitBang
{
public:
static void init()
{
CSPin(1); // Drive high (inactive)
ClockPin(0);
avr::setOutput()
<< ClockPin()
<< DataPin()
<< CSPin()
;
}
static void write(uint8_t value)
{
CSPin(0);
for(uint8_t i = 0; i < 8; ++i)
{
DataPin(value & (1 << i));
ClockPin(1);
ClockPin(0);
}
CSPin(1);
}
};
#include "cpp_spi_bitbang.h"
namespace pins
{
using namespace avr;
typedef Pin<PortA, 4> Clock;
typedef Pin<PortA, 5> Data;
typedef Pin<PortA, 6> CS;
}
typedef SPIBitBang<pins::Clock, pins::Data, pins::CS> SPI;
int main()
{
SPI::init();
SPI::write(0xFF);
}
6c: sbi 0x1b, 6 ; 27
6e: cbi 0x1b, 4 ; 27
70: in r24, 0x1a ; 26
72: ori r24, 0x70 ; 112
74: out 0x1a, r24 ; 26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment