Browse Source

implemented reading of bytes sent by the 1-wire master

timer1
Youen Toupin 10 years ago
parent
commit
b236a684ca
  1. 108
      OneWireIO.ino
  2. 24
      SerialChannel.cpp
  3. 11
      SerialChannel.h
  4. 2
      SerialMonitor/SerialMonitor/App.xaml.cs

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

24
SerialChannel.cpp

@ -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;
@ -77,6 +90,7 @@ SerialChannel::Message& SerialChannel::append(byte* data, short byteCount, unsig
return msg; return msg;
} }
}
void SerialChannel::append(const char* text, unsigned long time) void SerialChannel::append(const char* text, unsigned long time)
{ {
@ -115,10 +129,10 @@ 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)
{ {

11
SerialChannel.h

@ -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:

2
SerialMonitor/SerialMonitor/App.xaml.cs

@ -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…
Cancel
Save