Stm32 support (#12)

* 1st version for STM32

bit detection and EEPROM changed to support STM32

* added STM32F1 support

updated files: library.properties. NmraDcc.cpp, NmraDcc.h

* switch off debug output

* missing #endif added

Testports for esp8266 defined
This commit is contained in:
Franz-Peter
2017-01-30 05:08:41 +01:00
committed by Alex Shepherd
parent dafa1c9964
commit f8f106962f
3 changed files with 77 additions and 49 deletions

View File

@@ -22,6 +22,7 @@
// 2015-12-16 Version without use of Timer0 by Franz-Peter Müller
// 2016-07-16 handle glitches on DCC line
// 2016-08-20 added ESP8266 support by Sven (littleyoda)
// 2017-01-19 added STM32F1 support by Franz-Peter
//
//------------------------------------------------------------------------
//
@@ -32,12 +33,6 @@
#include "NmraDcc.h"
#if defined(ESP8266)
#include <EEPROM.h>
#else
#include <avr/eeprom.h>
#endif
//------------------------------------------------------------------------
// DCC Receive Routine
//
@@ -146,20 +141,34 @@
#define MODE_TP4 pinMode( A4,OUTPUT ) // A4 = PortB Bit3
#define SET_TP4 GPIOB_PSOR = 0x08
#define CLR_TP4 GPIOB_PCOR = 0x08
#elif defined (__SAM3X8E__)
// Arduino Due
#define MODE_TP1 pinMode( A1,OUTPUT ) // A1= PA24
#define SET_TP1 REG_PIOA_SODR = (1<<24)
#define CLR_TP1 REG_PIOA_CODR = (1<<24)
#define MODE_TP2 pinMode( A2,OUTPUT ) // A2= PA23
#define SET_TP2 REG_PIOA_SODR = (1<<23)
#define CLR_TP2 REG_PIOA_CODR = (1<<23)
#define MODE_TP3 pinMode( A3,OUTPUT ) // A3 = PA22
#define SET_TP3 REG_PIOA_SODR = (1<<22)
#define CLR_TP3 REG_PIOA_CODR = (1<<22)
#define MODE_TP4 pinMode( A4,OUTPUT ) // A4 = PA6
#define SET_TP4 REG_PIOA_SODR = (1<<6)
#define CLR_TP4 REG_PIOA_CODR = (1<<6)
#elif defined (__STM32F1__)
// STM32F103...
#define MODE_TP1 pinMode( PB12,OUTPUT ) // TP1= PB12
#define SET_TP1 gpio_write_bit( GPIOB,12, HIGH );
#define CLR_TP1 gpio_write_bit( GPIOB,12, LOW );
#define MODE_TP2 pinMode( PB13,OUTPUT ) // TP2= PB13
#define SET_TP2 gpio_write_bit( GPIOB,13, HIGH );
#define CLR_TP2 gpio_write_bit( GPIOB,13, LOW );
#define MODE_TP3 pinMode( PB14,OUTPUT ) // TP3 = PB14
#define SET_TP3 gpio_write_bit( GPIOB,14, HIGH );
#define CLR_TP3 gpio_write_bit( GPIOB,14, LOW );
#define MODE_TP4 pinMode( PB15,OUTPUT ) // TP4 = PB15
#define SET_TP4 gpio_write_bit( GPIOB,15, HIGH );
#define CLR_TP4 gpio_write_bit( GPIOB,15, LOW );
#elif defined(ESP8266)
#define MODE_TP1 pinMode( D5,OUTPUT ) ; // GPIO 14
#define SET_TP1 GPOS = (1 << D5);
#define CLR_TP1 GPOC = (1 << D5);
#define MODE_TP2 pinMode( D6,OUTPUT ) ; // GPIO 12
#define SET_TP2 GPOS = (1 << D6);
#define CLR_TP2 GPOC = (1 << D6);
#define MODE_TP3 pinMode( D7,OUTPUT ) ; // GPIO 13
#define SET_TP3 GPOS = (1 << D7);
#define CLR_TP3 GPOC = (1 << D7);
#define MODE_TP4 pinMode( D7,OUTPUT ); // GPIO 15
#define SET_TP4 GPOC = (1 << D8);
#define CLR_TP4 GPOC = (1 << D8);
//#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
#else
@@ -202,7 +211,11 @@
struct countOf_t countOf;
#endif
#if defined ( __STM32F1__ )
static ExtIntTriggerMode ISREdge;
#else
static byte ISREdge; // RISING or FALLING
#endif
static word bitMax, bitMin;
typedef enum
@@ -270,9 +283,7 @@ void ExternalInterruptHandler(void)
if ( bitMicros < bitMin ) {
// too short - my be false interrupt due to glitch or false protocol -> ignore
CLR_TP3;
SET_TP4;
SET_TP4;
CLR_TP4;
SET_TP4; CLR_TP4;
return; //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> abort IRQ
}
DccBitVal = ( bitMicros < bitMax );
@@ -281,7 +292,7 @@ void ExternalInterruptHandler(void)
if(DccBitVal) {SET_TP2;} else {CLR_TP2;};
//#endif
DCC_IrqRunning = true;
sei(); // time critical is only the micros() command,so allow nested irq's
interrupts(); // time critical is only the micros() command,so allow nested irq's
#ifdef DCC_DEBUG
DccProcState.TickCount++;
#endif
@@ -297,6 +308,9 @@ void ExternalInterruptHandler(void)
DccRx.State = WAIT_START_BIT ;
// While waiting for the start bit, detect halfbit lengths. We will detect the correct
// sync and detect whether we see a false (e.g. motorola) protocol
#if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum );
#endif
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, CHANGE);
halfBit = 0;
bitMax = MAX_ONEBITHALF;
@@ -321,12 +335,13 @@ void ExternalInterruptHandler(void)
bit1=bitMicros;
} else {
// was "0" half bit, maybe the startbit
SET_TP1;
halfBit = 4;
CLR_TP1;
}
break;
case 1: //SET_TP1; // previous halfbit was '1'
if ( DccBitVal ) {
CLR_TP1;
// its a '1' halfBit -> we are still in the preamble
halfBit = 0;
bit2=bitMicros;
@@ -339,13 +354,20 @@ void ExternalInterruptHandler(void)
bitMax = MAX_PRAEAMBEL;
bitMin = MIN_ONEBITFULL;
DccRx.BitCount = 0;
SET_TP4;
#if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum );
#endif
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
SET_TP3;
CLR_TP4;
}
} else {
// first '0' half detected in second halfBit
// wrong sync or not a DCC protokoll
CLR_TP3;
halfBit = 3;
SET_TP3;
}
break;
case 3: //SET_TP1; // previous halfbit was '0' in second halfbit
@@ -371,8 +393,13 @@ void ExternalInterruptHandler(void)
DccRx.BitCount = 0 ;
DccRx.TempByte = 0 ;
}
SET_TP4;
#if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum );
#endif
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
CLR_TP1;
CLR_TP4;
break;
case 4: SET_TP1; // previous (first) halfbit was 0
// if this halfbit is 0 too, we got the startbit
@@ -396,8 +423,14 @@ void ExternalInterruptHandler(void)
DccRx.BitCount = 0 ;
DccRx.TempByte = 0 ;
}
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
CLR_TP1;
SET_TP4;
#if defined ( __STM32F1__ )
detachInterrupt( DccProcState.ExtIntNum );
#endif
attachInterrupt( DccProcState.ExtIntNum, ExternalInterruptHandler, ISREdge );
CLR_TP4;
break;
}
@@ -456,28 +489,18 @@ void ackCV(void)
}
uint8_t readEEPROM( unsigned int CV ) {
#if defined(ESP8266)
return EEPROM.read(CV) ;
#else
return eeprom_read_byte( (uint8_t*) CV );
#endif
}
void writeEEPROM( unsigned int CV, uint8_t Value ) {
#if defined(ESP8266)
EEPROM.write(CV, Value) ;
#if defined(ESP8266)
EEPROM.commit();
#else
eeprom_write_byte( (uint8_t*) CV, Value ) ;
#endif
}
bool readyEEPROM() {
#if defined(ESP8266)
return true;
#else
return eeprom_is_ready();
#endif
}
@@ -996,7 +1019,12 @@ NmraDcc::NmraDcc()
void NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup)
{
#if defined ( __STM32F1__ )
// with STM32F1 the interuptnumber is equal the pin number
DccProcState.ExtIntNum = ExtIntPinNum;
#else
DccProcState.ExtIntNum = ExtIntNum;
#endif
DccProcState.ExtIntPinNum = ExtIntPinNum;
pinMode( ExtIntPinNum, INPUT );
@@ -1103,10 +1131,10 @@ uint8_t NmraDcc::process()
{
// We need to do this check with interrupts disabled
//SET_TP4;
cli();
noInterrupts();
Msg = DccRx.PacketCopy ;
DccRx.DataReady = 0 ;
sei();
interrupts();
#ifdef DCC_DBGVAR
countOf.Tel++;
#endif
@@ -1115,20 +1143,15 @@ uint8_t NmraDcc::process()
for(uint8_t i = 0; i < DccRx.PacketCopy.Size; i++)
xorValue ^= DccRx.PacketCopy.Data[i];
//CLR_TP4;
if(xorValue) {
SET_TP4;
#ifdef DCC_DBGVAR
countOf.Err++;
#endif
CLR_TP4;
return 0 ;
} else {
//SET_TP4;
if( notifyDccMsg ) notifyDccMsg( &Msg );
execDccProcessor( &Msg );
//CLR_TP4;
}
return 1 ;
}

View File

@@ -42,6 +42,8 @@
#include "WProgram.h"
#endif
#include "EEPROM.h"
#ifndef NMRADCC_IS_IN
#define NMRADCC_IS_IN
@@ -93,6 +95,9 @@ typedef struct
#if defined(ESP8266)
#include <spi_flash.h>
#define MAXCV SPI_FLASH_SEC_SIZE
#elif defined( __STM32F1__)
#define MAXCV (EEPROM_PAGE_SIZE/4 - 1) // number of storage places (CV address could be larger
// because STM32 uses virtual adresses)
#else
#define MAXCV E2END // the upper limit of the CV value currently defined to max memory.
#endif

View File

@@ -6,4 +6,4 @@ sentence=Enables NMRA DCC Communication
paragraph=This library allows you to interface to a NMRA DCC track signal and receive DCC commands. The library currently supports the AVR ATTiny84/85 & ATMega88/168/328/32u4 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms
category=Communication
url=http://mrrwa.org/dcc-decoder-interface/
architectures=avr,esp8266
architectures=avr,esp8266,STM32F1