Browse Source

Upload files to ''

master
IanF 5 years ago
parent
commit
bc5212e502
  1. 91
      FakeD2413.ino

91
FakeD2413.ino

@ -1,35 +1,19 @@
/* Ian Fleet 2018
All files, software, schematics and designs are provided as-is with no warranty.
All files, software, schematics and designs are for experimental/hobby use.
Under no circumstances should any part be used for critical systems where safety,
life or property depends upon it. You are responsible for all use.
You are free to use, modify, derive or otherwise extend for your own purposes
*/
// This example emulates a DS2413 device on an Arduino UNO
// note : physical DS2413 devices found in 2018 are often clones with
// a device code different to the Maxim datasheet
#include "Arduino.h" #include "Arduino.h"
#include "OneWireSlave.h" #include "OneWireSlave.h"
#include "comptime.h" #include "comptime.h"
// This is the pin that will be used for one-wire data // This is the pin that will be used for one-wire data
// On Arduino Uno, you can use pin 2 or pin 3 // On Arduino Uno, you can use pin 2 or pin 3
Pin oneWireData(2); Pin oneWireData(2); // PB2 only attiny85 pin with rising/falling interrupts
//Pin led(0);
Pin led(13); // builtin led
// This sample emulates a DS2413 device , so we start by defining the available commands // This sample emulates a DS2413 device , so we start by defining the available commands
const byte DS2413_FAMILY_ID = 0x3A; // Maxim DS2413 device code const byte DS2413_FAMILY_ID = 0x3A; // Maxim DS2413 device code
const byte CLONE_FAMILY_ID = 0x85; // Clone device code const byte CLONE_FAMILY_ID = 0x85; // Chinese clone device code
const byte DS2413_ACCESS_READ = 0xF5; const byte DS2413_ACCESS_READ = 0xF5;
const byte DS2413_ACCESS_WRITE = 0x5A; const byte DS2413_ACCESS_WRITE = 0x5A;
const byte DS2413_ACK_SUCCESS = 0xAA; const byte DS2413_ACK_SUCCESS = 0xAA;
@ -39,11 +23,11 @@ const byte owROM[7] = { DS2413_FAMILY_ID, SERIAL_NUMBER};
// will be calculated in begin:---------------^^^^ // will be calculated in begin:---------------^^^^
// or use fixed id - make sure it doesn't conflict with another device // or use fixed id - make sure it doesn't conflict with another device
//const byte owROM[7] = { 0x3A, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22 }; //const byte owROM[7] = { 0x3A, 0x00, 0x55, 0xAA, 0x00, 0x11, 0x22 };
#define PIOA 4 // DS2413 PIO PINS on the UNO #define PIOA 3 // (pin 3)
#define PIOB 5 // #define PIOB 4 // (pin 4)
uint8_t latch = 0; uint8_t latch = 0;
uint8_t statusbyte1 = 0; uint8_t statusbyte1 = 0;
@ -55,13 +39,11 @@ enum DeviceState
DS_WaitingCommand, DS_WaitingCommand,
DS_WaitingStatus1, DS_WaitingStatus1,
DS_WaitingStatus2, DS_WaitingStatus2,
}; };
volatile DeviceState state = DS_WaitingReset; volatile DeviceState state = DS_WaitingReset;
// scratchpad // scratchpad
volatile byte scratchpad[2]; volatile byte scratchpad[2];
volatile byte response[2]; volatile byte response[2];
@ -72,21 +54,19 @@ void owReceive(OneWireSlave::ReceiveEvent evt, byte data);
void setup() void setup()
{ {
led.outputMode(); // led.outputMode();
// led.writeLow();
Serial.begin(115200); // OSCCAL = 85;
// Setup the OneWire library // Setup the OneWire library
OWSlave.setReceiveCallback(&owReceive); OWSlave.setReceiveCallback(&owReceive);
OWSlave.begin(owROM, oneWireData.getPinNumber()); OWSlave.begin(owROM, oneWireData.getPinNumber());
} }
////////////////////////////////////////// //////////////////////////////////////////
void loop() void loop()
{ {
delay(1000); delay(10);
cli();//disable interrupts cli();//disable interrupts
// Be sure to not block interrupts for too long, OneWire timing is very tight for some operations. 1 or 2 microseconds (yes, microseconds, not milliseconds) can be too much depending on your master controller, but then it's equally unlikely that you block exactly at the moment where it matters. // Be sure to not block interrupts for too long, OneWire timing is very tight for some operations. 1 or 2 microseconds (yes, microseconds, not milliseconds) can be too much depending on your master controller, but then it's equally unlikely that you block exactly at the moment where it matters.
@ -94,9 +74,6 @@ void loop()
sei();//enable interrupts sei();//enable interrupts
led.writeLow(); // flash the led
delay(1000);
led.writeHigh();
} }
////////////////////////////////////////// //////////////////////////////////////////
@ -110,24 +87,27 @@ static uint8_t getstatus() {
uint8_t x = (~c) << 4; uint8_t x = (~c) << 4;
return x + c; return x + c;
} }
////////////////////////////////////////// //////////////////////////////////////////
static void port(int PIO, bool stat) { static void port(int led, bool stat) {
if (stat) { if (stat) {
digitalWrite(PIO, HIGH); digitalWrite(led, HIGH);
pinMode(PIO, INPUT); pinMode(led, INPUT);
} else { } else {
pinMode(PIO, OUTPUT); pinMode(led, OUTPUT);
digitalWrite(PIO, LOW); digitalWrite(led, LOW);
} }
} }
////////////////////////////////////////// //////////////////////////////////////////
static void set(uint8_t val) { static void set(uint8_t val) {
latch = val; latch = val;
port(PIOA, latch & 1); port(PIOA, latch & 1);
port(PIOB, latch & 2); port(PIOB, latch & 2);
// TODO store latch value for recovery at startup //eeprom_write_byte((uint8_t*)10, (unsigned char)latch);
} }
////////////////////////////////////////// //////////////////////////////////////////
@ -140,48 +120,49 @@ void owReceive(OneWireSlave::ReceiveEvent evt, byte data)
switch (state) switch (state)
{ {
case DS_WaitingCommand: case DS_WaitingCommand:
switch (data) // on command byte switch (data)
{ {
case DS2413_ACCESS_WRITE: case DS2413_ACCESS_WRITE:
state = DS_WaitingStatus1; // wait for status byte 1 state = DS_WaitingStatus1;
//OWSlave.beginWriteBit(0, true); // send zeros as long as the conversion is not finished
break; break;
case DS2413_ACCESS_READ: case DS2413_ACCESS_READ:
state = DS_WaitingReset; state = DS_WaitingReset;
scratchpad[0] = getstatus(); //return status in DS2413 format scratchpad[0] = getstatus();
OWSlave.beginWrite((const byte*)scratchpad, 1, 0); OWSlave.beginWrite((const byte*)scratchpad, 1, 0);
break;
default:
//TODO : report invalid commands
break; break;
} // end switch (data) command
//case :
// break;
}
break; break;
case DS_WaitingStatus1: case DS_WaitingStatus1:
statusbyte1 = data; statusbyte1 = data;
state = DS_WaitingStatus2; // wait for status byte 2 state = DS_WaitingStatus2;
break; break;
case DS_WaitingStatus2: case DS_WaitingStatus2:
statusbyte2 = data; statusbyte2 = data;
if (statusbyte1 != ~statusbyte2) { // is DS2413 status data valid? if (statusbyte1 != ~statusbyte2) {
set(statusbyte1); set(statusbyte1);
response[0] = DS2413_ACK_SUCCESS; response[0] = DS2413_ACK_SUCCESS;
} else { } else {
response[0] = 0x11; // mark error - real DS2413 don't do this response[0] = 0x11; // mark error
} }
response[1] = getstatus(); // DS2413 expects an update of new status response[1] = getstatus();
OWSlave.beginWrite((const byte*)response, 2, 0); OWSlave.beginWrite((const byte*)response, 2, 0);
state = DS_WaitingCommand; state = DS_WaitingCommand;
break; break;
} // end switch state }
break; break;
case OneWireSlave::RE_Reset: case OneWireSlave::RE_Reset:
state = DS_WaitingCommand; state = DS_WaitingCommand;
break; break;
@ -189,5 +170,5 @@ void owReceive(OneWireSlave::ReceiveEvent evt, byte data)
case OneWireSlave::RE_Error: case OneWireSlave::RE_Error:
state = DS_WaitingReset; state = DS_WaitingReset;
break; break;
} // end switch evt }
} }

Loading…
Cancel
Save