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

Fix SPI1 slave select #13

Closed
wants to merge 2 commits into from
Closed
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# OS generated files #
######################
.DS_Store

30 changes: 15 additions & 15 deletions hardware/atmega328pb/avr/libraries/SPI1/src/SPI1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright (c) 2014 by Paul Stoffregen <[email protected]> (Transaction API)
* Copyright (c) 2014 by Matthijs Kooijman <[email protected]> (SPISettings AVR)
* Copyright (c) 2014 by Andrew J. Kroll <[email protected]> (atomicity fixes)
* Copyright (c) 2014 by Andre Moehl [email protected] (SPI1 Class, for Atmega3258PB Support)
* Copyright (c) 2014 by Andre Moehl [email protected] (SPI1 Class, for ATmega328PB Support)
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -32,28 +32,28 @@ void SPI1Class::begin()
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
if (!initialized) {
// Set SS to high so a connected chip will be "deselected" by default
uint8_t port = digitalPinToPort(SS);
uint8_t bit = digitalPinToBitMask(SS);
// Set SS1 to high so a connected chip will be "deselected" by default
uint8_t port = digitalPinToPort(SS1);
uint8_t bit = digitalPinToBitMask(SS1);
volatile uint8_t *reg = portModeRegister(port);

// if the SS pin is not already configured as an output
// if the SS1 pin is not already configured as an output
// then set it high (to enable the internal pull-up resistor)
if(!(*reg & bit)){
digitalWrite(SS, HIGH);
digitalWrite(SS1, HIGH);
}

// When the SS pin is set as OUTPUT, it can be used as
// When the SS1 pin is set as OUTPUT, it can be used as
// a general purpose output port (it doesn't influence
// SPI operations).
pinMode(SS, OUTPUT);
pinMode(SS1, OUTPUT);

// Warning: if the SS pin ever becomes a LOW INPUT then SPI
// Warning: if the SS1 pin ever becomes a LOW INPUT then SPI
// automatically switches to Slave, so the data direction of
// the SS pin MUST be kept as OUTPUT.
// the SS1 pin MUST be kept as OUTPUT.
#if defined(__AVR_ATmega328PB__)
SPCR1 |= _BV(MSTR);
SPCR1 |= _BV(SPE);
SPCR1 |= _BV(MSTR1);
SPCR1 |= _BV(SPE1);
#endif

// Set direction register for SCK and MOSI pin.
Expand All @@ -69,18 +69,18 @@ void SPI1Class::begin()
SREG = sreg;
}

