sketchbook
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
onewire_internal.h
Go to the documentation of this file.
1 /*
2  * Copyright © 2010-2015, Matthias Urlichs <matthias@urlichs.de>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License (included; see the file LICENSE)
13  * for more details.
14  */
15 
16 /* Based on work published at http://www.mikrocontroller.net/topic/44100 */
17 
18 #include <avr/io.h>
19 #include <avr/interrupt.h>
20 #include <avr/wdt.h>
21 
22 #include "dev_data.h"
23 #ifndef DEBUG_ONEWIRE
24 #define NO_DEBUG
25 #endif
26 #include "debug.h"
27 
28 #include "uart.h"
29 #include "features.h"
30 #include "onewire.h"
31 #include "moat.h"
32 
33 typedef union {
34  CFG_DATA(owid) ow_addr;
35  uint8_t addr[8];
36 } ow_addr_t;
37 extern ow_addr_t ow_addr;
38 
39 extern volatile uint8_t bitp; // mask of current bit
40 extern volatile uint8_t bytep; // position of current byte
41 extern volatile uint8_t cbuf; // char buffer, current byte to be (dis)assembled
42 
43 #ifndef EICRA
44 #define EICRA MCUCR
45 #endif
46 
47 // use timer 2 (if present), because (a) we reset the prescaler and (b) the
48 // scaler from T2 is more accurate: 4 µsec vs. 8 µsec, in 8-MHz mode
49 #ifdef ONEWIRE_USE_T2
50 #define PRESCALE 32
51 #else
52 #ifdef ONEWIRE_USE_T0
53 #define PRESCALE 64
54 #else
55 #error "Which timer should we use?"
56 #endif
57 #endif
58 
59 // Frequency-dependent timing macros
60 #if 0 // def DBGPIN // additional overhead for playing with the trace pin
61 #define _ADD_T 1
62 #else
63 #define _ADD_T 0
64 #endif
65 // T_(x)-y => value for setting the timer
66 // x: nominal time in microseconds
67 // y: overhead: increase by 1 for each 64 clock ticks
68 #define T_(c) ((F_CPU/PRESCALE)/(1000000/c)-_ADD_T)
69 #define OWT_MIN_RESET T_(410)
70 #define OWT_RESET_PRESENCE (T_(40)-1)
71 #define OWT_PRESENCE (T_(160)-1)
72 #define OWT_READLINE (T_(30)-2)
73 #define OWT_LOWTIME (T_(40)-2)
74 
75 #if (OWT_MIN_RESET>240)
76 #error Reset timing is broken, your clock is too fast
77 #endif
78 #if (OWT_READLINE<1)
79 #error Read timing is broken, your clock is too slow
80 #endif
81 
82 #if ONEWIRE_IRQNUM == -1
83 #define EN_OWINT() do {IMSK|=(1<<INT0);IFR|=(1<<INTF0);}while(0) //enable interrupt
84 #define DIS_OWINT() do {IMSK&=~(1<<INT0);} while(0) //disable interrupt
85 #define SET_RISING() do {EICRA|=(1<<ISC01)|(1<<ISC00);}while(0) //set interrupt at rising edge
86 #define SET_FALLING() do {EICRA|=(1<<ISC01);EICRA&=~(1<<ISC00);} while(0) //set interrupt at falling edge
87 #define CHK_INT_EN() (IMSK&(1<<INT0)) //test if pin interrupt enabled
88 #define PIN_INT INT0_vect // the interrupt service routine
89 #elif ONEWIRE_IRQNUM == -2
90 #define EN_OWINT() do {IMSK|=(1<<INT1);IFR|=(1<<INTF1);}while(0) //enable interrupt
91 #define DIS_OWINT() do {IMSK&=~(1<<INT1);} while(0) //disable interrupt
92 #define SET_RISING() do {EICRA|=(1<<ISC11)|(1<<ISC10);}while(0) //set interrupt at rising edge
93 #define SET_FALLING() do {EICRA|=(1<<ISC11);EICRA&=~(1<<ISC10);} while(0) //set interrupt at falling edge
94 #define CHK_INT_EN() (IMSK&(1<<INT1)) //test if pin interrupt enabled
95 #define PIN_INT INT1_vect // the interrupt service routine
96 #else
97 #error generic pin change interrupts are not yet supported
98 #endif
99 //Timer Interrupt
100 //Timer Interrupt
101 
102 #ifdef ONEWIRE_USE_T2
103 #define EN_TIMER() do {TIMSK2 |= (1<<TOIE2); TIFR2|=(1<<TOV2);}while(0) //enable timer interrupt
104 #define DIS_TIMER() do {TIMSK2 &= ~(1<<TOIE2);} while(0) // disable timer interrupt
105 #define SET_TIMER(x) do { GTCCR = (1<<PSRASY); TCNT2=(uint8_t)~(x); } while(0) // reset prescaler
106 #define TIMER_INT ISR(TIMER2_OVF_vect) //the timer interrupt service routine
107 
108 #else
109 #ifdef __AVR_ATmega8__
110 // Not sure if this is valid for others as well?
111 #define GTCCR SFIOR
112 #define PSRSYNC PSR10
113 #else
114 #ifndef PSRSYNC
115 #define PSRSYNC PSR0
116 #endif
117 #endif
118 #define EN_TIMER() do {TIMSK0 |= (1<<TOIE0); TIFR0|=(1<<TOV0);}while(0) //enable timer interrupt
119 #define DIS_TIMER() do {TIMSK0 &= ~(1<<TOIE0);} while(0) // disable timer interrupt
120 #define SET_TIMER(x) do { GTCCR = (1<<PSRSYNC); TCNT0=(uint8_t)~(x); } while(0) // reset prescaler
121 #define TIMER_INT ISR(TIMER0_OVF_vect) //the timer interrupt service routine
122 #endif
123 
124 // stupidity
125 #ifndef TIMER0_OVF_vect
126 # define TIMER0_OVF_vect TIM0_OVF_vect
127 #endif
128 
129 #define SET_LOW() do { ONEWIRE_DDR|=ONEWIRE_PBIT;} while(0) //set 1-Wire line to low
130 #define CLEAR_LOW() do {ONEWIRE_DDR&=~ONEWIRE_PBIT;} while(0) //set 1-Wire pin as input
131 
132 // Initialise the hardware
133 void onewire_init(void);
134 
135 //States / Modes
136 typedef enum {
137  OWM_SLEEP, //Waiting for next reset pulse
138  OWM_IN_RESET, //waiting of rising edge from reset pulse
139  OWM_AFTER_RESET, //Reset pulse received
140  OWM_PRESENCE, //sending presence pulse
141  OWM_SEARCH_ZERO, //SEARCH_ROM algorithm
144 
145  OWM_IDLE, // non-IRQ mode starts here (mostly)
146  OWM_READ, // reading some bits
147  OWM_WRITE, // writing some bits
148 } mode_t;
149 volatile mode_t mode; //state
150 
151 //next high-level state
152 typedef enum {
153  OWX_IDLE, // nothing is happening
154  OWX_SELECT, // will read a selector
155  OWX_COMMAND, // will read a command
156  OWX_RUNNING, // in user code
157 } xmode_t;
158 extern volatile xmode_t xmode;
159 
160 // Write this bit at next falling edge from master.
161 // We use a whole byte for this for assembly speed reasons.
162 typedef enum {
163  OWW_WRITE_0, // used in assembly
166 } wmode_t;
167 extern volatile wmode_t wmode;
168 extern volatile uint8_t actbit; // current bit. Keeping this saves 14bytes ROM
169 
170 static inline void start_reading(uint8_t bits) {
171  mode = OWM_READ;
172  cbuf=0;
173  bitp=1<<(8-bits);
174 }
175 // same thing for within the timer interrupt
176 #define START_READING(bits) do { \
177  lmode = OWM_READ; \
178  cbuf=0; \
179  lbitp=1<<(8-bits); \
180 } while(0)
181 
182 #define wait_complete(c) _wait_complete()
183 //static inline void wait_complete(char c)
184 void _wait_complete(void);
185 
186 void next_command(void) __attribute__((noreturn));
187 
188 #ifdef NEED_BITS
189 void xmit_bit(uint8_t val);
190 #endif
191 
192 // It is a net space win not to inline this.
193 void xmit_byte(uint8_t val);
194 
195 uint16_t xmit_byte_crc(uint16_t crc, uint8_t val);
196 uint16_t xmit_bytes_crc(uint16_t crc, uint8_t *buf, uint8_t len);
197 
198 #if 0
199 uint8_t rx_ready(void);
200 #endif
201 
202 uint8_t recv_any_in(void);
203 #ifdef NEED_BITS
204 void recv_bit(void);
205 #endif
206 
207 void recv_byte(void);
208 
209 uint16_t recv_bytes_crc(uint16_t crc, uint8_t *buf, uint8_t len);
210 
211 uint16_t crc16(uint16_t r, uint8_t x);
212 
213 void onewire_poll(void);
214 
215 // NOTE this disables interrupts!
216 void set_idle(void);
217 
xmode_t
Definition: onewire_internal.h:152
ow_addr_t ow_addr
Definition: onewire.c:22
Definition: onewire_internal.h:163
Definition: onewire_internal.h:165
volatile uint8_t cbuf
Definition: onewire.c:26
#define CFG_DATA(n)
Definition: dev_data.h:9
void onewire_init(void)
Definition: onewire.c:32
Definition: onewire_internal.h:142
uint8_t recv_any_in(void)
Definition: onewire.c:194
void next_command(void) __attribute__((noreturn))
Definition: onewire.c:90
Definition: onewire_internal.h:155
tuple buf
Definition: DeviceGeneric.py:119
wmode_t
Definition: onewire_internal.h:162
Definition: onewire_internal.h:154
Definition: onewire_internal.h:145
byte addr[8]
Definition: OWP_DG_1w-adaptor.ino:104
volatile uint8_t bytep
Definition: onewire.c:25
Definition: onewire_internal.h:164
uint16_t crc16(uint16_t r, uint8_t x)
Definition: crc.c:24
uint16_t xmit_byte_crc(uint16_t crc, uint8_t val)
void set_idle(void)
Definition: onewire.c:369
Definition: onewire_internal.h:139
void xmit_byte(uint8_t val)
Definition: onewire.c:155
void recv_byte(void)
Definition: onewire.c:215
Definition: onewire_internal.h:156
uint16_t recv_bytes_crc(uint16_t crc, uint8_t *buf, uint8_t len)
Definition: onewire.c:220
#define noreturn
Definition: stdnoreturn.h:27
Definition: onewire_internal.h:143
Definition: onewire_internal.h:153
return r
Definition: IMU.cpp:176
Definition: onewire_internal.h:33
char __v64qi __attribute__((__vector_size__(64)))
Definition: avx512bwintrin.h:33
void onewire_poll(void)
Definition: onewire.c:362
Definition: onewire_internal.h:141
Definition: onewire_internal.h:137
Definition: onewire_internal.h:140
Definition: onewire_internal.h:138
volatile xmode_t xmode
Definition: onewire.c:27
volatile uint8_t bitp
Definition: onewire.c:24
volatile wmode_t wmode
Definition: onewire.c:28
Definition: onewire_internal.h:147
uint16_t xmit_bytes_crc(uint16_t crc, uint8_t *buf, uint8_t len)
mode_t
Definition: onewire_internal.h:136
volatile mode_t mode
Definition: onewire_internal.h:149
Definition: onewire_internal.h:146
volatile uint8_t actbit
Definition: onewire.c:29
void _wait_complete(void)
Definition: onewire.c:101