diff --git a/LowLevel.h b/LowLevel.h new file mode 100644 index 0000000..41ad123 --- /dev/null +++ b/LowLevel.h @@ -0,0 +1,93 @@ +#ifndef _LowLevel_h +#define _LowLevel_h + +#include + +#if ARDUINO >= 100 +#include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc +#else +#include "WProgram.h" // for delayMicroseconds +#include "pins_arduino.h" // for digitalPinToBitMask, etc +#endif + +#if defined(__AVR__) +#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM asm("r30") +#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) + +#elif defined(__MK20DX128__) || defined(__MK20DX256__) +#define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) +#define PIN_TO_BITMASK(pin) (1) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (*((base)+512)) +#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0) +#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1) +#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1) +#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1) + +#elif defined(__SAM3X8E__) +// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due. +// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268 +// If you have trouble with OneWire on Arduino Due, please check the +// status of delayMicroseconds() before reporting a bug in OneWire! +#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER)) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask)) +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef pgm_read_byte +#define pgm_read_byte(addr) (*(const uint8_t *)(addr)) +#endif + +#elif defined(__PIC32MX__) +#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10 +#define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08 +#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04 +#define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24 +#define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28 + +#else +#error "Please define I/O register types here" +#endif + +class Pin +{ +private: + IO_REG_TYPE mask; + volatile IO_REG_TYPE *reg; + +public: + inline Pin(uint8_t pin) + { + mask = PIN_TO_BITMASK(pin); + reg = PIN_TO_BASEREG(pin); + } + + inline void inputMode() { DIRECT_MODE_INPUT(reg, mask); } + inline void outputMode() { DIRECT_MODE_OUTPUT(reg, mask); } + + inline bool read() { return DIRECT_READ(reg, mask); } + inline void writeLow() { DIRECT_WRITE_LOW(reg, mask); } + inline void writeHigh() { DIRECT_WRITE_HIGH(reg, mask); } + inline void write(bool value) { if (value) writeHigh(); else writeLow(); } +}; + +#endif diff --git a/OneWireIO.ino b/OneWireIO.ino index ad39056..72920bd 100644 --- a/OneWireIO.ino +++ b/OneWireIO.ino @@ -1,18 +1,27 @@ #include "Arduino.h" +#include "LowLevel.h" #include "SerialChannel.h" #define LEDPin 13 -#define OWPin 2 +#define OWPin 2 #define InterruptNumber 0 // Must correspond to the OWPin to correctly detect state changes. On Arduino Uno, interrupt 0 is for digital pin 2 +#define ResetMinDuration 360 +#define ResetMaxDuration 900 + SerialChannel debug("debug"); +Pin owPin(OWPin); +Pin ledPin(LEDPin); + +unsigned long resetStart = (unsigned long)-1; + void setup() { - pinMode(LEDPin, OUTPUT); - pinMode(OWPin, INPUT); + ledPin.outputMode(); + owPin.inputMode(); - digitalWrite(LEDPin, LOW); + ledPin.writeLow(); attachInterrupt(InterruptNumber,onewireInterrupt,CHANGE); @@ -23,11 +32,28 @@ void loop() { cli();//disable interrupts - sei();//enable interrupts + sei();//enable interrupts } void onewireInterrupt(void) { - digitalWrite(LEDPin, digitalRead(OWPin)); + bool state = owPin.read(); + unsigned long now = micros(); + + //ledPin.write(state); + + if (!state) + resetStart = now; + + if (state) + { + unsigned long resetDuration = now - resetStart; + if (resetStart != (unsigned long)-1 && resetDuration >= ResetMinDuration && resetDuration <= ResetMaxDuration) + { + debug.write("reset"); + ledPin.writeHigh(); + } + resetStart = (unsigned long)-1; + } } diff --git a/OneWireIO.sln b/OneWireIO.sln new file mode 100644 index 0000000..873e73d --- /dev/null +++ b/OneWireIO.sln @@ -0,0 +1,44 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OneWireIO", "OneWireIO.vcxproj", "{3B500971-1570-460F-81C3-22AC3B7764B9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerialMonitor", "SerialMonitor\SerialMonitor\SerialMonitor.csproj", "{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Win32.ActiveCfg = Debug|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Win32.Build.0 = Debug|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Any CPU.ActiveCfg = Release|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Mixed Platforms.Build.0 = Release|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Win32.ActiveCfg = Release|Win32 + {3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Win32.Build.0 = Release|Win32 + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Any CPU.Build.0 = Release|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Win32.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/OneWireIO.vcxproj b/OneWireIO.vcxproj new file mode 100644 index 0000000..c0bc860 --- /dev/null +++ b/OneWireIO.vcxproj @@ -0,0 +1,81 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {3B500971-1570-460F-81C3-22AC3B7764B9} + OneWireIO + + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + + + Level3 + Disabled + true + D:\Outils\Arduino\hardware\arduino\avr\cores\arduino + _MBCS;%(PreprocessorDefinitions);ARDUINO=160;__AVR__ + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OneWireIO.vcxproj.filters b/OneWireIO.vcxproj.filters new file mode 100644 index 0000000..f361281 --- /dev/null +++ b/OneWireIO.vcxproj.filters @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Oscilloscope.ino b/Oscilloscope.ino deleted file mode 100644 index 5ee71f9..0000000 --- a/Oscilloscope.ino +++ /dev/null @@ -1,102 +0,0 @@ -#include "Arduino.h" -#include "SerialChannel.h" - -#define LEDPin 13 -#define OWPin 2 -#define InterruptNumber 0 // Must correspond to the OWPin to correctly detect state changes. On Arduino Uno, interrupt 0 is for digital pin 2 - -// how many samples we want to skip between two samples we keep (can be used to lower the sampling frequency) -#define SkipSamples 0 -byte regularEncodedFrequency; - -const int BufferSize = 512; -byte buffer1[BufferSize]; -byte buffer2[BufferSize]; -byte* backBuffer = buffer1; -volatile short backBufferPos = 0; -byte samplesSkipped = SkipSamples; -unsigned long backBufferStartTime = micros(); - -SerialChannel oscilloscope("oscilloscope"); -SerialChannel debug("debug"); - -void setup() -{ - pinMode(LEDPin, OUTPUT); - pinMode(OWPin, INPUT); - - digitalWrite(LEDPin, LOW); - - //attachInterrupt(InterruptNumber,onewireInterrupt,CHANGE); - - cli();//disable interrupts - - //set up continuous sampling of analog pin 0 - //clear ADCSRA and ADCSRB registers - ADCSRA = 0; - ADCSRB = 0; - - ADMUX |= (1 << REFS0); //set reference voltage - ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only - - int ADPS = (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); - ADCSRA |= ADPS; //set ADC clock with 32 prescaler- 16mHz/32=500KHz ; 13 cycles for a conversion which means 38000 samples per second - ADCSRA |= (1 << ADATE); //enabble auto trigger - ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete - ADCSRA |= (1 << ADEN); //enable ADC - ADCSRA |= (1 << ADSC); //start ADC measurements - - regularEncodedFrequency = (byte)ADPS; - byte skipSamples = 0; - #if SkipSamples > 0 - skipSamples = SkipSamples; - #endif - regularEncodedFrequency |= skipSamples << 3; - - sei();//enable interrupts - - Serial.begin(400000); -} - -void loop() -{ - while(backBufferPos < BufferSize / 2) ; - cli();//disable interrupts - byte* currentBuffer = backBuffer; - short currentBufferSize = backBufferPos; - backBuffer = (backBuffer == buffer1 ? buffer2 : buffer1); - backBufferPos = 0; - sei();//enable interrupts - unsigned long currentBufferStartTime = backBufferStartTime; - backBufferStartTime = micros(); - digitalWrite(LEDPin, LOW); - - //Serial.write(currentBuffer, currentBufferSize); - oscilloscope.beginWrite(currentBufferSize + 1, currentBufferStartTime); - oscilloscope.continueWrite(®ularEncodedFrequency, 1); - oscilloscope.continueWrite(currentBuffer, currentBufferSize); -} - -ISR(ADC_vect) {//when new ADC value ready - byte sample = ADCH; //store 8 bit value from analog pin 0 - - #if SkipSamples > 0 - if(samplesSkipped++ < SkipSamples) - return; - samplesSkipped = 0; - #endif - - backBuffer[backBufferPos++] = sample; - if(backBufferPos >= BufferSize) - { - // overflow of back buffer, we loose the current sample - digitalWrite(LEDPin, HIGH); - backBufferPos = BufferSize - 1; - } -} - -void onewireInterrupt(void) -{ - //digitalWrite(LEDPin, digitalRead(OWPin)); -} -