void SPI1Class::end()
void SPI1Class::end()
{
uint8_t sreg = SREG;
noInterrupts(); // Protect from a scheduler and prevent transactionBegin
// Decrease the reference counter
if (initialized)
initialized--;
// If there are no more references disable SPI
if (!initialized)
if (!initialized)
{
#if defined(__AVR_ATmega328PB__)
SPCR0 &= ~_BV(SPE);
SPCR0 &= ~_BV(SPE1);
#endif
interruptMode = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
Expand Down
52 changes: 26 additions & 26 deletions hardware/atmega328pb/avr/libraries/SPI1/src/SPI1.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Copyright (c) 2014 by Paul Stoffregen <[email protected]> (Transaction API)
* Copyright (c) 2014 by Matthijs Kooijman <[email protected]> (SPISettings AVR)
* Copyright (c) 2014 by Andrew J. Kroll <[email protected]> (atomicity fixes)
* Copyright (c) 2014 by Andre Moehl [email protected] (SPI1 Class, for Atmega3258PB Support)
* Copyright (c) 2014 by Andre Moehl [email protected] (SPI1 Class, for ATmega328PB Support)
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
Expand All @@ -21,29 +21,29 @@
/* SPI 1 Class *****************************************************/
class SPI1Settings {
public:
SPI1Settings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
SPI1Settings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
{
if (__builtin_constant_p(clock))
if (__builtin_constant_p(clock))
{
init_AlwaysInline(clock, bitOrder, dataMode);
} else
} else
{
init_MightInline(clock, bitOrder, dataMode);
}
}
SPI1Settings()

SPI1Settings()
{
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
}

private:
void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
{
init_AlwaysInline(clock, bitOrder, dataMode);
}
void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) __attribute__((__always_inline__))

void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) __attribute__((__always_inline__))
{
// Clock settings are defined as follows. Note that this shows SPI2X
// inverted, so the bits form increasing numbers. Also note that
Expand Down Expand Up @@ -102,7 +102,7 @@ class SPI1Settings {

// Pack into the SPI1Settings class
#if defined(__AVR_ATmega328PB__)
spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
spcr = _BV(SPE1) | _BV(MSTR1) | ((bitOrder == LSBFIRST) ? _BV(DORD1) : 0) |
(dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
#endif
}
Expand All @@ -111,7 +111,7 @@ class SPI1Settings {
friend class SPI1Class;
};

class SPI1Class
class SPI1Class
{
public:
// Initialize the SPI library
Expand Down Expand Up @@ -182,56 +182,56 @@ class SPI1Class
#endif
}

inline static uint16_t transfer16(uint16_t data)
inline static uint16_t transfer16(uint16_t data)
{
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
in.val = data;
#if defined(__AVR_ATmega328PB__)
if (!(SPCR1 & _BV(DORD))) {
if (!(SPCR1 & _BV(DORD1))) {
SPDR1 = in.msb;
asm volatile("nop"); // See transfer(uint8_t) function
while (!(SPSR1 & _BV(SPIF))) ;
while (!(SPSR1 & _BV(SPIF1))) ;
out.msb = SPDR1;
SPDR1 = in.lsb;
asm volatile("nop");
while (!(SPSR1 & _BV(SPIF))) ;
while (!(SPSR1 & _BV(SPIF1))) ;
out.lsb = SPDR1;
} else {
SPDR1 = in.lsb;
asm volatile("nop");
while (!(SPSR1 & _BV(SPIF))) ;
while (!(SPSR1 & _BV(SPIF1))) ;
out.lsb = SPDR1;
SPDR1 = in.msb;
asm volatile("nop");
while (!(SPSR1 & _BV(SPIF))) ;
while (!(SPSR1 & _BV(SPIF1))) ;
out.msb = SPDR1;
}
#endif
return out.val;
}

inline static void transfer(void *buf, size_t count)
inline static void transfer(void *buf, size_t count)
{
if (count == 0) return;
uint8_t *p = (uint8_t *)buf;
#if defined(__AVR_ATmega328PB__)
SPDR1 = *p;
while (--count > 0) {
uint8_t out = *(p + 1);
while (!(SPSR1 & _BV(SPIF))) ;
while (!(SPSR1 & _BV(SPIF1))) ;
uint8_t in = SPDR1;
SPDR1 = out;
*p++ = in;
}
while (!(SPSR1 & _BV(SPIF))) ;
while (!(SPSR1 & _BV(SPIF1))) ;
*p = SPDR1;

#endif
}

// After performing a group of transfers and releasing the chip select
// signal, this function allows others to access the SPI bus
inline static void endTransaction(void)
inline static void endTransaction(void)
{
#ifdef SPI_TRANSACTION_MISMATCH_LED
if (!inTransactionFlag) {
Expand Down Expand Up @@ -263,11 +263,11 @@ class SPI1Class

// This function is deprecated. New applications should use
// beginTransaction() to configure SPI settings.
inline static void setBitOrder(uint8_t bitOrder)
inline static void setBitOrder(uint8_t bitOrder)
{
#if defined(__AVR_ATmega328PB__)
if (bitOrder == LSBFIRST) SPCR1 |= _BV(DORD);
else SPCR1 &= ~(_BV(DORD));
if (bitOrder == LSBFIRST) SPCR1 |= _BV(DORD1);
else SPCR1 &= ~(_BV(DORD1));
#endif
}

Expand All @@ -276,8 +276,8 @@ class SPI1Class
// polls the hardware flag which is automatically cleared as the
// AVR responds to SPI's interrupt
#if defined(__AVR_ATmega328PB__)
inline static void attachInterrupt() { SPCR1 |= _BV(SPIE ); }
inline static void detachInterrupt() { SPCR1 &= ~_BV(SPIE); }
inline static void attachInterrupt() { SPCR1 |= _BV(SPIE1); }
inline static void detachInterrupt() { SPCR1 &= ~_BV(SPIE1); }
#endif

private:
Expand Down