Browse Source

Upload files to ''

Added support for attiny85  at 16mhz.

Attiny85 fuses settings and OSCCAL calibration are required to meet the OneWire timing specifications
master
IanF 6 years ago
parent
commit
d698f10a08
  1. 51
      LowLevel.h
  2. 923
      OneWireSlave.cpp
  3. 210
      OneWireSlave.h

51
LowLevel.h

@ -29,20 +29,38 @@
#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask))
#if defined (__AVR_ATtiny85__) #if defined (__AVR_ATtiny85__)
#define CLEARINTERRUPT GIFR |= (1 << INTF0)
#include "UserTimer.h" //ATtiny-support based on TinyCore1 Arduino-core for ATtiny at http://github.com/Coding-Badly/TinyCore1.git /* Note : The attiny85 clock speed = 16mhz (fuses L 0xF1, H 0xDF. E oxFF
OSCCAL VALUE must also be calibrated to 16mhz
*/
#define CLEARINTERRUPT GIFR |= (1 << INTF0) | (1<<PCIF);
#define USERTIMER_COMPA_vect TIMER1_COMPA_vect
__attribute__((always_inline)) static inline void UserTimer_Init( void ) __attribute__((always_inline)) static inline void UserTimer_Init( void )
{ {
UserTimer_SetToPowerup(); TCCR1 = 0; //stop the timer
UserTimer_SetWaveformGenerationMode(UserTimer_(CTC_OCR)); TCNT1 = 0;
//GTCCR |= (1<<PSR1); //reset the prescaler
TIMSK = 0; // clear timer interrupts enable
} }
__attribute__((always_inline)) static inline void UserTimer_Run(short skipTicks) __attribute__((always_inline)) static inline void UserTimer_Run(int skipTicks)
{ {
UserTimer_SetCount(0);
UserTimer_SetOutputCompareMatchAndClear(skipTicks); TCNT1 = 0; //zero the timer
UserTimer_ClockSelect(UserTimer_(Prescale_Value_64)); GTCCR |= (1 << PSR1); //reset the prescaler
OCR1A = skipTicks; //set the compare value
TCCR1 |= (1 << CTC1) | (0 << CS13) | (1 << CS12) | (1 << CS11) | (0 << CS10);//32 prescaler
//TCCR1 |= (1 << CTC1) | (0 << CS13) | (1 << CS12) | (0 << CS11) | (0 << CS10);//8 prescaler
TIMSK |= (1 << OCIE1A); //interrupt on Compare Match A
} }
#define UserTimer_Stop() UserTimer_ClockSelect(UserTimer_(Stopped))
__attribute__((always_inline)) static inline void UserTimer_Stop()
{
TIMSK = 0; //&= ~(1 << OCIE1A);// clear timer interrupt enable
TCCR1 = 0;
}
#elif defined (__AVR_ATmega328P__) #elif defined (__AVR_ATmega328P__)
#define CLEARINTERRUPT EIFR |= (1 << INTF0) #define CLEARINTERRUPT EIFR |= (1 << INTF0)
@ -52,8 +70,7 @@ __attribute__((always_inline)) static inline void UserTimer_Init( void )
{ {
TCCR1A = 0; TCCR1A = 0;
TCCR1B = 0; TCCR1B = 0;
// enable timer compare interrupt TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
} }
__attribute__((always_inline)) static inline void UserTimer_Run(short skipTicks) __attribute__((always_inline)) static inline void UserTimer_Run(short skipTicks)
{ {
@ -112,6 +129,7 @@ __attribute__((always_inline)) static inline void UserTimer_Run(short skipTicks)
#error "Please define I/O register types here" #error "Please define I/O register types here"
#endif #endif
class Pin class Pin
{ {
private: private:
@ -133,13 +151,6 @@ class Pin
pinNumber_ = pin; pinNumber_ = pin;
mask_ = PIN_TO_BITMASK(pin); mask_ = PIN_TO_BITMASK(pin);
reg_ = PIN_TO_BASEREG(pin); reg_ = PIN_TO_BASEREG(pin);
int x = reg_;
Serial.print(" Pin:");
Serial.print(pin);
Serial.print(" mask:");
Serial.print(mask_);
Serial.print(" reg:");
Serial.println(x);
switch (pin) switch (pin)
{ {
@ -176,12 +187,10 @@ class Pin
inline void attachInterrupt(void (*handler)(), int mode) inline void attachInterrupt(void (*handler)(), int mode)
{ {
//Serial.print(" handler:");
//int x = handler;
//Serial.println(x);
CLEARINTERRUPT; // clear any pending interrupt (we want to call the handler only for interrupts happening after it is attached) CLEARINTERRUPT; // clear any pending interrupt (we want to call the handler only for interrupts happening after it is attached)
::attachInterrupt(interruptNumber_, handler, mode); ::attachInterrupt(interruptNumber_, handler, mode);
} }
inline void detachInterrupt() { inline void detachInterrupt() {
::detachInterrupt(interruptNumber_); ::detachInterrupt(interruptNumber_);
} }

923
OneWireSlave.cpp

File diff suppressed because it is too large Load Diff

210
OneWireSlave.h

@ -6,141 +6,147 @@
class OneWireSlave class OneWireSlave
{ {
public: public:
enum ReceiveEvent enum ReceiveEvent
{ {
RE_Reset, //!< The master has sent a general reset RE_Reset, //!< The master has sent a general reset
RE_Byte, //!< The master just sent a byte of data RE_Byte, //!< The master just sent a byte of data
RE_Error //!< A communication error happened (such as a timeout) ; the library will stop all 1-wire activities until the next reset RE_Error //!< A communication error happened (such as a timeout) ; the library will stop all 1-wire activities until the next reset
}; };
//! Starts listening for the 1-wire master, on the specified pin, as a virtual slave device identified by the specified ROM (7 bytes, starting from the family code, CRC will be computed internally). Reset, Presence, SearchRom and MatchRom are handled automatically. The library will use the external interrupt on the specified pin (note that this is usually not possible with all pins, depending on the board), as well as one hardware timer. Blocking interrupts (either by disabling them explicitely with sei/cli, or by spending time in another interrupt) can lead to malfunction of the library, due to tight timing for some 1-wire operations. //! Starts listening for the 1-wire master, on the specified pin, as a virtual slave device identified by the specified ROM (7 bytes, starting from the family code, CRC will be computed internally). Reset, Presence, SearchRom and MatchRom are handled automatically. The library will use the external interrupt on the specified pin (note that this is usually not possible with all pins, depending on the board), as well as one hardware timer. Blocking interrupts (either by disabling them explicitely with sei/cli, or by spending time in another interrupt) can lead to malfunction of the library, due to tight timing for some 1-wire operations.
void begin(const byte* rom, byte pinNumber); void begin(const byte* rom, byte pinNumber);
//! Stops all 1-wire activities, which frees hardware resources for other purposes. //! Stops all 1-wire activities, which frees hardware resources for other purposes.
void end(); void end();
//! Sets (or replaces) a function to be called when something is received. The callback is executed from interrupts and should be as short as possible. Failure to return quickly can prevent the library from correctly reading the next byte. //! Sets (or replaces) a function to be called when something is received. The callback is executed from interrupts and should be as short as possible. Failure to return quickly can prevent the library from correctly reading the next byte.
void setReceiveCallback(void(*callback)(ReceiveEvent evt, byte data)) { clientReceiveCallback_ = callback; } void setReceiveCallback(void(*callback)(ReceiveEvent evt, byte data)) {
clientReceiveCallback_ = callback;
}
//! Sets (or replaces) a function to be called when a bit is received. The byte reception callback is called after that if the received bit was the last of a byte. The callback is executed from interrupts and should be as short as possible. Failure to return quickly can prevent the library from correctly reading the next bit. //! Sets (or replaces) a function to be called when a bit is received. The byte reception callback is called after that if the received bit was the last of a byte. The callback is executed from interrupts and should be as short as possible. Failure to return quickly can prevent the library from correctly reading the next bit.
void setReceiveBitCallback(void(*callback)(bool bit)) { clientReceiveBitCallback_ = callback; } void setReceiveBitCallback(void(*callback)(bool bit)) {
clientReceiveBitCallback_ = callback;
}
//! Sets (or replaces) a function to be called when the library has a message to log, if the functionality is enabled in OneWireSlave.cpp. This is for debugging purposes.
void setLogCallback(void(*callback)(const char* message)) {
logCallback_ = callback;
}
//! Writes the specified bytes synchronously. This function blocks until the write operation has finished. Do not call from an interrupt handler! Returns true in case of success, false if an error occurs.
bool write(const byte* bytes, short numBytes);
//! Sets (or replaces) a function to be called when the library has a message to log, if the functionality is enabled in OneWireSlave.cpp. This is for debugging purposes. //! Starts sending the specified bytes. They will be sent in the background, and the buffer must remain valid and unchanged until the write operation has finished or is cancelled. The optional callback is used to notify when the bytes are sent, or if an error occured. Callbacks are executed from interrupts and should be as short as possible. If bytes is null or numBytes is 0, nothing is sent, which is equivalent to calling stopWrite. In any case, calling the write function will cancel the previous write operation if it didn't complete yet.
void setLogCallback(void(*callback)(const char* message)) { logCallback_ = callback; } void beginWrite(const byte* bytes, short numBytes, void(*complete)(bool error));
//! Writes the specified bytes synchronously. This function blocks until the write operation has finished. Do not call from an interrupt handler! Returns true in case of success, false if an error occurs. //! Writes a single bit synchronously. This function blocks until the bit is sent. Do not call from an interrupt handler! Returns true in case of success, false if an error occurs.
bool write(const byte* bytes, short numBytes); bool writeBit(bool value);
//! Starts sending the specified bytes. They will be sent in the background, and the buffer must remain valid and unchanged until the write operation has finished or is cancelled. The optional callback is used to notify when the bytes are sent, or if an error occured. Callbacks are executed from interrupts and should be as short as possible. If bytes is null or numBytes is 0, nothing is sent, which is equivalent to calling stopWrite. In any case, calling the write function will cancel the previous write operation if it didn't complete yet. //! Sets a bit that will be sent next time the master asks for one. Optionnaly, the repeat parameter can be set to true to continue sending the same bit each time. In both cases, the send operation can be canceled by calling stopWrite.
void beginWrite(const byte* bytes, short numBytes, void(*complete)(bool error)); void beginWriteBit(bool value, bool repeat = false, void(*bitSent)(bool error) = 0);
//! Writes a single bit synchronously. This function blocks until the bit is sent. Do not call from an interrupt handler! Returns true in case of success, false if an error occurs. //! Cancels any pending write operation, started by writeBit or write. If this function is called before the master asked for a bit, then nothing is sent to the master.
bool writeBit(bool value); void stopWrite();
//! Sets a bit that will be sent next time the master asks for one. Optionnaly, the repeat parameter can be set to true to continue sending the same bit each time. In both cases, the send operation can be canceled by calling stopWrite. //! Sets the alarmed state, that is used when the master makes a conditional search of alarmed devices.
void beginWriteBit(bool value, bool repeat = false, void(*bitSent)(bool error) = 0); void alarmed(bool value);
//! Cancels any pending write operation, started by writeBit or write. If this function is called before the master asked for a bit, then nothing is sent to the master. static byte crc8(const byte* data, short numBytes);
void stopWrite();
//! Sets the alarmed state, that is used when the master makes a conditional search of alarmed devices. private:
void alarmed(bool value); static void setTimerEvent_(short delayMicroSeconds, void(*handler)());
static void disableTimer_();
static byte crc8(const byte* data, short numBytes); static void onEnterInterrupt_();
static void onLeaveInterrupt_();
private: static void error_(const char* message);
static void setTimerEvent_(short delayMicroSeconds, void(*handler)());
static void disableTimer_();
static void onEnterInterrupt_(); static void pullLow_();
static void onLeaveInterrupt_(); static void releaseBus_();
static void error_(const char* message); static void beginReceiveBit_(void(*completeCallback)(bool bit, bool error));
static void beginSendBit_(bool bit, void(*completeCallback)(bool error));
static void pullLow_(); static void beginResetDetection_();
static void releaseBus_(); static void beginResetDetectionSendZero_();
static void cancelResetDetection_();
static void beginReceiveBit_(void(*completeCallback)(bool bit, bool error)); static void beginWaitReset_();
static void beginSendBit_(bool bit, void(*completeCallback)(bool error)); static void beginWaitCommand_();
static void beginReceive_();
static void onBitReceived_(bool bit, bool error);
static void beginResetDetection_(); static void beginSearchRom_();
static void beginResetDetectionSendZero_(); static void beginSearchRomSendBit_();
static void cancelResetDetection_(); static void continueSearchRom_(bool error);
static void searchRomOnBitReceived_(bool bit, bool error);
static void beginWaitReset_(); static void beginWriteBytes_(const byte* data, short numBytes, void(*complete)(bool error));
static void beginWaitCommand_(); static void beginReceiveBytes_(byte* buffer, short numBytes, void(*complete)(bool error));
static void beginReceive_();
static void onBitReceived_(bool bit, bool error);
static void beginSearchRom_(); static void endWrite_(bool error, bool resetInterrupts = true);
static void beginSearchRomSendBit_();
static void continueSearchRom_(bool error);
static void searchRomOnBitReceived_(bool bit, bool error);
static void beginWriteBytes_(const byte* data, short numBytes, void(*complete)(bool error)); static void onSynchronousWriteComplete_(bool error);
static void beginReceiveBytes_(byte* buffer, short numBytes, void(*complete)(bool error)); static void noOpCallback_(bool error);
static void matchRomBytesReceived_(bool error);
static void notifyClientByteReceived_(bool error);
static void bitSent_(bool error);
static void endWrite_(bool error, bool resetInterrupts = true); // interrupt handlers
static void waitReset_();
static void beginPresence_();
static void endPresence_();
static void receive_();
static void readBit_();
static void sendBitOne_();
static void sendBitZero_();
static void endSendBitZero_();
static void resetCheck_();
static void onSynchronousWriteComplete_(bool error); private:
static void noOpCallback_(bool error); static byte rom_[8];
static void matchRomBytesReceived_(bool error); static byte scratchpad_[8];
static void notifyClientByteReceived_(bool error); static Pin pin_;
static void bitSent_(bool error);
// interrupt handlers static unsigned long resetStart_;
static void waitReset_(); static unsigned long lastReset_;
static void beginPresence_();
static void endPresence_();
static void receive_();
static void readBit_();
static void sendBitOne_();
static void sendBitZero_();
static void endSendBitZero_();
static void resetCheck_();
private: static void(*receiveBitCallback_)(bool bit, bool error);
static byte rom_[8]; static void(*bitSentCallback_)(bool error);
static byte scratchpad_[8];
static Pin pin_;
static unsigned long resetStart_; static byte receivingByte_;
static unsigned long lastReset_;
static void(*receiveBitCallback_)(bool bit, bool error); static byte searchRomBytePos_;
static void(*bitSentCallback_)(bool error); static byte searchRomBitPos_;
static bool searchRomInverse_;
static bool resumeCommandFlag_;
static bool alarmedFlag_;
static byte receivingByte_; static const byte* sendBuffer_;
static byte* recvBuffer_;
static short bufferLength_;
static short bufferPos_;
static byte bufferBitPos_;
static void(*receiveBytesCallback_)(bool error);
static void(*sendBytesCallback_)(bool error);
static byte searchRomBytePos_; static volatile bool waitingSynchronousWriteToComplete_;
static byte searchRomBitPos_; static volatile bool synchronousWriteError_;
static bool searchRomInverse_;
static bool resumeCommandFlag_;
static bool alarmedFlag_;
static const byte* sendBuffer_; static bool sendingClientBytes_;
static byte* recvBuffer_;
static short bufferLength_;
static short bufferPos_;
static byte bufferBitPos_;
static void(*receiveBytesCallback_)(bool error);
static void(*sendBytesCallback_)(bool error);
static volatile bool waitingSynchronousWriteToComplete_; static bool singleBit_;
static volatile bool synchronousWriteError_; static bool singleBitRepeat_;
static void (*singleBitSentCallback_)(bool error);
static void onSingleBitSent_(bool error);
static bool sendingClientBytes_; static void(*clientReceiveCallback_)(ReceiveEvent evt, byte data);
static void(*clientReceiveBitCallback_)(bool bit);
static bool singleBit_; static void(*logCallback_)(const char* message);
static bool singleBitRepeat_;
static void (*singleBitSentCallback_)(bool error);
static void onSingleBitSent_(bool error);
static void(*clientReceiveCallback_)(ReceiveEvent evt, byte data);
static void(*clientReceiveBitCallback_)(bool bit);
static void(*logCallback_)(const char* message);
}; };
extern OneWireSlave OWSlave; extern OneWireSlave OWSlave;

Loading…
Cancel
Save