1-Wire and ENS210 driver stack
DS28E18.c
Go to the documentation of this file.
1 /**
2  * @file DS28E18.c
3  * @brief Driver for a DS28E18 slave on a 1-Wire bus.
4  *
5  * @par Update history - Cleanups by Dave Nadler
6  * - 30-October-2023 Initial version.
7  * - 13-March-2026 Added many missing error checks.
8  *
9  * @todo Isolate DELAY_MSEC to make porting easier.
10  * @todo Use OneWire_ROM_ID_T for ROM ID in DS2485 code.
11  * @todo Add DS28E18 status register structure definition and interpretation.
12  * @todo Make a DS28E18 class to support multiple DS28E18 devices more easily.
13  */
14 
15 // ToDo 1-Wire: Isolate DELAY_MSEC to make porting easier
16 // ToDo 1-Wire: Use OneWire_ROM_ID_T for ROM ID in DS2485 code
17 // ToDo 1-Wire: Add DS28E18 status register structure definition and interpretation
18 // ToDo 1-Wire: Make a DS28E18 class to support multiple DS28E18 more easily
19 
20 /*******************************************************************************
21 * Copyright (C) Maxim Integrated Products, Inc., All rights Reserved.
22 *
23 * This software is protected by copyright laws of the United States and
24 * of foreign countries. This material may also be protected by patent laws
25 * and technology transfer regulations of the United States and of foreign
26 * countries. This software is furnished under a license agreement and/or a
27 * nondisclosure agreement and may only be used or reproduced in accordance
28 * with the terms of those agreements. Dissemination of this information to
29 * any party or parties not specified in the license agreement and/or
30 * nondisclosure agreement is expressly prohibited.
31 *
32 * The above copyright notice and this permission notice shall be included
33 * in all copies or substantial portions of the Software.
34 *
35 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
36 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
38 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
39 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
40 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41 * OTHER DEALINGS IN THE SOFTWARE.
42 *
43 * Except as contained in this notice, the name of Maxim Integrated
44 * Products, Inc. shall not be used except as stated in the Maxim Integrated
45 * Products, Inc. Branding Policy.
46 *
47 * The mere transfer of this software does not imply any licenses
48 * of trade secrets, proprietary technology, copyrights, patents,
49 * trademarks, maskwork rights, or any other form of intellectual
50 * property whatsoever. Maxim Integrated Products, Inc. retains all
51 * ownership rights.
52 *******************************************************************************
53 */
54 
55 // Enable debugging here or via command-line macro definition:
56 //#define DS28E18_ENABLE_PRINTF_DEBUGGING
57 
58 /* **** Includes **** */
59 #include <stdio.h> // printf for diagnostics
60 #include <string.h>
61 #include <stdint.h>
62 #include <assert.h>
63 
64 #include "DS28E18.h"
65 
66 #ifdef USE_MAXIM_DEFINITIONS // Maxim
67  #include "mxc_delay.h"
68  #include "mxc_sys.h"
69  #include "tmr.h"
70  #define DELAY_MSEC(msec_) mxc_delay(MXC_DELAY_MSEC(msec_))
71 #else
72  #include "FreeRTOS.h"
73  #include "task.h"
74  #define DELAY_MSEC(msec_) vTaskDelay(pdMS_TO_TICKS(msec_))
75 #endif
76 
77 #ifdef DS28E18_ENABLE_PRINTF_DEBUGGING
78  #define PRINTF(...) printf("DS28E18: " __VA_ARGS__)
79 #else
80  #define PRINTF(...) {}
81 #endif
82 
83 /* **** Globals **** */
85 /*
86  * For example, prototype Temperature probe's DS28E18 ID is set by DS28E18_Init:
87  * current_DS28E18_ROM_ID.ID[0] uint8_t 0x56 (Hex)
88  * current_DS28E18_ROM_ID.ID[1] uint8_t 0xf6 (Hex)
89  * current_DS28E18_ROM_ID.ID[2] uint8_t 0x60 (Hex)
90  * current_DS28E18_ROM_ID.ID[3] uint8_t 0x12 (Hex)
91  * current_DS28E18_ROM_ID.ID[4] uint8_t 0x0 (Hex)
92  * current_DS28E18_ROM_ID.ID[5] uint8_t 0x0 (Hex)
93  * current_DS28E18_ROM_ID.ID[6] uint8_t 0x0 (Hex)
94  * current_DS28E18_ROM_ID.ID[7] uint8_t 0x5c (Hex)
95  */
96 
97 /* **** Locals **** */
98 static DS28E18_one_wire_rom_commands_T current_ROM_command; // (normally MATCH_ROM, SKIP_ROM during device search)
99 static DS28E18_sequence_T localPacket; // holds command sequence constructed below
100 // Eliminates cut-and-paste of memcpy etc:
101 static inline void appendToSequencerPacket(const uint8_t* sequencerCmds, int length) {
102  memcpy(&localPacket.sequenceData[localPacket.sequenceIdx], sequencerCmds, length);
103  localPacket.sequenceIdx += length;
104 };
105 // Append an array (macro eliminates repeated error-prone sizeof)
106 #define APPEND_TO_PACKET(s_) { appendToSequencerPacket(s_, sizeof(s_)); }
107 
108 #define SPU_Delay_tOP_msec 1 // say what? what is this delay?
109 
110 
111 /* **** Functions **** */
112 
113 /*
114 On DS28E18 power-up, the ROM ID value is 56000000000000B2. The uniquely programmed factory value for each DS28E18
115 needs to be loaded from memory. After power-up, issue a Skip ROM command followed by a Write GPIO Configuration
116 command. This initial command populates (for all DS28E18 on the bus) the unique device ROM ID, including family code, serialization, and CRC-16.
117 Ignore the command CRC-16 result and the Result byte, as both might be invalid. Next issue a successful Write GPIO
118 Configuration command to configure the GPIO pullup/down states so that the voltage on the GPIO ports is known.
119 */
120 /// Initialize all DS28E18 on the 1-Wire bus.
121 /// @return number of DS28E18 found on the bus.
123 {
124  int devicesFound = 0;
125  int error = 0;
126 
127  PRINTF("-- Populate unique ROM ID of **ALL** devices on 1-Wire line --\n");
128  PRINTF("-- .. using Write GPIO Configuration command (ignore result) --\n");
129  error = DS28E18_SetOnewireSpeed(STANDARD); // Set DS2485 master 1-Wire speed, must be standard during search
130  if (error)
131  {
132  return 0; // no devices found because of error...
133  }
134  DS28E18_SetRomCommand(SKIP_ROM); // Skip trying to match a particular ROM ID
135  DS28E18_WriteGpioConfiguration(CONTROL, 0xA5, 0x0F); // populate all DS28E18 ROMID etc. Write is not addressed to a specific DS28E18 (now in SKIP_ROM mode)
136  DS28E18_SetRomCommand(MATCH_ROM); // for all subsequent operations...
137 
138  PRINTF("-- Search and initialize every device found on the 1-Wire line --\n");
139  // Temporary ID tracks last DS28E18 found, may be clobbered if there's a DS2485 error...
140  OneWire_ROM_ID_T temp_rom_id = { .ID = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
141  bool last_device_found = false;
142  while ( !last_device_found )
143  {
144  // Look for the next DS28E18
145  bool startNewSearch = (devicesFound==0);
146  int searchError = OneWire_Search(&temp_rom_id, startNewSearch, &last_device_found);
147  if(searchError) break;
148  devicesFound++;
149 
150  PRINTF("Found ROM ID: x");
151  #ifdef DS28E18_ENABLE_PRINTF_DEBUGGING
152  for(uint8_t i = 0; i < sizeof(temp_rom_id.ID); i++)
153  {
154  printf("%02X", temp_rom_id.ID[i]);
155  }
156  printf("\n");
157  #endif
158 
159  // ToDo 1-Wire: DS28E18_Init() assumes any 1-Wire device found on the bus is a DS28E18
160  current_DS28E18_ROM_ID = temp_rom_id; // Set active DS28E18 to device just found
161 
162  PRINTF("-- Write GPIO Configuration so the voltage on GPIO ports is known --\n");
163  if(!DS28E18_WriteGpioConfiguration(CONTROL, 0xA5, 0x0F))
164  {
165  return false;
166  }
167 
168  PRINTF("-- Read Device Status information (clears POR status bit) --\n");
169  uint8_t status[4] = {0xFF, 0xFF, 0xFF, 0xFF};
170  if(!DS28E18_DeviceStatus(status))
171  {
172  return false;
173  }
174  else
175  {
176  PRINTF("-- Status: ");
177  #ifdef DS28E18_ENABLE_PRINTF_DEBUGGING
178  for(uint8_t i = 0; i < sizeof(status); i++)
179  {
180  printf("%02X.", status[i]);
181  }
182  printf("\n");
183  #endif
184  }
185  };
186 
187  DS28E18_BuildPacket_ClearSequencerPacket(); // general initialization (sequencer is not used during Init() above).
188 
189  return devicesFound>0;
190 }
191 
192 //-----------------------------------------------------------------------------
193 /// Set desired 1-Wire speed between Standard and Overdrive for both, 1-Wire master and slave.
194 /// @return
195 /// 0 - At least one device is detected after a 1-Wire reset is performed on new speed.
196 /// 1 - Failure.
197 int DS28E18_SetOnewireSpeed(one_wire_speeds spd)
198 {
199  int error = 1;
200  switch (spd)
201  {
202  case STANDARD:
203  PRINTF("STANDARD*\n");
204  //Set host speed to Standard
205  error = OneWire_Set_OneWireMasterSpeed(STANDARD);
206  if (error) break;
207  // do a 1-Wire reset in Standard and catch presence result
208  error = OneWire_ResetPulse();
209  break;
210  case OVERDRIVE:
211  PRINTF("OVERDRIVE*\n");
212  //From Standard speed, do a 1-wire reset + Overdrive Skip ROM to set every device on the line to Overdrive
213  error = OneWire_ResetPulse();
214  if (error) break;
215  error = OneWire_WriteByte(OVERDRIVE_SKIP);
216  if (error) break;
217  DELAY_MSEC(40);
218  //Set host speed to Overdrive
219  error = OneWire_Set_OneWireMasterSpeed(OVERDRIVE);
220  if (error) break;
221  // do a 1-Wire reset in Overdrive and catch presence result
222  error = OneWire_ResetPulse();
223  break;
224  default:
225  break;
226  }
227  return error;
228 }
229 
230 /// Set 1-Wire 'current_ROM_command' (normally MATCH_ROM, SKIP_ROM during device search).
231 /// Does not send anything to lower-level code; just sets the operating mode for this DS28E18 layer.
233 {
234  assert(rom_cmd==MATCH_ROM || rom_cmd==SKIP_ROM);
235  current_ROM_command = rom_cmd;
236 }
237 /// Return the value of 'current_ROM_command'
239 {
240  return current_ROM_command;
241 }
242 
243 static unsigned int calculateCrc16Byte(uint8_t data, unsigned int crc)
244 {
245  const uint8_t oddparity[] = {0, 1, 1, 0, 1, 0, 0, 1,
246  1, 0, 0, 1, 0, 1, 1, 0};
247 
248  unsigned int data16 = (data ^ crc) & 0xff;
249  crc = (crc >> 8) & 0xff;
250 
251  if (oddparity[data16 & 0xf] ^ oddparity[data16 >> 4]) {
252  crc ^= 0xc001;
253  }
254 
255  data16 <<= 6;
256  crc ^= data16;
257  data16 <<= 1;
258  crc ^= data16;
259 
260  return crc;
261 }
262 static unsigned int calculateCrc16Block(uint8_t *data, int dataSize, unsigned int crc)
263 {
264  for (int i = 0; i < dataSize; i++)
265  {
266  crc = calculateCrc16Byte(data[i], crc);
267  }
268  return crc;
269 }
270 
271 /// Run a DS28E18 command (can be run sequencer), wait for it to complete, and return bool SUCCESS.
272 static bool run_command(DS28E18_device_function_commands_T command, uint8_t *parameters, int parameters_size, int delay_msec, uint8_t *result_data)
273 {
274  OneWire_ROM_ID_T ROMID;
275  uint8_t tx_packet[3 + parameters_size];
276  uint8_t tx_packet_CRC16[2];
277  unsigned int expectedCrc = 0;
278  uint8_t headerResponse[2];
279  int result_data_length;
280  uint8_t rx_packet_CRC16[2];
281  int error = 0; // error return from OneWire functions (0 return is no error)
282 
283  tx_packet[0] = COMMAND_START;
284  tx_packet[1] = 1 + parameters_size;
285  tx_packet[2] = command;
286  if (parameters_size)
287  {
288  memcpy(&tx_packet[3], parameters, parameters_size);
289  }
290 
291  //Reset pulse + presence
292  error = OneWire_ResetPulse();
293  if(error) return false;
294 
295  //Execute ROM Command currently set
296  switch(current_ROM_command)
297  {
298  case READ_ROM:
299  PRINTF("Error: Not appropriate use of Read ROM \n");
300  return false;
301  case MATCH_ROM:
302  ROMID = current_DS28E18_ROM_ID;
303  error = OneWire_WriteByte(MATCH_ROM);
304  if(error) return false;
305  error = OneWire_WriteBlock(ROMID.ID, 8);
306  if(error) return false;
307  break;
308  case SEARCH_ROM:
309  PRINTF("Error: Not appropriate use of Search ROM \n");
310  return false;
311  case SKIP_ROM:
312  error = OneWire_WriteByte(SKIP_ROM);
313  if(error) return false;
314  break;
315  case RESUME:
316  error = OneWire_WriteByte(RESUME);
317  if(error) return false;
318  break;
319  case OVERDRIVE_SKIP:
320  error = OneWire_WriteByte(OVERDRIVE_SKIP);
321  if(error) return false;
322  break;
323  case OVERDRIVE_MATCH:
324  ROMID = current_DS28E18_ROM_ID;;
325  error = OneWire_WriteByte(OVERDRIVE_MATCH);
326  if(error) return false;
327  error = OneWire_WriteBlock(ROMID.ID, 8);
328  if(error) return false;
329  break;
330  default:
331  PRINTF("Error: 1-Wire Communication Error\n");
332  return false;
333  }
334 
335  //Write command-specific 1-Wire packet, tx_packet
336  error = OneWire_WriteBlock(tx_packet, sizeof(tx_packet));
337  if(error) return false;
338 
339  //Read CRC16 of the tx_packet
340  error = OneWire_ReadBlock(tx_packet_CRC16, sizeof(tx_packet_CRC16));
341  if(error) return false;
342 
343  //Verify CRC16
344  expectedCrc = calculateCrc16Block(tx_packet, sizeof(tx_packet), expectedCrc);
345  expectedCrc ^= 0xFFFFU;
346  if (expectedCrc != (unsigned int)((tx_packet_CRC16[1] << 8) | tx_packet_CRC16[0]))
347  {
348  PRINTF("Error: Invalid CRC16\n");
349  return false;
350  }
351 
352  //Send Release Byte (0xAA) then enable SPU
353  error = OneWire_WriteBytePower(OneWire_Release_Byte_xAA); // Enables SPU (hence 'Power')
354  if(error) return false;
355 
356  //Command-specific delay
357  DELAY_MSEC(delay_msec);
358 
359  // NO! BUG! Some applications require SPU stays on to power peripheral, specifically DS28E18: Disable SPU
360  // OneWire_Enable_SPU(false); // Bug: DS28E18 run_command disabled SPU
361 
362  // Read command-specific 1-Wire packet
363  error = OneWire_ReadBlock(headerResponse, sizeof(headerResponse)); //Dummy Byte + Length Byte;
364  if(error) return false;
365  result_data_length = headerResponse[1];
366 
367  if (result_data_length == 0xFF)
368  {
369  PRINTF("Error: 1-Wire Communication Error\n");
370  return false;
371  }
372 
373  //Read rest of response
374  error = OneWire_ReadBlock(result_data, result_data_length); //Result Byte + Result Data
375  if(error) return false;
376 
377  //Read CRC16 of the rx_packet
378  error = OneWire_ReadBlock(rx_packet_CRC16, sizeof(rx_packet_CRC16));
379  if(error) return false;
380 
381  //Verify CRC16
382  expectedCrc = 0;
383  expectedCrc = calculateCrc16Block(&headerResponse[1], sizeof(headerResponse) - 1, expectedCrc);
384  expectedCrc = calculateCrc16Block(result_data, result_data_length, expectedCrc);
385  expectedCrc ^= 0xFFFFU;
386  if (expectedCrc != (unsigned int)((rx_packet_CRC16[1] << 8) | rx_packet_CRC16[0]))
387  {
388  PRINTF("Error: Invalid CRC16\n");
389  return false;
390  }
391 
392  return true;
393 }
394 
395 //---------------------------------------------------------------------------
396 //-------- Device Function Commands -----------------------------------------
397 //---------------------------------------------------------------------------
398 
399 static bool returnDeviceResponseResult(DS28E18_result_byte_T r) {
400  switch (r) {
401  case SUCCESS:
402  break;
403  case INVALID_PARAMETER:
404  PRINTF("Error: Invalid input or parameter\n");
405  return false;
406  default:
407  PRINTF("Error: 1-Wire Communication Error\n");
408  return false;
409  }
410  return true;
411 }
412 
413 /// Device Function Command: Write Sequencer (11h) - Write command sequence into DS28E28 sequencer memory over 1Wire
414 ///
415 /// @param nineBitStartingAddress Target write address
416 /// @param txData Array of data to be written into the sequencer memory starting from the target write address
417 /// @param txDataSize Number of elements found in txData array
418 /// @return
419 /// true - command successful @n
420 /// false - command failed
421 ///
422 /// @note Use Sequencer Commands functions to help build txData array.
423 bool DS28E18_WriteSequencer(unsigned short nineBitStartingAddress, const uint8_t *txData, int txDataSize)
424 {
425  uint8_t parameters[2 + txDataSize];
426  uint8_t response[1];
427  uint8_t addressLow = nineBitStartingAddress & 0xFF;
428  uint8_t addressHigh = (nineBitStartingAddress >> 8) & 0x01;
429  parameters[0] = addressLow;
430  parameters[1] = addressHigh;
431  memcpy(&parameters[2], &txData[0], txDataSize);
432 
433  if (!run_command(WRITE_SEQUENCER, parameters, sizeof(parameters), SPU_Delay_tOP_msec, response))
434  {
435  return false;
436  }
437  return returnDeviceResponseResult(response[0]);
438 }
439 
440 //---------------------------------------------------------------------------
441 /// Device Function Command: Read Sequencer (22h)
442 ///
443 /// @param nineBitStartingAddress Target read address
444 /// @param readLength Number of data bytes to be read from the sequencer memory starting from the target read address
445 /// @param[out] rxData Array of data returned from specified memory address
446 /// @return
447 /// true - command successful @n
448 /// false - command failed
449 bool DS28E18_ReadSequencer(unsigned short nineBitStartingAddress, uint8_t *rxData, unsigned short readLength)
450 {
451  uint8_t parameters[2];
452  int response_length = 1 + readLength;
453  uint8_t response[response_length];
454  uint8_t addressLow;
455  uint8_t addressHigh;
456 
457  if (readLength == 128)
458  {
459  readLength = 0;
460  }
461 
462  addressLow = nineBitStartingAddress & 0xFF;
463  addressHigh = (nineBitStartingAddress >> 8) & 0x01;
464 
465  parameters[0] = addressLow;
466  parameters[1] = (readLength << 1) | addressHigh;
467 
468  if (!run_command(READ_SEQUENCER, parameters, sizeof(parameters), SPU_Delay_tOP_msec, response))
469  {
470  return false;
471  }
472 
473  memcpy(rxData, &response[1], response_length - 1);
474 
475  // Parse result byte.
476  switch (response[0]) {
477  case SUCCESS:
478  // Success response.
479  break;
480 
481  case INVALID_PARAMETER:
482  PRINTF("Error: Invalid input or parameter\n");
483  return false;
484 
485  default:
486  PRINTF("Error: 1-Wire Communication Error\n");
487  return false;
488  }
489 
490  return true;
491 }
492 
493 //---------------------------------------------------------------------------
494 /// Device Function Command: Run Sequencer (33h) - Command DS28E18 over 1wire to run a command sequence already placed in DS28E18 sequence memory
495 ///
496 /// @param nineBitStartingAddress Target run address
497 /// @param runLength Number of data bytes to run from the sequencer memory starting from the target run address
498 /// @return
499 /// true - command successful @n
500 /// false - command failed
501 bool DS28E18_RunSequencer(unsigned short nineBitStartingAddress, unsigned short runLength)
502 {
503  uint8_t parameters[3];
504  int response_length = 3;
505  uint8_t response[response_length];
506  uint8_t addressLow;
507  uint8_t addressHigh;
508  uint8_t sequencerLengthLow;
509  uint8_t sequencerLengthHigh;
510  int totalSequencerCommunicationTime = 0;
511  int snackLo;
512  int snackHi;
513  unsigned short nackOffset;
514 
515  if (runLength == 512)
516  {
517  runLength = 0;
518  }
519 
520  addressLow = nineBitStartingAddress & 0xFF;
521  addressHigh = (nineBitStartingAddress >> 8) & 0x01;
522  sequencerLengthLow = ((runLength & 0x7F) << 1);
523  sequencerLengthHigh = ((runLength >> 7) & 0x03);
524 
525  parameters[0] = addressLow;
526  parameters[1] = sequencerLengthLow | addressHigh;
527  parameters[2] = sequencerLengthHigh;
528 
529  #if 0 // Replace stunningly INSANE looping and floating-point coding
530  for (float i = 0; i < (runLength / 10); i++) //add 1ms to Run Sequencer delay for every 10 sequencer commands
531  {
532  totalSequencerCommunicationTime += 1;
533  }
534  localPacket.totalSequencerDelayTime += localPacket.totalSequencerDelayTime * 0.05; // Add ~5% to delay option time for assurance
535  #else
536  totalSequencerCommunicationTime += (runLength / 10); // add 1ms to Run Sequencer delay for every 10 sequencer commands
537  localPacket.totalSequencerDelayTime += localPacket.totalSequencerDelayTime / 20; // Add ~5% to delay option time for assurance
538  #endif
539 
540  int run_sequencer_delay_msec = SPU_Delay_tOP_msec + localPacket.totalSequencerDelayTime + totalSequencerCommunicationTime;
541 
542  if (!run_command(RUN_SEQUENCER, parameters, sizeof(parameters), run_sequencer_delay_msec, response))
543  {
544  return false;
545  }
546 
547  // Parse result byte.
548  switch (response[0]) {
549 
550  case POR_OCCURRED:
551  PRINTF("Error: POR occurred resulting in the command sequencer memory being set to zero\n");
552  return false;
553 
554  case EXECUTION_ERROR:
555  PRINTF("Error: Execution Error (Sequencer Command packet or packets incorrectly formed)\n");
556  return false;
557 
558  case NACK_OCCURED:
559  snackLo = response[1];
560  snackHi = response[2];
561  nackOffset = snackLo + (snackHi << 8);
562  if (nackOffset == 0)
563  {
564  nackOffset = 512;
565  }
566  PRINTF("Error: RunSequencer NACK occurred at sequencer byte index: %d\n", nackOffset);
567  return false;
568 
569  default:
570  break;
571  }
572 
573  return returnDeviceResponseResult(response[0]);
574 }
575 
576 //---------------------------------------------------------------------------
577 /// Device Function Command: Write Configuration (55h)
578 ///
579 /// @param SPD Desired protocol speed from macros
580 /// @param INACK Desired INACK configuration from macros
581 /// @param PROT Desired protocol from macros
582 /// @param SPI_MODE Desired SPI Mode from macros
583 /// @return
584 /// true - command successful @n
585 /// false - command failed
586 bool DS28E18_WriteConfiguration(DS28E18_protocol_speed_T SPD, DS28E18_ignore_nack_T INACK, DS28E18_protocol_T PROT, DS28E18_spi_mode_T SPI_MODE)
587 {
588  uint8_t parameters[1];
589  uint8_t response[1];
590 
591  parameters[0] = (SPI_MODE << 4) | (PROT << 3) | (INACK << 2) | SPD;
592 
593  if (!run_command(WRITE_CONFIGURATION, parameters, sizeof(parameters), SPU_Delay_tOP_msec, response))
594  {
595  return false;
596  }
597 
598  return returnDeviceResponseResult(response[0]);
599 }
600 
601 //---------------------------------------------------------------------------
602 /// Device Function Command: Read Configuration (6Ah)
603 ///
604 /// @param[out] rxData Array of 2 bytes to be updated with devices' configuration information
605 /// @return
606 /// true - command successful @n
607 /// false - command failed
608 bool DS28E18_ReadConfiguration(uint8_t *rxData)
609 {
610  uint8_t parameters[0]; //no parameters
611  int response_length = 2;
612  uint8_t response[response_length];
613 
614  if (!run_command(READ_CONFIGURATION, parameters, 0, SPU_Delay_tOP_msec, response))
615  {
616  return false;
617  }
618 
619  memcpy(rxData, &response[1], response_length - 1);
620 
621  return returnDeviceResponseResult(response[0]);
622 }
623 
624 //---------------------------------------------------------------------------
625 /// Device Function Command: Write GPIO Configuration (83h)
626 ///
627 /// @param CFG_REG_TARGET Desired GPIO Configuration Register to write to
628 /// @param GPIO_HI Control/Buffer register high byte
629 /// @param GPIO_LO Control/Buffer register low byte
630 /// @return
631 /// true - command successful @n
632 /// false - command failed
633 ///
634 /// @note Use GPIO Configuration functions to help build GPIO_HI/GPIO_LO parameter.
635 bool DS28E18_WriteGpioConfiguration(DS28E18_target_configuration_register_T CFG_REG_TARGET, uint8_t GPIO_HI, uint8_t GPIO_LO)
636 {
637  uint8_t parameters[4];
638  uint8_t response[1];
639 
640  parameters[0] = CFG_REG_TARGET; // 0Bh: GPIO control register, 0Ch: GPIO buffer register
641  parameters[1] = 0x03;
642  parameters[2] = GPIO_HI;
643  parameters[3] = GPIO_LO;
644 
645  if (!run_command(WRITE_GPIO_CONFIGURATION, parameters, sizeof(parameters), SPU_Delay_tOP_msec, response))
646  {
647  return false;
648  }
649  return returnDeviceResponseResult(response[0]);
650 }
651 
652 //---------------------------------------------------------------------------
653 /// Device Function Command: Read GPIO Configuration (7Ch)
654 ///
655 /// @param CFG_REG_TARGET Desired GPIO Configuration Register from macros to read from
656 /// @param[out] rxData Array of 2 bytes to be updated with device current GPIO configuration for GPIO_HI and GPIO_LO
657 /// @return
658 /// true - command successful @n
659 /// false - command failed
660 bool DS28E18_ReadGpioConfiguration(uint8_t CFG_REG_TARGET, uint8_t *rxData)
661 {
662  uint8_t parameters[2];
663  const int response_length = 3;
664  uint8_t response[response_length];
665 
666  parameters[0] = CFG_REG_TARGET;
667  parameters[1] = 0x03;
668 
669  if (!run_command(READ_GPIO_CONFIGURATION, parameters, sizeof(parameters), SPU_Delay_tOP_msec, response))
670  {
671  return false;
672  }
673 
674  memcpy(rxData, &response[1], response_length - 1);
675  return returnDeviceResponseResult(response[0]);
676 }
677 
678 //---------------------------------------------------------------------------
679 /// Device Function Command: Device Status (7Ah)
680 ///
681 /// @param[out] rxData Array of 4 bytes to receive DS28E18's status information
682 /// @return
683 /// true - command successful @n
684 /// false - command failed
685 bool DS28E18_DeviceStatus(uint8_t *rxData)
686 {
687  uint8_t parameters[0]; //no parameters
688  const int response_length = 5;
689  uint8_t response[response_length];
690 
691  if (!run_command(DEVICE_STATUS, parameters, 0, SPU_Delay_tOP_msec, response))
692  {
693  return false;
694  }
695 
696  memcpy(rxData, &response[1], response_length - 1);
697  return returnDeviceResponseResult(response[0]);
698 }
699 
700 
701 //---------------------------------------------------------------------------
702 //------ Utilities to build and use a packet of Sequencer Commands --------
703 //---------------------------------------------------------------------------
704 
705 /// Reset local command sequencer packet under construction
707 {
708  memset(localPacket.sequenceData, 0x00, sizeof(localPacket.sequenceData));
709  localPacket.sequenceIdx = 0;
710  localPacket.totalSequencerDelayTime = 0;
711 }
712 /// Get address of locally constructed command sequencer packet's data
714 {
715  return localPacket.sequenceData;
716 }
717 /// Get length of locally constructed command sequencer packet
719 {
720  return localPacket.sequenceIdx;
721 }
722 /// Append commands to locally constructed command sequencer packet
723 void DS28E18_BuildPacket_Append(const uint8_t* sequencerCmds, size_t length)
724 {
725  appendToSequencerPacket(sequencerCmds,length);
726 }
727 /// Write locally constructed command sequencer packet into DS28E18's
728 /// sequence memory over 1wire, run it, and wait long enough for completion.
729 /// Does NOT fetch any response; use DS28E18_ReadSequencer for that.
731 {
732  //printf("\n\n-- Load packet sequence into DS28E18's sequence memory --");
733  bool success = DS28E18_WriteSequencer(0x000, localPacket.sequenceData, localPacket.sequenceIdx);
734  //printf("\n\n-- Run packet sequence --");
735  if(success) success = DS28E18_RunSequencer(0x000, localPacket.sequenceIdx);
736  return success;
737 }
738 
739 /// Retrieve length of constructed sequence, for use in DS28E18_RerunLastSequence(length)
741  { return localPacket.sequenceIdx; }; // DRN addition
742 /// Run last locally constructed and loaded command sequencer packet in DS28E18's
743 /// sequence memory and wait long enough for completion. Presumes start at 0x000. DRN addition.
744 /// Does NOT fetch any response; use DS28E18_ReadSequencer for that.
745 bool DS28E18_RerunLastSequence(unsigned int length) {
746  // As above, but skip: bool success = DS28E18_WriteSequencer(0x000, localPacket.sequenceData, localPacket.sequenceIdx);
747  //printf("\n\n-- Run packet sequence --");
748  bool success = DS28E18_RunSequencer(0x000, length);
749  return success;
750 }
751 
752 /// Sequencer Command: Start (02h).
753 ///
754 /// Append an I2C Start command to the locally constructed command sequencer packet.
756 {
757  static const uint8_t i2c_start[1] = { I2C_START };
758  APPEND_TO_PACKET(i2c_start);
759 }
760 
761 //---------------------------------------------------------------------------
762 /// Sequencer Command: Stop (03h).
763 ///
764 /// Append an I2C Stop command to the locally constructed command sequencer packet.
766 {
767  static const uint8_t i2c_stop[1] = { I2C_STOP };
768  APPEND_TO_PACKET(i2c_stop);
769 }
770 
771 //---------------------------------------------------------------------------
772 /// Sequencer Command: Write Data (E3h).
773 ///
774 /// Append an I2C Write Data command to the locally constructed command sequencer packet.
775 ///
776 /// @param i2cData Array with data to be transmitted over the I2C bus
777 /// @param i2cDataSize Number of elements found in i2cData array
778 void DS28E18_BuildPacket_I2C_WriteData(const uint8_t *i2cData, uint8_t i2cDataSize)
779 {
780  uint8_t i2c_write_data[2 + i2cDataSize];
781  i2c_write_data[0] = I2C_WRITE_DATA;
782  i2c_write_data[1] = i2cDataSize;
783  memcpy(&i2c_write_data[2], i2cData, i2cDataSize);
784  APPEND_TO_PACKET(i2c_write_data);
785 }
786 
787 //---------------------------------------------------------------------------
788 /// Sequencer Command: Read Data (D4h).
789 ///
790 /// Append an I2C Read Data command to the locally constructed command sequencer packet.
791 ///
792 /// @param readBytes Number of bytes to read from the I2C bus
793 /// @return
794 /// readArrayFFhStartingAddress - Address where I2C slave response will reside
795 unsigned short DS28E18_BuildPacket_I2C_ReadData(int readBytes)
796 {
797  unsigned short readArrayFFhStartingAddress = localPacket.sequenceIdx + 2;
798  uint8_t i2c_read_data[2 + readBytes];
799 
800  i2c_read_data[0] = I2C_READ_DATA;
801  if (readBytes == 256)
802  {
803  i2c_read_data[1] = 0;
804  }
805  else
806  {
807  i2c_read_data[1] = readBytes;
808  }
809  memset(&i2c_read_data[2], 0xFF, readBytes); // Note: This set read bytes to 0xFF in sequencer memory prior to actual read
810  APPEND_TO_PACKET(i2c_read_data);
811  return readArrayFFhStartingAddress;
812 }
813 
814 //---------------------------------------------------------------------------
815 /// Sequencer Command: Read Data w/NACK end (D3h).
816 ///
817 /// Append an I2C Read Data w/NACK end command to the locally constructed command sequencer packet.
818 ///
819 /// @param readBytes Number of bytes to read from the I2C bus
820 /// @return
821 /// readArrayFFhStartingAddress - Address where I2C slave response will reside
822 unsigned short DS28E18_BuildPacket_I2C_ReadDataWithNackEnd(int readBytes)
823 {
824  unsigned short readArrayFFhStartingAddress = localPacket.sequenceIdx + 2;
825  uint8_t i2c_read_data_with_nack_end[2 + readBytes];
826  i2c_read_data_with_nack_end[0] = I2C_READ_DATA_W_NACK_END;
827  if (readBytes == 256)
828  {
829  i2c_read_data_with_nack_end[1] = 0;
830  }
831  else
832  {
833  i2c_read_data_with_nack_end[1] = readBytes;
834  }
835  memset(&i2c_read_data_with_nack_end[2], 0xFF, readBytes); // Note: This set read bytes to 0xFF in sequencer memory prior to actual read
836  APPEND_TO_PACKET(i2c_read_data_with_nack_end);
837  return readArrayFFhStartingAddress;
838 }
839 
840 //---------------------------------------------------------------------------
841 /// Sequencer Command: SPI Write/Read Byte (C0h).
842 ///
843 /// Append an SPI Write/Read Byte command to the locally constructed command sequencer packet.
844 ///
845 /// @param spiWriteData Array with data to be transmitted over the SPI bus. Data not important if only reading.
846 /// @param spiWriteDataSize Number of elements found in spiWriteData array. Set to 0 if only reading.
847 /// @param readBytes Number of bytes to read from SPI bus. Set to 0 if only writting.
848 /// @param fullDuplex Set 'true' when interfacing with a full duplex SPI slave. Otherwise, set 'false'
849 /// @return
850 /// readArrayFFhStartingAddress - If reading, address where SPI slave response will reside.
851 unsigned short DS28E18_BuildPacket_SPI_WriteReadByte(const uint8_t *spiWriteData, uint8_t spiWriteDataSize, int readBytes, bool fullDuplex)
852 {
853  unsigned short readArrayFFhStartingAddress = 0;
854  uint8_t spi_write_read_data_byte[255];
855  int idx = 0;
856 
857  //command
858  spi_write_read_data_byte[idx++] = SPI_WRITE_READ_BYTE;
859 
860  if (spiWriteDataSize != 0 && readBytes != 0)
861  {
862  //Write Length
863  spi_write_read_data_byte[idx++] = spiWriteDataSize;
864 
865  //Read Length
866  spi_write_read_data_byte[idx] = readBytes;
867  if (!fullDuplex)
868  {
869  spi_write_read_data_byte[idx] += spiWriteDataSize;
870  }
871  idx++;
872 
873  //Write Array
874  for (int i = 0; i < spiWriteDataSize; i++)
875  {
876  spi_write_read_data_byte[idx++] = spiWriteData[i];
877  }
878 
879  //Read Array
880  if (!fullDuplex)
881  {
882  memset(&spi_write_read_data_byte[idx], 0xFF, spiWriteDataSize);
883  idx += spiWriteDataSize;
884  }
885  readArrayFFhStartingAddress = idx;
886  memset(&spi_write_read_data_byte[idx], 0xFF, readBytes);
887  idx += readBytes;
888  }
889 
890  else if(spiWriteDataSize != 0 && readBytes == 0)
891  {
892  //Write Length
893  spi_write_read_data_byte[idx++] = spiWriteDataSize;
894 
895  //Read Length
896  spi_write_read_data_byte[idx++] = 0;
897 
898  //Write Array
899  for (int i = 0; i < spiWriteDataSize; i++)
900  {
901  spi_write_read_data_byte[idx++] = spiWriteData[i];
902  }
903 
904  //Read Array
905  //omitted
906  }
907 
908  else if(spiWriteDataSize == 0 && readBytes != 0)
909  {
910  //Write Length
911  spi_write_read_data_byte[idx++] = 0;
912 
913  //Read Length
914  spi_write_read_data_byte[idx++] = readBytes;
915 
916  //Write Array
917  //omitted
918 
919  //Read Array
920  readArrayFFhStartingAddress = idx;
921  memset(&spi_write_read_data_byte[idx], 0xFF, readBytes);
922  idx += readBytes;
923  }
924 
925  else
926  {
927  //Write Length
928  spi_write_read_data_byte[idx++] = 0;
929 
930  //Read Length
931  spi_write_read_data_byte[idx++] = 0;
932 
933  //Write Array
934  //omitted
935 
936  //Read Array
937  //omitted
938  }
939  readArrayFFhStartingAddress += localPacket.sequenceIdx;
940  appendToSequencerPacket(spi_write_read_data_byte, idx);
941  return readArrayFFhStartingAddress;
942 }
943 
944 //---------------------------------------------------------------------------
945 /// Sequencer Command: SPI Write/Read Bit (B0h).
946 ///
947 /// Append an SPI Write/Read Bit command to the locally constructed command sequencer packet.
948 ///
949 /// @param spiWriteData Array with data to be transmitted over the SPI bus. Data not important if only reading.
950 /// @param spiWriteDataSize Number of elements found in spiWriteData array. Set to 0 if only reading.
951 /// @param writeBits Number of bits to write to SPI bus. Set to 0 if only reading.
952 /// @param readBits Number of bits to read from SPI bus. Set to 0 if only writting.
953 /// @return
954 /// readArrayFFhStartingAddress - If reading, address where SPI slave response will reside.
955 unsigned short DS28E18_BuildPacket_SPI_WriteReadBit(const uint8_t *spiWriteData, uint8_t spiWriteDataSize, int writeBits, int readBits)
956 {
957  uint8_t readBitsInBytes = 0;
958  unsigned short readArrayFFhStartingAddress = 0;
959  uint8_t spi_write_read_data_bit[255];
960  int idx = 0;
961 
962  if (readBits > 0 && readBits < 9)
963  {
964  readBitsInBytes = 1;
965  }
966  else if (readBits >= 9 && readBits < 17)
967  {
968  readBitsInBytes = 2;
969  }
970  else if (readBits >= 17 && readBits < 25)
971  {
972  readBitsInBytes = 3;
973  }
974  else if (readBits >= 25 && readBits < 33)
975  {
976  readBitsInBytes = 4;
977  }
978  else if (readBits >= 33 && readBits < 41)
979  {
980  readBitsInBytes = 5;
981  }
982  else if (readBits >= 41 && readBits < 49)
983  {
984  readBitsInBytes = 6;
985  }
986  else if (readBits >= 49 && readBits < 57)
987  {
988  readBitsInBytes = 7;
989  }
990  else if (readBits >= 57 && readBits < 65)
991  {
992  readBitsInBytes = 8;
993  }
994 
995  //command
996  spi_write_read_data_bit[idx++] = SPI_WRITE_READ_BIT;
997 
998  if (writeBits != 0 && readBits != 0)
999  {
1000  //Write Length
1001  spi_write_read_data_bit[idx++] = writeBits;
1002 
1003  //Read Length
1004  spi_write_read_data_bit[idx++] = readBits;
1005 
1006  //Write Array
1007  for (int i = 0; i < spiWriteDataSize; i++)
1008  {
1009  spi_write_read_data_bit[idx++] = spiWriteData[i];
1010  }
1011 
1012  //Read Array
1013  readArrayFFhStartingAddress = idx;
1014  memset(&spi_write_read_data_bit[idx], 0xFF, readBitsInBytes);
1015  idx += readBitsInBytes;
1016  }
1017 
1018  else if(writeBits != 0 && readBits == 0)
1019  {
1020  //Write Length
1021  spi_write_read_data_bit[idx++] = writeBits;
1022 
1023  //Read Length
1024  spi_write_read_data_bit[idx++] = 0;
1025 
1026  //Write Array
1027  for (int i = 0; i < spiWriteDataSize; i++)
1028  {
1029  spi_write_read_data_bit[idx++] = spiWriteData[i];
1030  }
1031 
1032  //Read Array
1033  //omitted
1034  }
1035 
1036  else if(writeBits == 0 && readBits != 0)
1037  {
1038  //Write Length
1039  spi_write_read_data_bit[idx++] = 0;
1040 
1041  //Read Length
1042  spi_write_read_data_bit[idx++] = readBits;
1043 
1044  //Write Array
1045  //omitted
1046 
1047  //Read Array
1048  readArrayFFhStartingAddress = idx;
1049  memset(&spi_write_read_data_bit[idx], 0xFF, readBitsInBytes);
1050  idx += readBitsInBytes;
1051  }
1052 
1053  else
1054  {
1055  //Write Length
1056  spi_write_read_data_bit[idx++] = 0;
1057 
1058  //Read Length
1059  spi_write_read_data_bit[idx++] = 0;
1060 
1061  //Write Array
1062  //omitted
1063 
1064  //Read Array
1065  //omitted
1066  }
1067 
1068  readArrayFFhStartingAddress += localPacket.sequenceIdx;
1069  appendToSequencerPacket(spi_write_read_data_bit,idx);
1070 
1071  return readArrayFFhStartingAddress;
1072 }
1073 
1074 //---------------------------------------------------------------------------
1075 /// Sequencer Command: SPI SS_High (01h).
1076 ///
1077 /// Append an SPI SS_High command to the locally constructed command sequencer packet.
1079 {
1080  static const uint8_t spi_slave_select_high[1] = { SPI_SS_HIGH };
1081  APPEND_TO_PACKET(spi_slave_select_high);
1082 }
1083 
1084 //---------------------------------------------------------------------------
1085 /// Sequencer Command: SPI SS_Low (80h).
1086 ///
1087 /// Append an SPI SS_Low command to the locally constructed command sequencer packet.
1089 {
1090  static const uint8_t spi_slave_select_low[1] = { SPI_SS_LOW };
1091  APPEND_TO_PACKET(spi_slave_select_low);
1092 }
1093 
1094 //---------------------------------------------------------------------------
1095 /// Sequencer Command: Delay (DDh).
1096 ///
1097 /// Append a Delay command to the locally constructed command sequencer packet.
1099 {
1100  uint16_t delayTimeInMs = 1U << (uint16_t)delayTimeInMsExponent;
1101  localPacket.totalSequencerDelayTime += delayTimeInMs;
1102  uint8_t utility_delay_sequence[2] = { UTILITY_DELAY, delayTimeInMsExponent };
1103  APPEND_TO_PACKET(utility_delay_sequence);
1104 }
1105 
1106 //---------------------------------------------------------------------------
1107 /// Sequencer Command: SENS_VDD On (CCh).
1108 ///
1109 /// Append a 'SENS_VDD On' command to the locally constructed command sequencer packet.
1111 {
1112  static const uint8_t utility_sens_vdd_on[1] = { UTILITY_SENS_VDD_ON };
1113  APPEND_TO_PACKET(utility_sens_vdd_on);
1114 }
1115 
1116 //---------------------------------------------------------------------------
1117 /// Sequencer Command: SENS_VDD Off (BBh).
1118 ///
1119 /// Append a 'SENS_VDD Off' command to the locally constructed command sequencer packet.
1121 {
1122  static const uint8_t utility_sens_vdd_off[1] = { UTILITY_SENS_VDD_OFF };
1123  APPEND_TO_PACKET(utility_sens_vdd_off);
1124 }
1125 
1126 //---------------------------------------------------------------------------
1127 /// Sequencer Command: GPIO_BUF Write (D1h).
1128 ///
1129 /// Append a GPIO_BUF Write command to the locally constructed command sequencer packet.
1130 ///
1131 /// @param GPIO_BUF Buffer register high byte.
1133 {
1134  uint8_t utility_gpio_buff_write[2] = { UTILITY_GPIO_BUF_WRITE, GPIO_BUF };
1135  APPEND_TO_PACKET(utility_gpio_buff_write);
1136 }
1137 
1138 //---------------------------------------------------------------------------
1139 /// Sequencer Command: GPIO_BUF Read (1Dh).
1140 ///
1141 /// Append a GPIO_BUF Read command to the locally constructed command sequencer packet.
1142 ///
1143 /// @return readArrayFFhStartingAddress - Starting address where configuration data will reside.
1145 {
1146  unsigned short readArrayFFhStartingAddress = localPacket.sequenceIdx + 1;
1147  static const uint8_t utility_gpio_buff_read[2] = { UTILITY_GPIO_BUF_READ, 0xFF };
1148  APPEND_TO_PACKET(utility_gpio_buff_read);
1149  return readArrayFFhStartingAddress;
1150 }
1151 
1152 //---------------------------------------------------------------------------
1153 /// Sequencer Command: GPIO_CNTL Write (E2h).
1154 ///
1155 /// Append a GPIO_CNTL Write command to the locally constructed command sequencer packet.
1156 ///
1157 /// @param GPIO_CRTL_HI Control register high byte.
1158 /// @param GPIO_CRTL_LO Control register low byte.
1159 void DS28E18_BuildPacket_Utility_GpioControlWrite(uint8_t GPIO_CRTL_HI, uint8_t GPIO_CRTL_LO)
1160 {
1161  uint8_t utility_gpio_cntl_write[3] = { UTILITY_GPIO_CNTL_WRITE, GPIO_CRTL_HI, GPIO_CRTL_LO };
1162  APPEND_TO_PACKET(utility_gpio_cntl_write);
1163 }
1164 
1165 //---------------------------------------------------------------------------
1166 /// Sequencer Command: GPIO_CNTL Read (2Eh).
1167 ///
1168 /// Append a GPIO_CNTL Read command to the locally constructed command sequencer packet.
1169 ///
1170 /// @return readArrayFFhStartingAddress - Starting address where configuration data will reside.
1172 {
1173  unsigned short readArrayFFhStartingAddress = localPacket.sequenceIdx + 1;
1174  static const uint8_t utility_gpio_cntl_read[3] = { UTILITY_GPIO_CNTL_READ, 0xFF, 0xFF };
1175  APPEND_TO_PACKET(utility_gpio_cntl_read);
1176  return readArrayFFhStartingAddress;
1177 }
void DS28E18_BuildPacket_Utility_GpioBufferWrite(uint8_t GPIO_BUF)
Definition: DS28E18.c:1132
bool DS28E18_WriteGpioConfiguration(DS28E18_target_configuration_register_T CFG_REG_TARGET, uint8_t GPIO_HI, uint8_t GPIO_LO)
Definition: DS28E18.c:635
DS28E18_utility_delay_T
Definition: DS28E18.h:146
void DS28E18_BuildPacket_Append(const uint8_t *sequencerCmds, size_t length)
Append commands to locally constructed command sequencer packet.
Definition: DS28E18.c:723
bool DS28E18_DeviceStatus(uint8_t *rxData)
Definition: DS28E18.c:685
int DS28E18_BuildPacket_GetSequencerPacketSize()
Get length of locally constructed command sequencer packet.
Definition: DS28E18.c:718
unsigned short DS28E18_BuildPacket_SPI_WriteReadBit(const uint8_t *spiWriteData, uint8_t spiWriteDataSize, int writeBits, int readBits)
Definition: DS28E18.c:955
uint8_t * DS28E18_BuildPacket_GetSequencerPacket()
Get address of locally constructed command sequencer packet&#39;s data.
Definition: DS28E18.c:713
OneWire_ROM_ID_T current_DS28E18_ROM_ID
DS28E18 device addressed for current operations (may be one of many on 1-Wire bus) ...
Definition: DS28E18.c:84
void DS28E18_BuildPacket_ClearSequencerPacket()
Reset local command sequencer packet under construction.
Definition: DS28E18.c:706
can only be used if there is a single slave on the bus
Definition: DS28E18.h:75
void DS28E18_BuildPacket_SPI_SlaveSelectLow()
Definition: DS28E18.c:1088
void DS28E18_BuildPacket_Utility_Delay(DS28E18_utility_delay_T delayTimeInMsExponent)
Definition: DS28E18.c:1098
unsigned short DS28E18_BuildPacket_Utility_GpioBufferRead()
Definition: DS28E18.c:1144
unsigned short DS28E18_BuildPacket_SPI_WriteReadByte(const uint8_t *spiWriteData, uint8_t spiWriteDataSize, int readBytes, bool fullDuplex)
Definition: DS28E18.c:851
bool DS28E18_BuildPacket_WriteAndRun()
Definition: DS28E18.c:730
OneWire_ROM_ID_T type stores a 1-Wire address.
int OneWire_Search(OneWire_ROM_ID_T *romid, bool search_reset, bool *last_device_found)
Definition: one_wire.c:191
void DS28E18_BuildPacket_I2C_WriteData(const uint8_t *i2cData, uint8_t i2cDataSize)
Definition: DS28E18.c:778
unsigned short DS28E18_BuildPacket_I2C_ReadDataWithNackEnd(int readBytes)
Definition: DS28E18.c:822
void DS28E18_BuildPacket_SPI_SlaveSelectHigh()
Definition: DS28E18.c:1078
void DS28E18_BuildPacket_Utility_SensVddOn()
Definition: DS28E18.c:1110
Driver for a DS28E18 slave on a 1-Wire bus.
bool DS28E18_ReadGpioConfiguration(uint8_t CFG_REG_TARGET, uint8_t *rxData)
Definition: DS28E18.c:660
unsigned short DS28E18_GetLastSequenceLength()
Retrieve length of constructed sequence, for use in DS28E18_RerunLastSequence(length) ...
Definition: DS28E18.c:740
void DS28E18_BuildPacket_Utility_GpioControlWrite(uint8_t GPIO_CRTL_HI, uint8_t GPIO_CRTL_LO)
Definition: DS28E18.c:1159
selected (matched ROM ID) slave goes into overdrive
Definition: DS28E18.h:81
void DS28E18_BuildPacket_Utility_SensVddOff()
Definition: DS28E18.c:1120
DS28E18_one_wire_rom_commands_T DS28E18_GetRomCommand()
Return the value of &#39;current_ROM_command&#39;.
Definition: DS28E18.c:238
bool DS28E18_WriteConfiguration(DS28E18_protocol_speed_T SPD, DS28E18_ignore_nack_T INACK, DS28E18_protocol_T PROT, DS28E18_spi_mode_T SPI_MODE)
Definition: DS28E18.c:586
void DS28E18_SetRomCommand(DS28E18_one_wire_rom_commands_T rom_cmd)
Definition: DS28E18.c:232
don&#39;t use ROM ID (applicable only when there is only 1 slave on the bus)
Definition: DS28E18.h:78
unsigned short DS28E18_BuildPacket_Utility_GpioControlRead()
Definition: DS28E18.c:1171
bool DS28E18_WriteSequencer(unsigned short nineBitStartingAddress, const uint8_t *txData, int txDataSize)
Definition: DS28E18.c:423
int DS28E18_SetOnewireSpeed(one_wire_speeds spd)
Definition: DS28E18.c:197
int DS28E18_Init()
Definition: DS28E18.c:122
DS28E18_one_wire_rom_commands_T
Definition: DS28E18.h:74
unsigned short DS28E18_BuildPacket_I2C_ReadData(int readBytes)
Definition: DS28E18.c:795
void DS28E18_BuildPacket_I2C_Start()
Definition: DS28E18.c:755
enumeration of all slaves on bus
Definition: DS28E18.h:77
void DS28E18_BuildPacket_I2C_Stop()
Definition: DS28E18.c:765
bool DS28E18_ReadSequencer(unsigned short nineBitStartingAddress, uint8_t *rxData, unsigned short readLength)
Definition: DS28E18.c:449
bool DS28E18_RunSequencer(unsigned short nineBitStartingAddress, unsigned short runLength)
Definition: DS28E18.c:501
bool DS28E18_RerunLastSequence(unsigned int length)
Definition: DS28E18.c:745
address a specific slave by ROM ID
Definition: DS28E18.h:76
bool DS28E18_ReadConfiguration(uint8_t *rxData)
Definition: DS28E18.c:608