CuVoodoo STM32F1 firmware template
onewire_master.c
Go to the documentation of this file.
1 /* This program is free software: you can redistribute it and/or modify
2  * it under the terms of the GNU General Public License as published by
3  * the Free Software Foundation, either version 3 of the License, or
4  * (at your option) any later version.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program. If not, see <http://www.gnu.org/licenses/>.
13  *
14  */
24 /* standard libraries */
25 #include <stdint.h> // standard integer types
26 #include <stdbool.h> // boolean type
27 #include <stddef.h> // NULL definition
28 
29 /* STM32 (including CM3) libraries */
30 #include <libopencmsis/core_cm3.h> // Cortex M3 utilities
31 #include <libopencm3/cm3/nvic.h> // interrupt handler
32 #include <libopencm3/stm32/rcc.h> // real-time control clock library
33 #include <libopencm3/stm32/gpio.h> // general purpose input output library
34 #include <libopencm3/stm32/timer.h> // timer library
35 
36 /* own libraries */
37 #include "global.h" // help macros
38 #include "onewire_master.h" // own definitions
39 
43 #define ONEWIRE_MASTER_TIMER 2
50 #define ONEWIRE_MASTER_PORT A
51 #define ONEWIRE_MASTER_PIN 4
55 volatile enum {
65 
66 static volatile bool slave_presence = false;
67 static uint8_t* buffer = NULL;
68 static uint32_t buffer_size = 0;
69 static volatile uint32_t buffer_bit = 0;
70 static bool onewire_master_parasite = false;
71 static uint16_t onewire_master_recovery = 0;
73 void onewire_master_setup(bool parasite, uint16_t recovery)
74 {
75  // setup GPIO with external interrupt
76  rcc_periph_clock_enable(RCC_GPIO(ONEWIRE_MASTER_PORT)); // enable clock for GPIO peripheral
77  gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // idle is high (using pull-up resistor)
78  onewire_master_parasite = parasite; // save if we should provide parasite power
79  // setup GPIO pin as output (master starts communication before slave replies)
81  gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(ONEWIRE_MASTER_PIN)); // provide parasite power (external pull-up resistor is still require for communication)
82  } else {
83  gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(ONEWIRE_MASTER_PIN)); // normal 1-Wire communication (only using external pull-up resistor)
84  }
85 
86  // setup timer to generate/measure signal timing
87  rcc_periph_clock_enable(RCC_TIM(ONEWIRE_MASTER_TIMER)); // enable clock for timer peripheral
88  timer_reset(TIM(ONEWIRE_MASTER_TIMER)); // reset timer state
89  timer_set_mode(TIM(ONEWIRE_MASTER_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
90  timer_set_prescaler(TIM(ONEWIRE_MASTER_TIMER), 1-1); // don't use prescale since this 16 bits timer allows to wait > 480 us used for the reset pulse ( 1/(72E6/1/(2**16))=910us )
91 
92  // use comparator to time signal (without using the output), starting at slot start
93  timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC1, 1*(rcc_ahb_frequency/1000000)-1); // use compare function to time master pulling low when reading (1 < Tlowr < 15)
94  timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC2, 7*(rcc_ahb_frequency/1000000)-1); // use compare function to read or write 0 or 1 (1 < Trw < 15)
95  timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC3, 62*(rcc_ahb_frequency/1000000)-1); // use compare function to end time slot (60 < Tslot < 120), this will be followed by a recovery time (end of timer)
96  timer_set_oc_value(TIM(ONEWIRE_MASTER_TIMER), TIM_OC4, (70-10)*(rcc_ahb_frequency/1000000)-1); // use compare function to detect slave presence (15 < Tpdh < 60 + 60 < Tpdl < 240), with hand tunig
97  onewire_master_recovery = 5; // set minimum recovery time
98  if (recovery>onewire_master_recovery) {
99  onewire_master_recovery = recovery; // save desired recovery time
100  }
101  if (UINT16_MAX/onewire_master_recovery<(rcc_ahb_frequency/1000000)) { // catch integer overflow
102  onewire_master_recovery = UINT16_MAX; // save maximum value
103  } else {
104  onewire_master_recovery *= (rcc_ahb_frequency/1000000); // save actual recovery time value
105  }
106 
107  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_UIF); // clear update (overflow) flag
108  timer_update_on_overflow(TIM(ONEWIRE_MASTER_TIMER)); // only use counter overflow as UEV source (use overflow as start time or timeout)
109  timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_UIE); // enable update interrupt for overflow
110  nvic_enable_irq(NVIC_TIM_IRQ(ONEWIRE_MASTER_TIMER)); // catch interrupt in service routine
111 
112  slave_presence = false; // reset state
113  onewire_master_state = ONEWIRE_STATE_IDLE; // reset state
114 }
115 
117 {
118  // prepare timer
119  timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to reconfigure it
120  timer_set_counter(TIM(ONEWIRE_MASTER_TIMER),0); // reset counter
121  timer_set_period(TIM(ONEWIRE_MASTER_TIMER), 490*(rcc_ahb_frequency/1000000)-1); // set timeout to > 480 us (480 < Trst)
122 
123  slave_presence = false; // reset state
125 
126  gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(ONEWIRE_MASTER_PIN)); // normal 1-Wire communication (only using external pull-up resistor)
127  gpio_clear(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal low to start reset (it's not important if it was low in the first place since the reset pulse has no maximum time)
128  timer_enable_counter(TIM(ONEWIRE_MASTER_TIMER)); // start timer
129 
130  while (onewire_master_state!=ONEWIRE_STATE_DONE && onewire_master_state!=ONEWIRE_STATE_ERROR) { // wait until reset procedure completed
131  __WFI(); // go to sleep
132  }
133  if (ONEWIRE_STATE_ERROR==onewire_master_state) { // an error occurred
134  return false;
135  }
136 
137  return slave_presence;
138 }
139 
144 static bool onewire_master_write(void)
145 {
146  buffer_bit = 0; // reset bit index
148 
149  // prepare timer
150  timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to reconfigure it
151  timer_set_counter(TIM(ONEWIRE_MASTER_TIMER),0); // reset counter
152  uint16_t timeout = TIM_CCR3(TIM(ONEWIRE_MASTER_TIMER)); // time until new slot (= end of slot+recovery)
153  if (UINT16_MAX-timeout<onewire_master_recovery) { // catch integer overflow
154  timeout = UINT16_MAX; // set maximum value
155  } else {
156  timeout += onewire_master_recovery; // add recovery time to end of slot
157  }
158  timer_set_period(TIM(ONEWIRE_MASTER_TIMER), timeout-1); // set time for new time slot (Trec>1, after time slot end and recovery time)
159  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF); // clear output compare flag
160  timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC2IE); // enable compare interrupt for bit setting
161  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF); // clear output compare flag
162  timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC3IE); // enable compare interrupt for end of time slow
163 
164  // start writing
165  gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(ONEWIRE_MASTER_PIN)); // normal 1-Wire communication (only using external pull-up resistor)
166  gpio_clear(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal low to start slot
167  timer_enable_counter(TIM(ONEWIRE_MASTER_TIMER)); // start timer
168  while (onewire_master_state!=ONEWIRE_STATE_DONE && onewire_master_state!=ONEWIRE_STATE_ERROR) { // wait until write procedure completed
169  __WFI(); // go to sleep
170  }
171  if (ONEWIRE_STATE_ERROR==onewire_master_state) { // an error occurred
172  return false;
173  }
174  return true;
175 }
176 
181 static bool onewire_master_read(void)
182 {
183  if (0==buffer_size) { // check input
184  return false;
185  }
186  buffer_bit = 0; // reset bit index
188 
189  // prepare timer
190  timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer to reconfigure it
191  timer_set_counter(TIM(ONEWIRE_MASTER_TIMER),0); // reset counter
192  uint16_t timeout = TIM_CCR3(TIM(ONEWIRE_MASTER_TIMER)); // time until new slot (= end of slot+recovery)
193  if (UINT16_MAX-timeout<onewire_master_recovery) { // catch integer overflow
194  timeout = UINT16_MAX; // set maximum value
195  } else {
196  timeout += onewire_master_recovery; // add recovery time to end of slot
197  }
198  timer_set_period(TIM(ONEWIRE_MASTER_TIMER), timeout-1); // set time for new time slot (Trec>1, after time slot end and recovery time)
199  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF); // clear output compare flag
200  timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC1IE); // enable compare interrupt for stop pulling low
201  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF); // clear output compare flag
202  timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC2IE); // enable compare interrupt for bit setting
203  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF); // clear output compare flag
204  timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC3IE); // enable compare interrupt for end of time slow
205 
206  // start reading
207  gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(ONEWIRE_MASTER_PIN)); // normal 1-Wire communication (only using external pull-up resistor)
208  gpio_clear(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal low to start slot
209  timer_enable_counter(TIM(ONEWIRE_MASTER_TIMER)); // start timer
210  while (onewire_master_state!=ONEWIRE_STATE_DONE && onewire_master_state!=ONEWIRE_STATE_ERROR) { // wait until read procedure completed
211  __WFI(); // go to sleep
212  }
213  if (ONEWIRE_STATE_ERROR==onewire_master_state) { // an error occurred
214  return false;
215  }
216  return true;
217 }
218 
219 uint8_t onewire_master_crc(uint8_t* data, uint32_t length)
220 {
221  if (NULL==data || 0==length) { // check input
222  return 0; // wrong input
223  }
224 
225  uint8_t crc = 0x00; // initial value
226  for (uint8_t i=0; i<length; i++) { // go through every byte
227  crc ^= data[i]; // XOR byte
228  for (uint8_t b=0; b<8; b++) { // go through every bit
229  if (crc&0x01) { // least significant bit is set (we are using the reverse way)
230  crc = (crc>>1)^0x8C; // // shift to the right (for the next bit) and XOR with (reverse) polynomial
231  } else {
232  crc >>= 1; // just shift right (for the next bit)
233  }
234  }
235  }
236  return crc;
237 }
238 
239 bool onewire_master_function_read(uint8_t function, uint8_t* data, uint32_t bits)
240 {
241  // send function command
242  buffer_size = 8; // function command is only one byte
243  buffer = &function; // set the buffer to the function code
244  if (!onewire_master_write()) { // send command
245  return false; // an error occurred
246  }
247 
248  if (NULL==data || 0==bits) { // there is no data to read
249  return true; // operation completed
250  }
251 
252  // read data
253  buffer_size = bits; // save number of bits to read
254  buffer = data; // set the buffer to the data to write
255  if (!onewire_master_read()) { // read bits from slave
256  return false; // an error occurred
257  }
258 
259  return true;
260 }
261 
262 bool onewire_master_function_write(uint8_t function, uint8_t* data, uint32_t bits)
263 {
264  // send function command
265  buffer_size = 8; // function command is only one byte
266  buffer = &function; // set the buffer to the function code
267  if (!onewire_master_write()) { // send command
268  return false; // an error occurred
269  }
270 
271  if (NULL==data || 0==bits) { // there is no data to read
272  return true; // operation completed
273  }
274 
275  // copy data from user buffer
276  buffer_size = bits; // save number of bits to write
277  buffer = data; // set the buffer to the data to write
278  // write data
279  if (!onewire_master_write()) { // read bits from slave
280  return false; // an error occurred
281  }
282 
283  return true;
284 }
285 
287 {
288  uint8_t rom_code[8] = {0}; // to store 64 bits ROM code
289  if (!onewire_master_function_read(0x33, rom_code, 64)) { // read ROM code (I'm cheating because the ROM command isn't a function command, but it works the same way in the end)
290  return 0; // an error occurred
291  }
292  if (onewire_master_crc(rom_code, LENGTH(rom_code))) { // verify checksum
293  return 0; // checksum is wrong (not 0)
294  }
295 
296  // return ROM code
297  uint64_t code = 0;
298  for (uint32_t i=0; i<8; i++) {
299  code += (uint64_t)rom_code[i]<<(8*i); // add byte
300  }
301 
302  return code;
303 }
304 
305 bool onewire_master_rom_search(uint64_t* code, bool alarm)
306 {
307  static uint8_t conflict_last = 64; // on which bit has the conflict been detected (64 means there hasn't been)
308  uint8_t conflict_current = 64; // to remember on which bit the last unknown conflict has been detected
309  uint8_t bits[1] = {0}; // small buffer to store the bits used to search the ROM codes
310 
311  // send SEARCH ROM command
312  uint8_t command = 0xf0; // SEARCH ROM command
313  if (alarm) { // looking only for ROM codes for slaves in alarm state
314  command = 0xec; // use ALARM SEARCH ROM command instead
315  }
316  if (!onewire_master_function_read(command, NULL, 0)) { // send SEARCH ROM command
317  goto end; // an error occurred
318  }
319 
320  if (conflict_last>=64) { // no previous conflict has been detected
321  *code = 0; // restart search codes
322  }
323 
324  buffer = bits; // buffer to read up to two bits
325  for (uint8_t bit=0; bit<64; bit++) { // go through all 64 bits ROM code
326  buffer_size = 2; // read two first bits to detect conflict
327  if (!onewire_master_read()) { // read ROM ID from slave
328  goto end; // an error occurred
329  }
330  switch (buffer[0]&0x03) { // check 2 bits received
331  case 0: // collision detected
332  if (bit==conflict_last) { // this conflict is known
333  *code |= (((uint64_t)1)<<bit); // use 0 as next bit
334  } else { // unknown conflict
335  conflict_current = bit; // remember conflict
336  *code &= ~(((uint64_t)1)<<bit); // use 1 as next bit
337  }
338  break;
339  case 1: // no conflict, valid bit is 1
340  *code |= (((uint64_t)1)<<bit); // remember valid bit 1
341  break;
342  case 2: // no conflict, valid bit is 0
343  *code &= ~(((uint64_t)1)<<bit); // remember valid bit 0
344  break;
345  default: // two 1's indicate there is no slave
346  goto end; // an error has occurred
347  }
348  buffer_size = 1; // to send next bit
349  buffer[0] = (*code>>bit); // set bit to send
350  if (!onewire_master_write()) { // send bit
351  goto end; // an error has occurred
352  }
353  }
354  // verify ROM code
355  uint8_t rom_code[8] = {0}; // to store ROM code
356  for (uint8_t i=0; i<LENGTH(rom_code); i++) {
357  rom_code[i] = *code>>(8*i); // split and save last code in ROM code
358  }
359  if (onewire_master_crc(rom_code, LENGTH(rom_code))) { // verify checksum
360  *code = 0; // return the last code found since it's valid
361  }
362 
363 end:
364  conflict_last = conflict_current; // update the last seen and unknown conflict
365  if (conflict_current<64) { // we have seen an unknown conflict
366  return true; // tell there are more slaves
367  } else { // no conflict seen
368  return false; // no more slaves
369  }
370 }
371 
373 {
374  if (!onewire_master_function_write(0xcc, NULL, 0)) { // send SKIP ROM command
375  return false; // an error occurred
376  }
377  return true;
378 }
379 
380 bool onewire_master_rom_match(uint64_t code)
381 {
382  uint8_t rom_code[8] = {0}; // to store ROM code
383  for (uint8_t i=0; i<LENGTH(rom_code); i++) {
384  rom_code[i] = code>>(8*i); // split and save code in ROM code
385  }
386  if (!onewire_master_function_write(0x55, rom_code, 64)) { // send MATCH ROM command with ROM code
387  return false; // an error occurred
388  }
389  return true;
390 }
391 
392 
395 {
396  if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_UIF)) { // overflow update event happened
397  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_UIF); // clear flag
398  switch (onewire_master_state) {
399  case ONEWIRE_STATE_MASTER_RESET: // reset pulse has been started
400  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC4IF); // clear output compare flag
401  timer_enable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC4IE); // enable compare interrupt for presence detection
402  gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // set signal high again for slaves to respond
404  break;
405  case ONEWIRE_STATE_SLAVE_PRESENCE: // waiting for slave presence but none received
406  timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer
407  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC4IE); // disable compare interrupt for presence detection
408  onewire_master_state = ONEWIRE_STATE_DONE; // go to next state
409  break;
410  case ONEWIRE_STATE_MASTER_READ: // end of time slot and recovery time for reading bit
411  case ONEWIRE_STATE_MASTER_WRITE: // end of time slot and recovery time for writing bit
412  if (buffer_bit<buffer_size) { // check if byte to read/write are remaining
413  gpio_clear(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal low to start next slot
414  } else { // all bytes read/written
415  timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer
416  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC1IE); // disable compare interrupt for master pull low
417  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC2IE); // disable compare interrupt for read/write bit
418  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC3IE); // disable compare interrupt for end of slot
419  onewire_master_state = ONEWIRE_STATE_DONE; // set end state
420  }
421  break;
422  default: // unknown state for this stage
423  timer_disable_counter(TIM(ONEWIRE_MASTER_TIMER)); // disable timer
424  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC1IE); // disable all compare interrupt
425  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC2IE); // disable all compare interrupt
426  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC3IE); // disable all compare interrupt
427  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC4IE); // disable all compare interrupt
428  gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal high (idle state)
429  onewire_master_state = ONEWIRE_STATE_ERROR; // indicate error
430  }
432  gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(ONEWIRE_MASTER_PIN)); // provide parasite power
433  } else {
434  gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(ONEWIRE_MASTER_PIN)); // normal 1-Wire communication (only using external pull-up resistor)
435  }
436  } else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF)) { // compare event happened for master pull low end for read
437  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC1IF); // clear flag
438  switch (onewire_master_state) {
439  case ONEWIRE_STATE_MASTER_READ: // master has to read a bit
440  gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal high to end time slot
441  break;
442  default: // unknown state for this stage
443  break; // let the overflow handle the error if any
444  }
445  } else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF)) { // compare event happened for bit sampling/setting
446  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC2IF); // clear flag
447  switch (onewire_master_state) {
448  case ONEWIRE_STATE_MASTER_WRITE: // master has to write a bit
449  if (buffer_bit<buffer_size) { // check if byte to send are remaining
450  if (buffer[buffer_bit/8]&(1<<(buffer_bit%8))) { // check bit (LSb first)
451  gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // set signal high again to write "1"
452  }
453  buffer_bit++; // got to next bit
454  } else {
455  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC2IE); // disable compare interrupt
456  onewire_master_state = ONEWIRE_STATE_ERROR; // indicate error
457  }
458  break;
459  case ONEWIRE_STATE_MASTER_READ: // master has to read a bit set by slave
460  if (buffer_bit<buffer_size) { // check if byte to send are remaining
461  if (gpio_get(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN))) { // check if the slave kept it low
462  buffer[buffer_bit/8] |= (1<<(buffer_bit%8)); // save bit "1"
463  } else {
464  buffer[buffer_bit/8] &= ~(1<<(buffer_bit%8)); // save bit "0"
465  }
466  buffer_bit++; // got to next bit
467  } else {
468  timer_disable_irq(TIM(ONEWIRE_MASTER_TIMER), TIM_DIER_CC2IE); // disable compare interrupt
469  onewire_master_state = ONEWIRE_STATE_ERROR; // indicate error
470  }
471  break;
472  default: // unknown state for this stage
473  break; // let the overflow handle the error if any
474  }
475  } else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF)) { // compare event happened for end to time slot
476  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC3IF); // clear flag
477  gpio_set(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN)); // pull signal high to end time slot
478  if (onewire_master_parasite) { // provide power during recovery time
479  gpio_set_mode(GPIO(ONEWIRE_MASTER_PORT), GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(ONEWIRE_MASTER_PIN)); // provide parasite power
480  }
481  } else if (timer_get_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC4IF)) { // compare event happened for slave presence detection
482  timer_clear_flag(TIM(ONEWIRE_MASTER_TIMER), TIM_SR_CC4IF); // clear flag
483  if (gpio_get(GPIO(ONEWIRE_MASTER_PORT),GPIO(ONEWIRE_MASTER_PIN))) { // check is a slave let its presence know by pulling low
484  slave_presence = false; // remember no slave(s) responded
485  } else {
486  slave_presence = true; // remember slave(s) responded
487  }
488  } else { // no other interrupt should occur
489  while (true); // unhandled exception: wait for the watchdog to bite
490  }
491 }
static volatile uint32_t buffer_bit
number of bits read/written
#define TIM_ISR(x)
get interrupt service routine for timer base on TIM identifier
Definition: global.h:113
#define ONEWIRE_MASTER_PORT
GPIO port.
#define RCC_GPIO(x)
get RCC for GPIO based on GPIO identifier
Definition: global.h:105
reset pulse started
uint64_t onewire_master_rom_read(void)
send READ ROM command and read ROM code response
bool onewire_master_rom_search(uint64_t *code, bool alarm)
send SEARCH ROM command
#define NVIC_TIM_IRQ(x)
get NVIC IRQ for timer base on TIM identifier
Definition: global.h:111
bool onewire_master_function_write(uint8_t function, uint8_t *data, uint32_t bits)
issue function and write data
#define ONEWIRE_MASTER_PIN
GPIO pin.
communication error
waiting for slave response to reset pulse
void onewire_master_setup(bool parasite, uint16_t recovery)
setup 1-wire peripheral
global definitions and methods (API)
#define GPIO(x)
get GPIO based on GPIO identifier
Definition: global.h:103
static bool onewire_master_read(void)
read bits on 1-Wire bus
#define RCC_TIM(x)
get RCC for timer based on TIM identifier
Definition: global.h:109
library for 1-wire protocol as master (API)
bool onewire_master_function_read(uint8_t function, uint8_t *data, uint32_t bits)
issue function and read data
bool onewire_master_rom_skip(void)
send SKIP ROM command (all slaves on the bus will be selected)
master is writing bits
static bool onewire_master_write(void)
write bits on 1-Wire bus
to count the number of possible states
static uint16_t onewire_master_recovery
the recovery time in us (1 < Trec)
static uint8_t * buffer
input/output buffer for read/write commands/functions
static uint32_t buffer_size
size of buffer in bits
communication complete
#define LENGTH(x)
get the length of an array
Definition: global.h:26
bool onewire_master_rom_match(uint64_t code)
send MATCH ROM command to select a specific slave
static bool onewire_master_parasite
if parasite power should be provided whenever the is no communication
#define TIM(x)
get TIM based on TIM identifier
Definition: global.h:107
static volatile bool slave_presence
if slaves have been detected
uint8_t onewire_master_crc(uint8_t *data, uint32_t length)
compute CRC for 1-Wire
no current communication
master is reading bits
bool onewire_master_reset(void)
send reset pulse
enum @0 onewire_master_state
state of 1-Wire communication
#define ONEWIRE_MASTER_TIMER
timer ID