Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for SPI with hardware USI on ATtiny devices #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/mcp2515_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
#include "utils.h"

#include "can_private.h"
#include "spi.h"

// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -81,14 +80,20 @@
#define P_MOSI B,0
#define P_MISO B,1
#define P_SCK B,2

#define USE_SOFTWARE_SPI 1
#define SUPPORT_FOR_MCP2515__
#elif defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
#define P_MOSI A,5
#define P_MISO A,6
#define P_SCK A,4
#define SUPPORT_FOR_MCP2515__
#else
#error choosen AVR-type is not supported yet!
#endif
#endif

#include "spi.h"


#ifdef SUPPORT_FOR_MCP2515__

Expand Down
32 changes: 2 additions & 30 deletions src/mcp2515_write_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,7 @@

#include "mcp2515_private.h"
#ifdef SUPPORT_FOR_MCP2515__

// ----------------------------------------------------------------------------
#ifdef USE_SOFTWARE_SPI

static uint8_t usi_interface_spi_temp;

static void spi_start(uint8_t data) {
usi_interface_spi_temp = spi_putc(data);
}

static uint8_t spi_wait(void) {
return usi_interface_spi_temp;
}

#else

static void spi_start(uint8_t data) {
SPDR = data;
}

static uint8_t spi_wait(void) {
// warten bis der vorherige Werte geschrieben wurde
while(!(SPSR & (1<<SPIF)))
;

return SPDR;
}

#endif
#include "spi.h"

// ----------------------------------------------------------------------------
/* Schreibt eine CAN ID in die Register des MCP2515
Expand Down Expand Up @@ -124,7 +96,7 @@ void mcp2515_write_id(const uint32_t *id, uint8_t extended)
}
}

#else
#else // USE_EXTENDED_CANID

void mcp2515_write_id(const uint16_t *id)
{
Expand Down
21 changes: 13 additions & 8 deletions src/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,28 @@
#error SPI_PRESCALER not defined!
#endif

#ifdef USE_SOFTWARE_SPI
uint8_t usi_interface_spi_temp;
#endif


// ----------------------------------------------------------------------------
void mcp2515_spi_init(void)
{
#ifndef USE_SOFTWARE_SPI
// Aktivieren des SPI Master Interfaces
#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);
#else
SPCR = (1<<SPE)|(1<<MSTR) | R_SPCR;
SPSR = R_SPSR;
#endif
#endif
#endif /* !USE_SOFTWARE_SPI */
}

// ----------------------------------------------------------------------------
// Schreibt/liest ein Byte ueber den Hardware SPI Bus
// \return gelesene Daten

uint8_t spi_putc(uint8_t data)
{
Expand Down Expand Up @@ -107,13 +116,9 @@ uint8_t spi_putc(uint8_t data)
#else

// put byte in send-buffer
SPDR = data;

// wait until byte was send
while( !( SPSR & (1<<SPIF) ) )
;

return SPDR;
spi_start(data);
// wait until byte was send
return spi_wait();

#endif
}
Expand Down
23 changes: 21 additions & 2 deletions src/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extern uint8_t spi_putc(uint8_t data);
// ----------------------------------------------------------------------------
#ifdef USE_SOFTWARE_SPI

static uint8_t usi_interface_spi_temp;
extern uint8_t usi_interface_spi_temp;

extern __attribute__ ((gnu_inline)) inline void spi_start(uint8_t data) {
usi_interface_spi_temp = spi_putc(data);
Expand All @@ -71,18 +71,37 @@ extern __attribute__ ((gnu_inline)) inline uint8_t spi_wait(void) {

#else

/** Initiate SPI write transfer
* \param data The data to transfer
*/
extern __attribute__ ((gnu_inline)) inline void spi_start(uint8_t data) {
#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
USIDR = data; // Daten in Data Register laden
USISR |= (1<<USIOIF); // Überlaufflag löschen
#else
SPDR = data;
#endif
}

/** Wait for SPI to complete operation (all data transferred)
* \return data received from SPI
*/
extern __attribute__ ((gnu_inline)) inline uint8_t spi_wait(void) {
// warten bis der vorherige Werte geschrieben wurde
#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
while(!(USISR & (1<<USIOIF))) {
USICR |= (1<<USITC); // toggle clk
}

return USIDR;
#else
while(!(SPSR & (1<<SPIF)))
;

return SPDR;
#endif
}

#endif
#endif // !USE_SOFTWARE_SPI

#endif // SPI_H