implemented reading of bytes sent by the 1-wire master
This commit is contained in:
parent
8c473f50e4
commit
b236a684ca
108
OneWireIO.ino
108
OneWireIO.ino
@ -12,12 +12,24 @@
|
|||||||
#define PresenceWaitDuration 30
|
#define PresenceWaitDuration 30
|
||||||
#define PresenceDuration 300
|
#define PresenceDuration 300
|
||||||
|
|
||||||
|
#define BitZeroMinDuration 20
|
||||||
|
#define BitZeroMaxDuration 75
|
||||||
|
|
||||||
SerialChannel debug("debug");
|
SerialChannel debug("debug");
|
||||||
|
|
||||||
Pin owPin(OWPin);
|
Pin owPin(OWPin);
|
||||||
Pin owOutTestPin(3);
|
Pin owOutTestPin(3);
|
||||||
Pin led(LEDPin);
|
Pin led(LEDPin);
|
||||||
|
|
||||||
|
enum OwStatus
|
||||||
|
{
|
||||||
|
OS_WaitReset,
|
||||||
|
OS_Presence,
|
||||||
|
OS_AfterPresence,
|
||||||
|
OS_WaitCommand,
|
||||||
|
};
|
||||||
|
OwStatus status;
|
||||||
|
|
||||||
void owPullLow()
|
void owPullLow()
|
||||||
{
|
{
|
||||||
owPin.outputMode();
|
owPin.outputMode();
|
||||||
@ -40,6 +52,10 @@ void owWrite(bool value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned long resetStart = (unsigned long)-1;
|
unsigned long resetStart = (unsigned long)-1;
|
||||||
|
unsigned long lastReset = (unsigned long)-1;
|
||||||
|
unsigned long bitStart = (unsigned long)-1;
|
||||||
|
byte receivingByte = 0;
|
||||||
|
byte receivingBitPos = 0;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
@ -63,7 +79,7 @@ void setup()
|
|||||||
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
|
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
|
||||||
sei(); // enable interrupts
|
sei(); // enable interrupts
|
||||||
|
|
||||||
Serial.begin(400000);
|
Serial.begin(9600);
|
||||||
}
|
}
|
||||||
|
|
||||||
//int count = 0;
|
//int count = 0;
|
||||||
@ -92,6 +108,17 @@ void setTimerEvent(short microSecondsDelay, void(*event)())
|
|||||||
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // turn on CTC mode with 64 prescaler
|
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // turn on CTC mode with 64 prescaler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void owError(const char* message)
|
||||||
|
{
|
||||||
|
debug.append(message);
|
||||||
|
led.writeHigh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void owResetError()
|
||||||
|
{
|
||||||
|
led.writeLow();
|
||||||
|
}
|
||||||
|
|
||||||
void onewireInterrupt(void)
|
void onewireInterrupt(void)
|
||||||
{
|
{
|
||||||
bool state = owPin.read();
|
bool state = owPin.read();
|
||||||
@ -102,32 +129,107 @@ void onewireInterrupt(void)
|
|||||||
if (!state)
|
if (!state)
|
||||||
resetStart = now;
|
resetStart = now;
|
||||||
|
|
||||||
|
// handle reset
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
unsigned long resetDuration = resetStart == (unsigned long)-1 ? (unsigned long)-1 : now - resetStart;
|
unsigned long resetDuration = resetStart == (unsigned long)-1 ? (unsigned long)-1 : now - resetStart;
|
||||||
resetStart = (unsigned long)-1;
|
resetStart = (unsigned long)-1;
|
||||||
|
lastReset = now;
|
||||||
|
|
||||||
if (resetDuration >= ResetMinDuration && resetDuration <= ResetMaxDuration)
|
if (resetDuration >= ResetMinDuration && resetDuration <= ResetMaxDuration)
|
||||||
{
|
{
|
||||||
//debug.SC_APPEND_STR_TIME("reset", now);
|
//debug.SC_APPEND_STR_TIME("reset", now);
|
||||||
|
owResetError();
|
||||||
|
status = OS_Presence;
|
||||||
setTimerEvent(PresenceWaitDuration - (micros() - now), &beginPresence);
|
setTimerEvent(PresenceWaitDuration - (micros() - now), &beginPresence);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status == OS_AfterPresence)
|
||||||
|
{
|
||||||
|
status = OS_WaitCommand;
|
||||||
|
receivingByte = 0;
|
||||||
|
receivingBitPos = 0;
|
||||||
|
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
// this is the rising edge of end-of-presence ; don't try to interpret it as a bit
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read bytes
|
||||||
|
if (status == OS_WaitCommand)
|
||||||
|
{
|
||||||
|
if (!state)
|
||||||
|
{
|
||||||
|
// master just pulled low, this is a bit start
|
||||||
|
//debug.SC_APPEND_STR_TIME("bit start", now);
|
||||||
|
bitStart = now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bitStart == (unsigned long)-1)
|
||||||
|
{
|
||||||
|
//owError("Invalid read sequence");
|
||||||
|
//return;
|
||||||
|
|
||||||
|
// we missed the falling edge, we emulate one here (this can happen if handling of rising edge interrupt takes too long)
|
||||||
|
bitStart = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
// master released the line, we interpret it as a bit 1 or 0 depending on timing
|
||||||
|
unsigned long bitLength = now - bitStart;
|
||||||
|
bitStart = (unsigned long)-1;
|
||||||
|
|
||||||
|
if (bitLength < BitZeroMinDuration)
|
||||||
|
{
|
||||||
|
// received bit = 1
|
||||||
|
//debug.SC_APPEND_STR_TIME("received bit 1", now);
|
||||||
|
receivingByte |= (1 << receivingBitPos);
|
||||||
|
++receivingBitPos;
|
||||||
|
}
|
||||||
|
else if (bitLength < BitZeroMaxDuration)
|
||||||
|
{
|
||||||
|
// received bit = 0
|
||||||
|
//debug.SC_APPEND_STR_TIME("received bit 0", now);
|
||||||
|
++receivingBitPos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is not a valid bit
|
||||||
|
owError("Invalid read timing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (receivingBitPos == 8)
|
||||||
|
{
|
||||||
|
debug.SC_APPEND_STR_INT("received byte", (long)receivingByte);
|
||||||
|
receivingBitPos = 0;
|
||||||
|
receivingByte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void beginPresence()
|
void beginPresence()
|
||||||
{
|
{
|
||||||
//debug.SC_APPEND_STR("beginPresence");
|
unsigned long now = micros();
|
||||||
owPullLow();
|
owPullLow();
|
||||||
owOutTestPin.writeLow();
|
owOutTestPin.writeLow();
|
||||||
setTimerEvent(PresenceDuration, &endPresence);
|
setTimerEvent(PresenceDuration, &endPresence);
|
||||||
|
debug.SC_APPEND_STR_TIME("reset", lastReset);
|
||||||
|
debug.SC_APPEND_STR_TIME("beginPresence", now);
|
||||||
}
|
}
|
||||||
|
|
||||||
void endPresence()
|
void endPresence()
|
||||||
{
|
{
|
||||||
//debug.SC_APPEND_STR("endPresence");
|
unsigned long now = micros();
|
||||||
owRelease();
|
owRelease();
|
||||||
|
debug.SC_APPEND_STR_TIME("endPresence", now);
|
||||||
|
|
||||||
|
status = OS_AfterPresence;
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(TIMER1_COMPA_vect) // timer1 interrupt
|
ISR(TIMER1_COMPA_vect) // timer1 interrupt
|
||||||
|
@ -6,10 +6,12 @@ SerialChannel* SerialChannel::first = 0;
|
|||||||
|
|
||||||
SerialChannel::Message SerialChannel::buffer1[SerialChannel::MaxPendingMessages];
|
SerialChannel::Message SerialChannel::buffer1[SerialChannel::MaxPendingMessages];
|
||||||
SerialChannel::Message SerialChannel::buffer2[SerialChannel::MaxPendingMessages];
|
SerialChannel::Message SerialChannel::buffer2[SerialChannel::MaxPendingMessages];
|
||||||
SerialChannel::Message* SerialChannel::backBuffer;
|
volatile SerialChannel::Message* SerialChannel::backBuffer;
|
||||||
byte SerialChannel::backBufferPos;
|
volatile byte SerialChannel::backBufferPos;
|
||||||
byte SerialChannel::frontBufferSize;
|
byte SerialChannel::frontBufferSize;
|
||||||
|
|
||||||
|
SerialChannel::Message dummyMessage;
|
||||||
|
|
||||||
SerialChannel::SerialChannel(const char* name_)
|
SerialChannel::SerialChannel(const char* name_)
|
||||||
: next(0)
|
: next(0)
|
||||||
, id((byte)-1)
|
, id((byte)-1)
|
||||||
@ -66,9 +68,20 @@ SerialChannel::Message& SerialChannel::append(byte* data, short byteCount, unsig
|
|||||||
if (time == (unsigned long)-1)
|
if (time == (unsigned long)-1)
|
||||||
time = micros();
|
time = micros();
|
||||||
|
|
||||||
Message& msg = backBuffer[backBufferPos++];
|
|
||||||
if (backBufferPos >= MaxPendingMessages)
|
if (backBufferPos >= MaxPendingMessages)
|
||||||
backBufferPos = MaxPendingMessages - 1;
|
{
|
||||||
|
Message& msg = ((Message*)backBuffer)[MaxPendingMessages-1];
|
||||||
|
msg.id = id;
|
||||||
|
msg.data = (byte*)"OVERFLOW";
|
||||||
|
msg.byteCount = 8;
|
||||||
|
msg.time = time;
|
||||||
|
msg.longArg0 = 0;
|
||||||
|
|
||||||
|
return dummyMessage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message& msg = ((Message*)backBuffer)[backBufferPos++];
|
||||||
msg.id = id;
|
msg.id = id;
|
||||||
msg.data = data;
|
msg.data = data;
|
||||||
msg.byteCount = byteCount;
|
msg.byteCount = byteCount;
|
||||||
@ -76,6 +89,7 @@ SerialChannel::Message& SerialChannel::append(byte* data, short byteCount, unsig
|
|||||||
msg.longArg0 = 0;
|
msg.longArg0 = 0;
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialChannel::append(const char* text, unsigned long time)
|
void SerialChannel::append(const char* text, unsigned long time)
|
||||||
@ -115,9 +129,9 @@ void SerialChannel::flush()
|
|||||||
Serial.write(msg->data, msg->byteCount);
|
Serial.write(msg->data, msg->byteCount);
|
||||||
if (paramsSize > 0)
|
if (paramsSize > 0)
|
||||||
Serial.write(params, paramsSize);
|
Serial.write(params, paramsSize);
|
||||||
}
|
|
||||||
|
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialChannel::writeShort(short num)
|
void SerialChannel::writeShort(short num)
|
||||||
|
@ -8,9 +8,7 @@
|
|||||||
|
|
||||||
class SerialChannel
|
class SerialChannel
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
static const byte MaxPendingMessages = 16;
|
|
||||||
|
|
||||||
struct Message
|
struct Message
|
||||||
{
|
{
|
||||||
unsigned long time;
|
unsigned long time;
|
||||||
@ -20,6 +18,9 @@ private:
|
|||||||
byte id;
|
byte id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const byte MaxPendingMessages = 32;
|
||||||
|
|
||||||
static SerialChannel* first;
|
static SerialChannel* first;
|
||||||
SerialChannel* next;
|
SerialChannel* next;
|
||||||
|
|
||||||
@ -29,8 +30,8 @@ private:
|
|||||||
|
|
||||||
static Message buffer1[MaxPendingMessages];
|
static Message buffer1[MaxPendingMessages];
|
||||||
static Message buffer2[MaxPendingMessages];
|
static Message buffer2[MaxPendingMessages];
|
||||||
static Message* backBuffer;
|
static volatile Message* backBuffer;
|
||||||
static byte backBufferPos;
|
static volatile byte backBufferPos;
|
||||||
static byte frontBufferSize;
|
static byte frontBufferSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -28,7 +28,7 @@ namespace SerialMonitor
|
|||||||
|
|
||||||
Serial = new SerialPort();
|
Serial = new SerialPort();
|
||||||
Serial.PortName = "COM4";
|
Serial.PortName = "COM4";
|
||||||
Serial.BaudRate = 400000;
|
Serial.BaudRate = 9600;
|
||||||
|
|
||||||
Serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(OnDataReceived);
|
Serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(OnDataReceived);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user