Update HAL and libs formatting

This commit is contained in:
Scott Lahteine 2018-11-10 17:51:49 -06:00
parent 47483e8c17
commit 4e0c935959
11 changed files with 620 additions and 656 deletions

View file

@ -145,8 +145,8 @@ static const UnwindCallbacks UnwCallbacks = {
UnwReadW, UnwReadW,
UnwReadH, UnwReadH,
UnwReadB UnwReadB
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
,UnwPrintf , UnwPrintf
#endif #endif
}; };

View file

@ -118,7 +118,7 @@ static const UnwindCallbacks UnwCallbacks = {
UnwReadW, UnwReadW,
UnwReadH, UnwReadH,
UnwReadB UnwReadB
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
,UnwPrintf ,UnwPrintf
#endif #endif
}; };

View file

@ -45,7 +45,7 @@
#define FTM3_CH5_PIN 36 #define FTM3_CH5_PIN 36
#define FTM3_CH6_PIN 37 #define FTM3_CH6_PIN 37
#define FTM3_CH7_PIN 38 #define FTM3_CH7_PIN 38
#if defined(__MK66FX1M0__) // Teensy3.6 #ifdef __MK66FX1M0__ // Teensy3.6
#define TPM1_CH0_PIN 16 #define TPM1_CH0_PIN 16
#define TPM1_CH1_PIN 17 #define TPM1_CH1_PIN 17
#endif #endif

View file

@ -23,7 +23,7 @@
#include "unwarm.h" #include "unwarm.h"
#include "unwarmmem.h" #include "unwarmmem.h"
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
/** /**
* Printf wrapper. * Printf wrapper.

View file

@ -106,7 +106,7 @@ typedef struct {
#define M_IsOriginValid(v) (((v) & 0x7F) ? true : false) #define M_IsOriginValid(v) (((v) & 0x7F) ? true : false)
#define M_Origin2Str(v) ((v) ? "VALID" : "INVALID") #define M_Origin2Str(v) ((v) ? "VALID" : "INVALID")
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
#define UnwPrintd1(a) state->cb->printf(a) #define UnwPrintd1(a) state->cb->printf(a)
#define UnwPrintd2(a,b) state->cb->printf(a,b) #define UnwPrintd2(a,b) state->cb->printf(a,b)
#define UnwPrintd3(a,b,c) state->cb->printf(a,b,c) #define UnwPrintd3(a,b,c) state->cb->printf(a,b,c)

View file

@ -142,7 +142,7 @@ UnwResult UnwStartArm(UnwState * const state) {
/* MRS */ /* MRS */
else if ((instr & 0xFFBF0FFF) == 0xE10F0000) { else if ((instr & 0xFFBF0FFF) == 0xE10F0000) {
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
bool R = (instr & 0x00400000) ? true : false; bool R = (instr & 0x00400000) ? true : false;
#endif #endif
uint8_t rd = (instr & 0x0000F000) >> 12; uint8_t rd = (instr & 0x0000F000) >> 12;
@ -154,7 +154,7 @@ UnwResult UnwStartArm(UnwState * const state) {
} }
/* MSR */ /* MSR */
else if ((instr & 0xFFB0F000) == 0xE120F000) { else if ((instr & 0xFFB0F000) == 0xE120F000) {
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
bool R = (instr & 0x00400000) ? true : false; bool R = (instr & 0x00400000) ? true : false;
UnwPrintd2("MSR %s_?, ???", R ? "SPSR" : "CPSR"); UnwPrintd2("MSR %s_?, ???", R ? "SPSR" : "CPSR");
@ -172,7 +172,7 @@ UnwResult UnwStartArm(UnwState * const state) {
else if (isDataProc(instr)) { else if (isDataProc(instr)) {
bool I = (instr & 0x02000000) ? true : false; bool I = (instr & 0x02000000) ? true : false;
uint8_t opcode = (instr & 0x01E00000) >> 21; uint8_t opcode = (instr & 0x01E00000) >> 21;
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
bool S = (instr & 0x00100000) ? true : false; bool S = (instr & 0x00100000) ? true : false;
#endif #endif
uint8_t rn = (instr & 0x000F0000) >> 16; uint8_t rn = (instr & 0x000F0000) >> 16;
@ -220,7 +220,7 @@ UnwResult UnwStartArm(UnwState * const state) {
uint8_t regShift = (operand2 & 0x0010) ? true : false; uint8_t regShift = (operand2 & 0x0010) ? true : false;
uint8_t shiftType = (operand2 & 0x0060) >> 5; uint8_t shiftType = (operand2 & 0x0060) >> 5;
uint32_t shiftDist; uint32_t shiftDist;
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
const char * const shiftMnu[4] = { "LSL", "LSR", "ASR", "ROR" }; const char * const shiftMnu[4] = { "LSL", "LSR", "ASR", "ROR" };
#endif #endif
UnwPrintd2("r%d ", rm); UnwPrintd2("r%d ", rm);
@ -453,7 +453,7 @@ UnwResult UnwStartArm(UnwState * const state) {
bool addrValid = M_IsOriginValid(state->regData[baseReg].o); bool addrValid = M_IsOriginValid(state->regData[baseReg].o);
int8_t r; int8_t r;
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
/* Display the instruction */ /* Display the instruction */
if (L) { if (L) {
UnwPrintd6("LDM%c%c r%d%s, {reglist}%s\n", P ? 'E' : 'F', U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : ""); UnwPrintd6("LDM%c%c r%d%s, {reglist}%s\n", P ? 'E' : 'F', U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : "");

View file

@ -680,7 +680,7 @@ UnwResult UnwStartThumb(UnwState * const state) {
uint8_t rs = (instr & 0x0038) >> 3; uint8_t rs = (instr & 0x0038) >> 3;
uint8_t rd = (instr & 0x0007); uint8_t rd = (instr & 0x0007);
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
static const char * const mnu[16] = { static const char * const mnu[16] = {
"AND", "EOR", "LSL", "LSR", "AND", "EOR", "LSL", "LSR",
"ASR", "ADC", "SBC", "ROR", "ASR", "ADC", "SBC", "ROR",

View file

@ -90,7 +90,7 @@ bool UnwMemHashWrite(MemData * const memData, uint32_t addr, uint32_t val, bool
M_SetIdxUsed(memData->tracked, i); M_SetIdxUsed(memData->tracked, i);
} }
else { else {
#if defined(UNW_DEBUG) #ifdef UNW_DEBUG
memData->v[i] = 0xDEADBEEF; memData->v[i] = 0xDEADBEEF;
#endif #endif
M_ClrIdxUsed(memData->tracked, i); M_ClrIdxUsed(memData->tracked, i);

View file

@ -1,5 +1,5 @@
/** /**
* @file lcdprint_hd44780.c * @file lcdprint_hd44780.cpp
* @brief LCD print api for HD44780 * @brief LCD print api for HD44780
* @author Yunhui Fu (yhfudev@gmail.com) * @author Yunhui Fu (yhfudev@gmail.com)
* @version 1.0 * @version 1.0
@ -39,7 +39,7 @@ typedef struct _hd44780_charmap_t {
uint8_t idx2; // the char used to be combined with the idx to simulate a single char uint8_t idx2; // the char used to be combined with the idx to simulate a single char
} hd44780_charmap_t; } hd44780_charmap_t;
#if defined(__AVR__) #ifdef __AVR__
#define IV(a) U##a #define IV(a) U##a
#else #else
#define IV(a) L##a #define IV(a) L##a

View file

@ -1,5 +1,5 @@
/** /**
* @file lcdprint_u8g.c * @file lcdprint_u8g.cpp
* @brief LCD print api for u8glib * @brief LCD print api for u8glib
* @author Yunhui Fu (yhfudev@gmail.com) * @author Yunhui Fu (yhfudev@gmail.com)
* @version 1.0 * @version 1.0

View file

@ -1,78 +1,93 @@
//https://github.com/niteris/ArduinoSoftSpi // https://github.com/niteris/ArduinoSoftSpi
#include <Arduino.h> #include <Arduino.h>
#ifndef FORCE_INLINE
#define FORCE_INLINE inline __attribute__((always_inline))
#endif
#ifndef _BV
#define _BV(B) (1 << (B))
#define SBI(A,B) (A |= (1 << (B)))
#define CBI(A,B) (A &= ~(1 << (B)))
#endif
#define nop __asm__ volatile ("nop") // NOP for timing
#ifdef __arm__ #ifdef __arm__
#ifdef CORE_TEENSY
//------------------------------------------------------------------------------ #ifdef CORE_TEENSY
/** read pin value
/**
* Read pin value
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* @return value read * @return value read
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static bool fastDigitalRead(uint8_t pin) {
bool fastDigitalRead(uint8_t pin) {
return *portInputRegister(pin); return *portInputRegister(pin);
} }
//------------------------------------------------------------------------------
/** Set pin value /**
* Set pin value
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* @param[in] level value to write * @param[in] level value to write
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static void fastDigitalWrite(uint8_t pin, bool value) {
void fastDigitalWrite(uint8_t pin, bool value) {
if (value) if (value)
*portSetRegister(pin) = 1; *portSetRegister(pin) = 1;
else else
*portClearRegister(pin) = 1; *portClearRegister(pin) = 1;
} }
#else // CORE_TEENSY
//------------------------------------------------------------------------------ #else // !CORE_TEENSY
/** read pin value
/**
* Read pin value
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* @return value read * @return value read
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static bool fastDigitalRead(uint8_t pin) {
bool fastDigitalRead(uint8_t pin) {
return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin; return g_APinDescription[pin].pPort->PIO_PDSR & g_APinDescription[pin].ulPin;
} }
//------------------------------------------------------------------------------
/** Set pin value /**
* Set pin value
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* @param[in] level value to write * @param[in] level value to write
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static void fastDigitalWrite(uint8_t pin, bool value) {
void fastDigitalWrite(uint8_t pin, bool value) {
if (value) if (value)
g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin; g_APinDescription[pin].pPort->PIO_SODR = g_APinDescription[pin].ulPin;
else else
g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin; g_APinDescription[pin].pPort->PIO_CODR = g_APinDescription[pin].ulPin;
} }
#endif // CORE_TEENSY
//------------------------------------------------------------------------------ #endif // !CORE_TEENSY
inline void fastDigitalToggle(uint8_t pin) {
fastDigitalWrite(pin, !fastDigitalRead(pin)); inline void fastDigitalToggle(uint8_t pin) { fastDigitalWrite(pin, !fastDigitalRead(pin)); }
}
//------------------------------------------------------------------------------ inline void fastPinMode(uint8_t pin, bool mode) { pinMode(pin, mode); }
inline void fastPinMode(uint8_t pin, bool mode) {pinMode(pin, mode);}
#else // __arm__ #else // !__arm__
#include <avr/io.h>
#include <util/atomic.h> #include <avr/io.h>
//------------------------------------------------------------------------------ #include <util/atomic.h>
/**
/**
* @class pin_map_t * @class pin_map_t
* @brief struct for mapping digital pins * @brief struct for mapping digital pins
*/ */
struct pin_map_t { struct pin_map_t {
volatile uint8_t* ddr; /**< address of DDR for this pin */ volatile uint8_t* ddr; /**< address of DDR for this pin */
volatile uint8_t* pin; /**< address of PIN for this pin */ volatile uint8_t* pin; /**< address of PIN for this pin */
volatile uint8_t* port; /**< address of PORT for this pin */ volatile uint8_t* port; /**< address of PORT for this pin */
uint8_t bit; /**< bit number for this pin */ uint8_t bit; /**< bit number for this pin */
}; };
//------------------------------------------------------------------------------
#if defined(__AVR_ATmega168__)\ #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
||defined(__AVR_ATmega168P__)\
||defined(__AVR_ATmega328P__) // 168 and 328 Arduinos
// 168 and 328 Arduinos const static pin_map_t pinMap[] = {
const static pin_map_t pinMap[] = {
{&DDRD, &PIND, &PORTD, 0}, // D0 0 {&DDRD, &PIND, &PORTD, 0}, // D0 0
{&DDRD, &PIND, &PORTD, 1}, // D1 1 {&DDRD, &PIND, &PORTD, 1}, // D1 1
{&DDRD, &PIND, &PORTD, 2}, // D2 2 {&DDRD, &PIND, &PORTD, 2}, // D2 2
@ -93,12 +108,12 @@ const static pin_map_t pinMap[] = {
{&DDRC, &PINC, &PORTC, 3}, // C3 17 {&DDRC, &PINC, &PORTC, 3}, // C3 17
{&DDRC, &PINC, &PORTC, 4}, // C4 18 {&DDRC, &PINC, &PORTC, 4}, // C4 18
{&DDRC, &PINC, &PORTC, 5} // C5 19 {&DDRC, &PINC, &PORTC, 5} // C5 19
}; };
//------------------------------------------------------------------------------
#elif defined(__AVR_ATmega1280__)\ #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|| defined(__AVR_ATmega2560__)
// Mega // Mega
static const pin_map_t pinMap[] = { static const pin_map_t pinMap[] = {
{&DDRE, &PINE, &PORTE, 0}, // E0 0 {&DDRE, &PINE, &PORTE, 0}, // E0 0
{&DDRE, &PINE, &PORTE, 1}, // E1 1 {&DDRE, &PINE, &PORTE, 1}, // E1 1
{&DDRE, &PINE, &PORTE, 4}, // E4 2 {&DDRE, &PINE, &PORTE, 4}, // E4 2
@ -170,7 +185,7 @@ static const pin_map_t pinMap[] = {
{&DDRK, &PINK, &PORTK, 6}, // K6 68 {&DDRK, &PINK, &PORTK, 6}, // K6 68
{&DDRK, &PINK, &PORTK, 7}, // K7 69 {&DDRK, &PINK, &PORTK, 7}, // K7 69
//pins_MIGHTYBOARD_REVE.h // pins_MIGHTYBOARD_REVE.h
{&DDRG, &PING, &PORTG, 4}, // G4 70 {&DDRG, &PING, &PORTG, 4}, // G4 70
{&DDRG, &PING, &PORTG, 3}, // G3 71 {&DDRG, &PING, &PORTG, 3}, // G3 71
{&DDRJ, &PINJ, &PORTJ, 2}, // J2 72 {&DDRJ, &PINJ, &PORTJ, 2}, // J2 72
@ -181,21 +196,17 @@ static const pin_map_t pinMap[] = {
{&DDRJ, &PINJ, &PORTJ, 6}, // J6 77 {&DDRJ, &PINJ, &PORTJ, 6}, // J6 77
{&DDRE, &PINE, &PORTE, 2}, // E2 78 {&DDRE, &PINE, &PORTE, 2}, // E2 78
{&DDRE, &PINE, &PORTE, 6} // E6 79 {&DDRE, &PINE, &PORTE, 6} // E6 79
};
}; #elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__) \
//------------------------------------------------------------------------------ || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) \
#elif defined(__AVR_ATmega1284P__)\ || defined(__AVR_ATmega64__) || defined(__AVR_ATmega32__) \
|| defined(__AVR_ATmega1284__)\ || defined(__AVR_ATmega324__) || defined(__AVR_ATmega16__)
|| defined(__AVR_ATmega644P__)\
|| defined(__AVR_ATmega644__)\
|| defined(__AVR_ATmega64__)\
|| defined(__AVR_ATmega32__)\
|| defined(__AVR_ATmega324__)\
|| defined(__AVR_ATmega16__)
#ifdef VARIANT_MIGHTY #ifdef VARIANT_MIGHTY
// Mighty Layout
static const pin_map_t pinMap[] = { // Mighty Layout
static const pin_map_t pinMap[] = {
{&DDRB, &PINB, &PORTB, 0}, // B0 0 {&DDRB, &PINB, &PORTB, 0}, // B0 0
{&DDRB, &PINB, &PORTB, 1}, // B1 1 {&DDRB, &PINB, &PORTB, 1}, // B1 1
{&DDRB, &PINB, &PORTB, 2}, // B2 2 {&DDRB, &PINB, &PORTB, 2}, // B2 2
@ -228,10 +239,12 @@ static const pin_map_t pinMap[] = {
{&DDRA, &PINA, &PORTA, 5}, // A5 29 {&DDRA, &PINA, &PORTA, 5}, // A5 29
{&DDRA, &PINA, &PORTA, 6}, // A6 30 {&DDRA, &PINA, &PORTA, 6}, // A6 30
{&DDRA, &PINA, &PORTA, 7} // A7 31 {&DDRA, &PINA, &PORTA, 7} // A7 31
}; };
#elif defined(VARIANT_BOBUINO)
// Bobuino Layout #elif defined(VARIANT_BOBUINO)
static const pin_map_t pinMap[] = {
// Bobuino Layout
static const pin_map_t pinMap[] = {
{&DDRD, &PIND, &PORTD, 0}, // D0 0 {&DDRD, &PIND, &PORTD, 0}, // D0 0
{&DDRD, &PIND, &PORTD, 1}, // D1 1 {&DDRD, &PIND, &PORTD, 1}, // D1 1
{&DDRD, &PIND, &PORTD, 2}, // D2 2 {&DDRD, &PIND, &PORTD, 2}, // D2 2
@ -264,10 +277,12 @@ static const pin_map_t pinMap[] = {
{&DDRC, &PINC, &PORTC, 7}, // C7 29 {&DDRC, &PINC, &PORTC, 7}, // C7 29
{&DDRD, &PIND, &PORTD, 4}, // D4 30 {&DDRD, &PIND, &PORTD, 4}, // D4 30
{&DDRD, &PIND, &PORTD, 7} // D7 31 {&DDRD, &PIND, &PORTD, 7} // D7 31
}; };
#elif defined(VARIANT_STANDARD)
// Standard Layout #elif defined(VARIANT_STANDARD)
static const pin_map_t pinMap[] = {
// Standard Layout
static const pin_map_t pinMap[] = {
{&DDRB, &PINB, &PORTB, 0}, // B0 0 {&DDRB, &PINB, &PORTB, 0}, // B0 0
{&DDRB, &PINB, &PORTB, 1}, // B1 1 {&DDRB, &PINB, &PORTB, 1}, // B1 1
{&DDRB, &PINB, &PORTB, 2}, // B2 2 {&DDRB, &PINB, &PORTB, 2}, // B2 2
@ -300,15 +315,20 @@ static const pin_map_t pinMap[] = {
{&DDRA, &PINA, &PORTA, 2}, // A2 29 {&DDRA, &PINA, &PORTA, 2}, // A2 29
{&DDRA, &PINA, &PORTA, 1}, // A1 30 {&DDRA, &PINA, &PORTA, 1}, // A1 30
{&DDRA, &PINA, &PORTA, 0} // A0 31 {&DDRA, &PINA, &PORTA, 0} // A0 31
}; };
#else // VARIANT_MIGHTY
#error Undefined variant 1284, 644, 324, 64, 32 #else // !(VARIANT_MIGHTY || VARIANT_BOBUINO || VARIANT_STANDARD)
#endif // VARIANT_MIGHTY
//------------------------------------------------------------------------------ #error Undefined variant 1284, 644, 324, 64, 32
#elif defined(__AVR_ATmega32U4__)
#ifdef CORE_TEENSY #endif
// Teensy 2.0
static const pin_map_t pinMap[] = { #elif defined(__AVR_ATmega32U4__)
#ifdef CORE_TEENSY
// Teensy 2.0
static const pin_map_t pinMap[] = {
{&DDRB, &PINB, &PORTB, 0}, // B0 0 {&DDRB, &PINB, &PORTB, 0}, // B0 0
{&DDRB, &PINB, &PORTB, 1}, // B1 1 {&DDRB, &PINB, &PORTB, 1}, // B1 1
{&DDRB, &PINB, &PORTB, 2}, // B2 2 {&DDRB, &PINB, &PORTB, 2}, // B2 2
@ -334,11 +354,12 @@ static const pin_map_t pinMap[] = {
{&DDRD, &PIND, &PORTD, 4}, // D4 22 {&DDRD, &PIND, &PORTD, 4}, // D4 22
{&DDRD, &PIND, &PORTD, 5}, // D5 23 {&DDRD, &PIND, &PORTD, 5}, // D5 23
{&DDRE, &PINE, &PORTE, 6} // E6 24 {&DDRE, &PINE, &PORTE, 6} // E6 24
}; };
//------------------------------------------------------------------------------
#else // CORE_TEENSY #else // !CORE_TEENSY
// Leonardo
static const pin_map_t pinMap[] = { // Leonardo
static const pin_map_t pinMap[] = {
{&DDRD, &PIND, &PORTD, 2}, // D2 0 {&DDRD, &PIND, &PORTD, 2}, // D2 0
{&DDRD, &PIND, &PORTD, 3}, // D3 1 {&DDRD, &PIND, &PORTD, 3}, // D3 1
{&DDRD, &PIND, &PORTD, 1}, // D1 2 {&DDRD, &PIND, &PORTD, 1}, // D1 2
@ -369,13 +390,14 @@ static const pin_map_t pinMap[] = {
{&DDRB, &PINB, &PORTB, 5}, // B5 27 {&DDRB, &PINB, &PORTB, 5}, // B5 27
{&DDRB, &PINB, &PORTB, 6}, // B6 28 {&DDRB, &PINB, &PORTB, 6}, // B6 28
{&DDRD, &PIND, &PORTD, 6} // D6 29 {&DDRD, &PIND, &PORTD, 6} // D6 29
}; };
#endif // CORE_TEENSY
//------------------------------------------------------------------------------ #endif // !CORE_TEENSY
#elif defined(__AVR_AT90USB646__)\
|| defined(__AVR_AT90USB1286__) #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
// Teensy++ 1.0 & 2.0
static const pin_map_t pinMap[] = { // Teensy++ 1.0 & 2.0
static const pin_map_t pinMap[] = {
{&DDRD, &PIND, &PORTD, 0}, // D0 0 {&DDRD, &PIND, &PORTD, 0}, // D0 0
{&DDRD, &PIND, &PORTD, 1}, // D1 1 {&DDRD, &PIND, &PORTD, 1}, // D1 1
{&DDRD, &PIND, &PORTD, 2}, // D2 2 {&DDRD, &PIND, &PORTD, 2}, // D2 2
@ -422,232 +444,192 @@ static const pin_map_t pinMap[] = {
{&DDRF, &PINF, &PORTF, 5}, // F5 43 {&DDRF, &PINF, &PORTF, 5}, // F5 43
{&DDRF, &PINF, &PORTF, 6}, // F6 44 {&DDRF, &PINF, &PORTF, 6}, // F6 44
{&DDRF, &PINF, &PORTF, 7} // F7 45 {&DDRF, &PINF, &PORTF, 7} // F7 45
}; };
//------------------------------------------------------------------------------
#else // CPU type #else // CPU type
#error unknown CPU type
#endif // CPU type #error "Unknown CPU type for Software SPI"
//------------------------------------------------------------------------------
/** count of pins */ #endif // CPU type
static const uint8_t digitalPinCount = sizeof(pinMap)/sizeof(pin_map_t);
//============================================================================== /** count of pins */
/** generate bad pin number error */ static constexpr uint8_t digitalPinCount = sizeof(pinMap) / sizeof(pin_map_t);
void badPinNumber(void)
/** generate bad pin number error */
void badPinNumber(void)
__attribute__((error("Pin number is too large or not a constant"))); __attribute__((error("Pin number is too large or not a constant")));
//------------------------------------------------------------------------------
/** Check for valid pin number /**
* Check for valid pin number
* @param[in] pin Number of pin to be checked. * @param[in] pin Number of pin to be checked.
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static void badPinCheck(const uint8_t pin) {
void badPinCheck(uint8_t pin) { if (!__builtin_constant_p(pin) || pin >= digitalPinCount) badPinNumber();
if (!__builtin_constant_p(pin) || pin >= digitalPinCount) {
badPinNumber();
} }
}
//------------------------------------------------------------------------------ /**
/** fast write helper * Fast write helper
* @param[in] address I/O register address * @param[in] address I/O register address
* @param[in] bit bit number to write * @param[in] bit bit number to write
* @param[in] level value for bit * @param[in] level value for bit
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static void fastBitWriteSafe(volatile uint8_t* address, uint8_t bit, bool level) {
void fastBitWriteSafe(volatile uint8_t* address, uint8_t bit, bool level) {
uint8_t oldSREG; uint8_t oldSREG;
if (address > (uint8_t*)0x5F) { if (address > (uint8_t*)0x5F) { oldSREG = SREG; cli(); }
oldSREG = SREG; if (level) SBI(*address, bit); else CBI(*address, bit);
cli(); if (address > (uint8_t*)0x5F) SREG = oldSREG;
} }
if (level) {
*address |= 1 << bit; /**
} else { * Read pin value
*address &= ~(1 << bit);
}
if (address > (uint8_t*)0x5F) {
SREG = oldSREG;
}
}
//------------------------------------------------------------------------------
/** read pin value
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* @return value read * @return value read
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static bool fastDigitalRead(uint8_t pin) {
bool fastDigitalRead(uint8_t pin) {
badPinCheck(pin); badPinCheck(pin);
return (*pinMap[pin].pin >> pinMap[pin].bit) & 1; return (*pinMap[pin].pin >> pinMap[pin].bit) & 1;
} }
//------------------------------------------------------------------------------
/** toggle a pin /**
* Toggle a pin
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* *
* If the pin is in output mode toggle the pin level. * If the pin is in output mode toggle the pin level.
* If the pin is in input mode toggle the state of the 20K pullup. * If the pin is in input mode toggle the state of the 20K pullup.
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static void fastDigitalToggle(uint8_t pin) {
void fastDigitalToggle(uint8_t pin) {
badPinCheck(pin); badPinCheck(pin);
if (pinMap[pin].pin > (uint8_t*)0x5F) { if (pinMap[pin].pin > (uint8_t*)0x5F)
// must write bit to high address port *pinMap[pin].pin = _BV(pinMap[pin].bit); // Must write bit to high address port
*pinMap[pin].pin = 1 << pinMap[pin].bit; else
} else { SBI(*pinMap[pin].pin, pinMap[pin].bit); // Compiles to sbi and PIN register will not be read
// will compile to sbi and PIN register will not be read.
*pinMap[pin].pin |= 1 << pinMap[pin].bit;
} }
}
//------------------------------------------------------------------------------ /**
/** Set pin value * Set pin value
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* @param[in] level value to write * @param[in] level value to write
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static void fastDigitalWrite(uint8_t pin, bool level) {
void fastDigitalWrite(uint8_t pin, bool level) {
badPinCheck(pin); badPinCheck(pin);
fastBitWriteSafe(pinMap[pin].port, pinMap[pin].bit, level); fastBitWriteSafe(pinMap[pin].port, pinMap[pin].bit, level);
} }
//------------------------------------------------------------------------------
/** set pin mode /**
* Set pin mode
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* @param[in] mode if true set output mode else input mode * @param[in] mode if true set output mode else input mode
* *
* fastPinMode does not enable or disable the 20K pullup for input mode. * fastPinMode does not enable or disable the 20K pullup for input mode.
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static void fastPinMode(uint8_t pin, bool mode) {
void fastPinMode(uint8_t pin, bool mode) {
badPinCheck(pin); badPinCheck(pin);
fastBitWriteSafe(pinMap[pin].ddr, pinMap[pin].bit, mode); fastBitWriteSafe(pinMap[pin].ddr, pinMap[pin].bit, mode);
} }
#endif // __arm__ #endif // !__arm__
//------------------------------------------------------------------------------
/** set pin configuration /**
* Set pin configuration
* @param[in] pin Arduino pin number * @param[in] pin Arduino pin number
* @param[in] mode If true set output mode else input mode * @param[in] mode If true set output mode else input mode
* @param[in] level If mode is output, set level high/low. * @param[in] level If mode is output, set level high/low.
* If mode is input, enable or disable the pin's 20K pullup. * If mode is input, enable or disable the pin's 20K pullup.
*/ */
static inline __attribute__((always_inline)) FORCE_INLINE static void fastPinConfig(uint8_t pin, bool mode, bool level) {
void fastPinConfig(uint8_t pin, bool mode, bool level) {
fastPinMode(pin, mode); fastPinMode(pin, mode);
fastDigitalWrite(pin, level); fastDigitalWrite(pin, level);
} }
//==============================================================================
/** /**
* @class DigitalPin * @class DigitalPin
* @brief Fast digital port I/O * @brief Fast digital port I/O
*/ */
template<uint8_t PinNumber> template<uint8_t PinNumber>
class DigitalPin { class DigitalPin {
public: public:
//----------------------------------------------------------------------------
/** Constructor */ /** Constructor */
DigitalPin() {} DigitalPin() {}
//----------------------------------------------------------------------------
/** Constructor /**
* Constructor
* @param[in] pinMode if true set output mode else input mode. * @param[in] pinMode if true set output mode else input mode.
*/ */
explicit DigitalPin(bool pinMode) { explicit DigitalPin(bool pinMode) { mode(pinMode); }
mode(pinMode);
} /**
//---------------------------------------------------------------------------- * Constructor
/** Constructor
* @param[in] mode If true set output mode else input mode * @param[in] mode If true set output mode else input mode
* @param[in] level If mode is output, set level high/low. * @param[in] level If mode is output, set level high/low.
* If mode is input, enable or disable the pin's 20K pullup. * If mode is input, enable or disable the pin's 20K pullup.
*/ */
DigitalPin(bool mode, bool level) { DigitalPin(bool mode, bool level) { config(mode, level); }
config(mode, level);
} /**
//---------------------------------------------------------------------------- * Assignment operator
/** Asignment operator
* @param[in] value If true set the pin's level high else set the * @param[in] value If true set the pin's level high else set the
* pin's level low. * pin's level low.
* *
* @return This DigitalPin instance. * @return This DigitalPin instance.
*/ */
inline DigitalPin & operator = (bool value) __attribute__((always_inline)) { FORCE_INLINE DigitalPin & operator = (bool value) { write(value); return *this; }
write(value);
return *this; /**
} * Parentheses operator
//----------------------------------------------------------------------------
/** Parenthesis operator
* @return Pin's level * @return Pin's level
*/ */
inline operator bool () const __attribute__((always_inline)) { FORCE_INLINE operator bool () const { return read(); }
return read();
} /**
//---------------------------------------------------------------------------- * Set pin configuration
/** set pin configuration
* @param[in] mode If true set output mode else input mode * @param[in] mode If true set output mode else input mode
* @param[in] level If mode is output, set level high/low. * @param[in] level If mode is output, set level high/low.
* If mode is input, enable or disable the pin's 20K pullup. * If mode is input, enable or disable the pin's 20K pullup.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE void config(bool mode, bool level) { fastPinConfig(PinNumber, mode, level); }
void config(bool mode, bool level) {
fastPinConfig(PinNumber, mode, level);
}
//----------------------------------------------------------------------------
/** /**
* Set pin level high if output mode or enable 20K pullup if input mode. * Set pin level high if output mode or enable 20K pullup if input mode.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE void high() { write(true); }
void high() {write(true);}
//----------------------------------------------------------------------------
/** /**
* Set pin level low if output mode or disable 20K pullup if input mode. * Set pin level low if output mode or disable 20K pullup if input mode.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE void low() { write(false); }
void low() {write(false);}
//----------------------------------------------------------------------------
/** /**
* Set pin mode * Set pin mode
* @param[in] pinMode if true set output mode else input mode. * @param[in] pinMode if true set output mode else input mode.
* *
* mode() does not enable or disable the 20K pullup for input mode. * mode() does not enable or disable the 20K pullup for input mode.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE void mode(bool pinMode) { fastPinMode(PinNumber, pinMode); }
void mode(bool pinMode) {
fastPinMode(PinNumber, pinMode);
}
//----------------------------------------------------------------------------
/** @return Pin's level */ /** @return Pin's level */
inline __attribute__((always_inline)) FORCE_INLINE bool read() const { return fastDigitalRead(PinNumber); }
bool read() const {
return fastDigitalRead(PinNumber); /**
} * Toggle a pin
//----------------------------------------------------------------------------
/** toggle a pin
*
* If the pin is in output mode toggle the pin's level. * If the pin is in output mode toggle the pin's level.
* If the pin is in input mode toggle the state of the 20K pullup. * If the pin is in input mode toggle the state of the 20K pullup.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE void toggle() { fastDigitalToggle(PinNumber); }
void toggle() {
fastDigitalToggle(PinNumber); /**
} * Write the pin's level.
//----------------------------------------------------------------------------
/** Write the pin's level.
* @param[in] value If true set the pin's level high else set the * @param[in] value If true set the pin's level high else set the
* pin's level low. * pin's level low.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE void write(bool value) { fastDigitalWrite(PinNumber, value); }
void write(bool value) {
fastDigitalWrite(PinNumber, value);
}
}; };
//------------------------------------------------------------------------------ const bool MISO_MODE = false, // Pin Mode for MISO is input.
/** Nop for timing. */ MISO_LEVEL = false, // Pullups disabled for MISO are disabled.
#define nop __asm__ volatile ("nop") MOSI_MODE = true, // Pin Mode for MOSI is output.
//------------------------------------------------------------------------------ SCK_MODE = true; // Pin Mode for SCK is output.
/** Pin Mode for MISO is input.*/
const bool MISO_MODE = false;
/** Pullups disabled for MISO are disabled. */
const bool MISO_LEVEL = false;
/** Pin Mode for MOSI is output.*/
const bool MOSI_MODE = true;
/** Pin Mode for SCK is output. */
const bool SCK_MODE = true;
//------------------------------------------------------------------------------
/** /**
* @class SoftSPI * @class SoftSPI
* @brief Fast software SPI. * @brief Fast software SPI.
@ -655,19 +637,19 @@ const bool SCK_MODE = true;
template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin, uint8_t Mode = 0> template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin, uint8_t Mode = 0>
class SoftSPI { class SoftSPI {
public: public:
//----------------------------------------------------------------------------
/** Initialize SoftSPI pins. */ /** Initialize SoftSPI pins. */
void begin() { void begin() {
fastPinConfig(MisoPin, MISO_MODE, MISO_LEVEL); fastPinConfig(MisoPin, MISO_MODE, MISO_LEVEL);
fastPinConfig(MosiPin, MOSI_MODE, !MODE_CPHA(Mode)); fastPinConfig(MosiPin, MOSI_MODE, !MODE_CPHA(Mode));
fastPinConfig(SckPin, SCK_MODE, MODE_CPOL(Mode)); fastPinConfig(SckPin, SCK_MODE, MODE_CPOL(Mode));
} }
//----------------------------------------------------------------------------
/** Soft SPI receive byte. /**
* Soft SPI receive byte.
* @return Data byte received. * @return Data byte received.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE uint8_t receive() {
uint8_t receive() {
uint8_t data = 0; uint8_t data = 0;
receiveBit(7, &data); receiveBit(7, &data);
receiveBit(6, &data); receiveBit(6, &data);
@ -679,12 +661,12 @@ class SoftSPI {
receiveBit(0, &data); receiveBit(0, &data);
return data; return data;
} }
//----------------------------------------------------------------------------
/** Soft SPI send byte. /**
* Soft SPI send byte.
* @param[in] data Data byte to send. * @param[in] data Data byte to send.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE void send(uint8_t data) {
void send(uint8_t data) {
sendBit(7, data); sendBit(7, data);
sendBit(6, data); sendBit(6, data);
sendBit(5, data); sendBit(5, data);
@ -694,13 +676,13 @@ class SoftSPI {
sendBit(1, data); sendBit(1, data);
sendBit(0, data); sendBit(0, data);
} }
//----------------------------------------------------------------------------
/** Soft SPI transfer byte. /**
* Soft SPI transfer byte.
* @param[in] txData Data byte to send. * @param[in] txData Data byte to send.
* @return Data byte received. * @return Data byte received.
*/ */
inline __attribute__((always_inline)) FORCE_INLINE uint8_t transfer(uint8_t txData) {
uint8_t transfer(uint8_t txData) {
uint8_t rxData = 0; uint8_t rxData = 0;
transferBit(7, &rxData, txData); transferBit(7, &rxData, txData);
transferBit(6, &rxData, txData); transferBit(6, &rxData, txData);
@ -714,53 +696,35 @@ class SoftSPI {
} }
private: private:
//----------------------------------------------------------------------------
inline __attribute__((always_inline)) FORCE_INLINE bool MODE_CPHA(uint8_t mode) { return bool(mode & 1); }
bool MODE_CPHA(uint8_t mode) {return (mode & 1) != 0;} FORCE_INLINE bool MODE_CPOL(uint8_t mode) { return bool(mode & 2); }
inline __attribute__((always_inline)) FORCE_INLINE void receiveBit(uint8_t bit, uint8_t* data) {
bool MODE_CPOL(uint8_t mode) {return (mode & 2) != 0;} if (MODE_CPHA(Mode)) fastDigitalWrite(SckPin, !MODE_CPOL(Mode));
inline __attribute__((always_inline))
void receiveBit(uint8_t bit, uint8_t* data) {
if (MODE_CPHA(Mode)) {
fastDigitalWrite(SckPin, !MODE_CPOL(Mode));
}
nop; nop;
nop; nop;
fastDigitalWrite(SckPin, fastDigitalWrite(SckPin,
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode));
if (fastDigitalRead(MisoPin)) *data |= 1 << bit; if (fastDigitalRead(MisoPin)) SBI(*data, bit);
if (!MODE_CPHA(Mode)) { if (!MODE_CPHA(Mode)) fastDigitalWrite(SckPin, MODE_CPOL(Mode));
fastDigitalWrite(SckPin, MODE_CPOL(Mode));
} }
}
//---------------------------------------------------------------------------- FORCE_INLINE void sendBit(uint8_t bit, uint8_t data) {
inline __attribute__((always_inline)) if (MODE_CPHA(Mode)) fastDigitalWrite(SckPin, !MODE_CPOL(Mode));
void sendBit(uint8_t bit, uint8_t data) { fastDigitalWrite(MosiPin, data & _BV(bit));
if (MODE_CPHA(Mode)) { fastDigitalWrite(SckPin, MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode));
fastDigitalWrite(SckPin, !MODE_CPOL(Mode));
}
fastDigitalWrite(MosiPin, data & (1 << bit));
fastDigitalWrite(SckPin,
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode));
nop; nop;
nop; nop;
if (!MODE_CPHA(Mode)) { if (!MODE_CPHA(Mode)) fastDigitalWrite(SckPin, MODE_CPOL(Mode));
fastDigitalWrite(SckPin, MODE_CPOL(Mode));
} }
}
//---------------------------------------------------------------------------- FORCE_INLINE void transferBit(uint8_t bit, uint8_t* rxData, uint8_t txData) {
inline __attribute__((always_inline)) if (MODE_CPHA(Mode)) fastDigitalWrite(SckPin, !MODE_CPOL(Mode));
void transferBit(uint8_t bit, uint8_t* rxData, uint8_t txData) { fastDigitalWrite(MosiPin, txData & _BV(bit));
if (MODE_CPHA(Mode)) {
fastDigitalWrite(SckPin, !MODE_CPOL(Mode));
}
fastDigitalWrite(MosiPin, txData & (1 << bit));
fastDigitalWrite(SckPin, fastDigitalWrite(SckPin,
MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode)); MODE_CPHA(Mode) ? MODE_CPOL(Mode) : !MODE_CPOL(Mode));
if (fastDigitalRead(MisoPin)) *rxData |= 1 << bit; if (fastDigitalRead(MisoPin)) SBI(*rxData, bit);
if (!MODE_CPHA(Mode)) { if (!MODE_CPHA(Mode)) fastDigitalWrite(SckPin, MODE_CPOL(Mode));
fastDigitalWrite(SckPin, MODE_CPOL(Mode));
} }
}
//----------------------------------------------------------------------------
}; };