1-Wire and ENS210 driver stack
Macros | Functions | Variables
DS28E18.c File Reference

Driver for a DS28E18 slave on a 1-Wire bus. More...

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
#include "DS28E18.h"
#include "FreeRTOS.h"
#include "task.h"
Include dependency graph for DS28E18.c:

Go to the source code of this file.

Macros

#define DELAY_MSEC(msec_)   vTaskDelay(pdMS_TO_TICKS(msec_))
 
#define PRINTF(...)   {}
 
#define APPEND_TO_PACKET(s_)   { appendToSequencerPacket(s_, sizeof(s_)); }
 
#define SPU_Delay_tOP_msec   1
 

Functions

int DS28E18_Init ()
 
int DS28E18_SetOnewireSpeed (one_wire_speeds spd)
 
void DS28E18_SetRomCommand (DS28E18_one_wire_rom_commands_T rom_cmd)
 
DS28E18_one_wire_rom_commands_T DS28E18_GetRomCommand ()
 Return the value of 'current_ROM_command'.
 
bool DS28E18_WriteSequencer (unsigned short nineBitStartingAddress, const uint8_t *txData, int txDataSize)
 
bool DS28E18_ReadSequencer (unsigned short nineBitStartingAddress, uint8_t *rxData, unsigned short readLength)
 
bool DS28E18_RunSequencer (unsigned short nineBitStartingAddress, unsigned short runLength)
 
bool DS28E18_WriteConfiguration (DS28E18_protocol_speed_T SPD, DS28E18_ignore_nack_T INACK, DS28E18_protocol_T PROT, DS28E18_spi_mode_T SPI_MODE)
 
bool DS28E18_ReadConfiguration (uint8_t *rxData)
 
bool DS28E18_WriteGpioConfiguration (DS28E18_target_configuration_register_T CFG_REG_TARGET, uint8_t GPIO_HI, uint8_t GPIO_LO)
 
bool DS28E18_ReadGpioConfiguration (uint8_t CFG_REG_TARGET, uint8_t *rxData)
 
bool DS28E18_DeviceStatus (uint8_t *rxData)
 
void DS28E18_BuildPacket_ClearSequencerPacket ()
 Reset local command sequencer packet under construction.
 
uint8_t * DS28E18_BuildPacket_GetSequencerPacket ()
 Get address of locally constructed command sequencer packet's data.
 
int DS28E18_BuildPacket_GetSequencerPacketSize ()
 Get length of locally constructed command sequencer packet.
 
void DS28E18_BuildPacket_Append (const uint8_t *sequencerCmds, size_t length)
 Append commands to locally constructed command sequencer packet.
 
bool DS28E18_BuildPacket_WriteAndRun ()
 
unsigned short DS28E18_GetLastSequenceLength ()
 Retrieve length of constructed sequence, for use in DS28E18_RerunLastSequence(length)
 
bool DS28E18_RerunLastSequence (unsigned int length)
 
void DS28E18_BuildPacket_I2C_Start ()
 
void DS28E18_BuildPacket_I2C_Stop ()
 
void DS28E18_BuildPacket_I2C_WriteData (const uint8_t *i2cData, uint8_t i2cDataSize)
 
unsigned short DS28E18_BuildPacket_I2C_ReadData (int readBytes)
 
unsigned short DS28E18_BuildPacket_I2C_ReadDataWithNackEnd (int readBytes)
 
unsigned short DS28E18_BuildPacket_SPI_WriteReadByte (const uint8_t *spiWriteData, uint8_t spiWriteDataSize, int readBytes, bool fullDuplex)
 
unsigned short DS28E18_BuildPacket_SPI_WriteReadBit (const uint8_t *spiWriteData, uint8_t spiWriteDataSize, int writeBits, int readBits)
 
void DS28E18_BuildPacket_SPI_SlaveSelectHigh ()
 
void DS28E18_BuildPacket_SPI_SlaveSelectLow ()
 
void DS28E18_BuildPacket_Utility_Delay (DS28E18_utility_delay_T delayTimeInMsExponent)
 
void DS28E18_BuildPacket_Utility_SensVddOn ()
 
void DS28E18_BuildPacket_Utility_SensVddOff ()
 
void DS28E18_BuildPacket_Utility_GpioBufferWrite (uint8_t GPIO_BUF)
 
unsigned short DS28E18_BuildPacket_Utility_GpioBufferRead ()
 
void DS28E18_BuildPacket_Utility_GpioControlWrite (uint8_t GPIO_CRTL_HI, uint8_t GPIO_CRTL_LO)
 
unsigned short DS28E18_BuildPacket_Utility_GpioControlRead ()
 

Variables

OneWire_ROM_ID_T current_DS28E18_ROM_ID
 DS28E18 device addressed for current operations (may be one of many on 1-Wire bus)
 

Detailed Description

Driver for a DS28E18 slave on a 1-Wire bus.

Update history - Cleanups by Dave Nadler
  • 30-October-2023 Initial version.
  • 13-March-2026 Added many missing error checks.
Todo:

Isolate DELAY_MSEC to make porting easier.

Use OneWire_ROM_ID_T for ROM ID in DS2485 code.

Add DS28E18 status register structure definition and interpretation.

Make a DS28E18 class to support multiple DS28E18 devices more easily.

Definition in file DS28E18.c.

Function Documentation

◆ DS28E18_BuildPacket_I2C_ReadData()

unsigned short DS28E18_BuildPacket_I2C_ReadData ( int  readBytes)

Sequencer Command: Read Data (D4h).

Append an I2C Read Data command to the locally constructed command sequencer packet.

Parameters
readBytesNumber of bytes to read from the I2C bus
Returns
readArrayFFhStartingAddress - Address where I2C slave response will reside

Definition at line 795 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_I2C_ReadDataWithNackEnd()

unsigned short DS28E18_BuildPacket_I2C_ReadDataWithNackEnd ( int  readBytes)

Sequencer Command: Read Data w/NACK end (D3h).

Append an I2C Read Data w/NACK end command to the locally constructed command sequencer packet.

Parameters
readBytesNumber of bytes to read from the I2C bus
Returns
readArrayFFhStartingAddress - Address where I2C slave response will reside

Definition at line 822 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_I2C_Start()

void DS28E18_BuildPacket_I2C_Start ( void  )

Sequencer Command: Start (02h).

Append an I2C Start command to the locally constructed command sequencer packet.

Definition at line 755 of file DS28E18.c.

756 {
757  static const uint8_t i2c_start[1] = { I2C_START };
758  APPEND_TO_PACKET(i2c_start);
759 }

◆ DS28E18_BuildPacket_I2C_Stop()

void DS28E18_BuildPacket_I2C_Stop ( void  )

Sequencer Command: Stop (03h).

Append an I2C Stop command to the locally constructed command sequencer packet.

Definition at line 765 of file DS28E18.c.

766 {
767  static const uint8_t i2c_stop[1] = { I2C_STOP };
768  APPEND_TO_PACKET(i2c_stop);
769 }

◆ DS28E18_BuildPacket_I2C_WriteData()

void DS28E18_BuildPacket_I2C_WriteData ( const uint8_t *  i2cData,
uint8_t  i2cDataSize 
)

Sequencer Command: Write Data (E3h).

Append an I2C Write Data command to the locally constructed command sequencer packet.

Parameters
i2cDataArray with data to be transmitted over the I2C bus
i2cDataSizeNumber of elements found in i2cData array

Definition at line 778 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_SPI_SlaveSelectHigh()

void DS28E18_BuildPacket_SPI_SlaveSelectHigh ( void  )

Sequencer Command: SPI SS_High (01h).

Append an SPI SS_High command to the locally constructed command sequencer packet.

Definition at line 1078 of file DS28E18.c.

1079 {
1080  static const uint8_t spi_slave_select_high[1] = { SPI_SS_HIGH };
1081  APPEND_TO_PACKET(spi_slave_select_high);
1082 }

◆ DS28E18_BuildPacket_SPI_SlaveSelectLow()

void DS28E18_BuildPacket_SPI_SlaveSelectLow ( void  )

Sequencer Command: SPI SS_Low (80h).

Append an SPI SS_Low command to the locally constructed command sequencer packet.

Definition at line 1088 of file DS28E18.c.

1089 {
1090  static const uint8_t spi_slave_select_low[1] = { SPI_SS_LOW };
1091  APPEND_TO_PACKET(spi_slave_select_low);
1092 }

◆ DS28E18_BuildPacket_SPI_WriteReadBit()

unsigned short DS28E18_BuildPacket_SPI_WriteReadBit ( const uint8_t *  spiWriteData,
uint8_t  spiWriteDataSize,
int  writeBits,
int  readBits 
)

Sequencer Command: SPI Write/Read Bit (B0h).

Append an SPI Write/Read Bit command to the locally constructed command sequencer packet.

Parameters
spiWriteDataArray with data to be transmitted over the SPI bus. Data not important if only reading.
spiWriteDataSizeNumber of elements found in spiWriteData array. Set to 0 if only reading.
writeBitsNumber of bits to write to SPI bus. Set to 0 if only reading.
readBitsNumber of bits to read from SPI bus. Set to 0 if only writting.
Returns
readArrayFFhStartingAddress - If reading, address where SPI slave response will reside.

Definition at line 955 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_SPI_WriteReadByte()

unsigned short DS28E18_BuildPacket_SPI_WriteReadByte ( const uint8_t *  spiWriteData,
uint8_t  spiWriteDataSize,
int  readBytes,
bool  fullDuplex 
)

Sequencer Command: SPI Write/Read Byte (C0h).

Append an SPI Write/Read Byte command to the locally constructed command sequencer packet.

Parameters
spiWriteDataArray with data to be transmitted over the SPI bus. Data not important if only reading.
spiWriteDataSizeNumber of elements found in spiWriteData array. Set to 0 if only reading.
readBytesNumber of bytes to read from SPI bus. Set to 0 if only writting.
fullDuplexSet 'true' when interfacing with a full duplex SPI slave. Otherwise, set 'false'
Returns
readArrayFFhStartingAddress - If reading, address where SPI slave response will reside.

Definition at line 851 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_Utility_Delay()

void DS28E18_BuildPacket_Utility_Delay ( DS28E18_utility_delay_T  delayTimeInMsExponent)

Sequencer Command: Delay (DDh).

Append a Delay command to the locally constructed command sequencer packet.

Definition at line 1098 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_Utility_GpioBufferRead()

unsigned short DS28E18_BuildPacket_Utility_GpioBufferRead ( void  )

Sequencer Command: GPIO_BUF Read (1Dh).

Append a GPIO_BUF Read command to the locally constructed command sequencer packet.

Returns
readArrayFFhStartingAddress - Starting address where configuration data will reside.

Definition at line 1144 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_Utility_GpioBufferWrite()

void DS28E18_BuildPacket_Utility_GpioBufferWrite ( uint8_t  GPIO_BUF)

Sequencer Command: GPIO_BUF Write (D1h).

Append a GPIO_BUF Write command to the locally constructed command sequencer packet.

Parameters
GPIO_BUFBuffer register high byte.

Definition at line 1132 of file DS28E18.c.

1133 {
1134  uint8_t utility_gpio_buff_write[2] = { UTILITY_GPIO_BUF_WRITE, GPIO_BUF };
1135  APPEND_TO_PACKET(utility_gpio_buff_write);
1136 }

◆ DS28E18_BuildPacket_Utility_GpioControlRead()

unsigned short DS28E18_BuildPacket_Utility_GpioControlRead ( void  )

Sequencer Command: GPIO_CNTL Read (2Eh).

Append a GPIO_CNTL Read command to the locally constructed command sequencer packet.

Returns
readArrayFFhStartingAddress - Starting address where configuration data will reside.

Definition at line 1171 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_Utility_GpioControlWrite()

void DS28E18_BuildPacket_Utility_GpioControlWrite ( uint8_t  GPIO_CRTL_HI,
uint8_t  GPIO_CRTL_LO 
)

Sequencer Command: GPIO_CNTL Write (E2h).

Append a GPIO_CNTL Write command to the locally constructed command sequencer packet.

Parameters
GPIO_CRTL_HIControl register high byte.
GPIO_CRTL_LOControl register low byte.

Definition at line 1159 of file DS28E18.c.

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 }

◆ DS28E18_BuildPacket_Utility_SensVddOff()

void DS28E18_BuildPacket_Utility_SensVddOff ( void  )

Sequencer Command: SENS_VDD Off (BBh).

Append a 'SENS_VDD Off' command to the locally constructed command sequencer packet.

Definition at line 1120 of file DS28E18.c.

1121 {
1122  static const uint8_t utility_sens_vdd_off[1] = { UTILITY_SENS_VDD_OFF };
1123  APPEND_TO_PACKET(utility_sens_vdd_off);
1124 }

◆ DS28E18_BuildPacket_Utility_SensVddOn()

void DS28E18_BuildPacket_Utility_SensVddOn ( void  )

Sequencer Command: SENS_VDD On (CCh).

Append a 'SENS_VDD On' command to the locally constructed command sequencer packet.

Definition at line 1110 of file DS28E18.c.

1111 {
1112  static const uint8_t utility_sens_vdd_on[1] = { UTILITY_SENS_VDD_ON };
1113  APPEND_TO_PACKET(utility_sens_vdd_on);
1114 }

◆ DS28E18_BuildPacket_WriteAndRun()

bool DS28E18_BuildPacket_WriteAndRun ( void  )

Write locally constructed command sequencer packet into DS28E18's sequence memory over 1wire, run it, and wait long enough for completion. Does NOT fetch any response; use DS28E18_ReadSequencer for that.

Definition at line 730 of file DS28E18.c.

References DS28E18_RunSequencer(), and DS28E18_WriteSequencer().

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 }
bool DS28E18_WriteSequencer(unsigned short nineBitStartingAddress, const uint8_t *txData, int txDataSize)
Definition: DS28E18.c:423
bool DS28E18_RunSequencer(unsigned short nineBitStartingAddress, unsigned short runLength)
Definition: DS28E18.c:501

◆ DS28E18_DeviceStatus()

bool DS28E18_DeviceStatus ( uint8_t *  rxData)

Device Function Command: Device Status (7Ah)

Parameters
[out]rxDataArray of 4 bytes to receive DS28E18's status information
Returns
true - command successful
false - command failed

Definition at line 685 of file DS28E18.c.

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 }

◆ DS28E18_Init()

int DS28E18_Init ( void  )

Initialize all DS28E18 on the 1-Wire bus.

Returns
number of DS28E18 found on the bus.

Definition at line 122 of file DS28E18.c.

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 }
bool DS28E18_WriteGpioConfiguration(DS28E18_target_configuration_register_T CFG_REG_TARGET, uint8_t GPIO_HI, uint8_t GPIO_LO)
Definition: DS28E18.c:635
bool DS28E18_DeviceStatus(uint8_t *rxData)
Definition: DS28E18.c:685
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
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_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
int DS28E18_SetOnewireSpeed(one_wire_speeds spd)
Definition: DS28E18.c:197
address a specific slave by ROM ID
Definition: DS28E18.h:76

◆ DS28E18_ReadConfiguration()

bool DS28E18_ReadConfiguration ( uint8_t *  rxData)

Device Function Command: Read Configuration (6Ah)

Parameters
[out]rxDataArray of 2 bytes to be updated with devices' configuration information
Returns
true - command successful
false - command failed

Definition at line 608 of file DS28E18.c.

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 }

◆ DS28E18_ReadGpioConfiguration()

bool DS28E18_ReadGpioConfiguration ( uint8_t  CFG_REG_TARGET,
uint8_t *  rxData 
)

Device Function Command: Read GPIO Configuration (7Ch)

Parameters
CFG_REG_TARGETDesired GPIO Configuration Register from macros to read from
[out]rxDataArray of 2 bytes to be updated with device current GPIO configuration for GPIO_HI and GPIO_LO
Returns
true - command successful
false - command failed

Definition at line 660 of file DS28E18.c.

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 }

◆ DS28E18_ReadSequencer()

bool DS28E18_ReadSequencer ( unsigned short  nineBitStartingAddress,
uint8_t *  rxData,
unsigned short  readLength 
)

Device Function Command: Read Sequencer (22h)

Parameters
nineBitStartingAddressTarget read address
readLengthNumber of data bytes to be read from the sequencer memory starting from the target read address
[out]rxDataArray of data returned from specified memory address
Returns
true - command successful
false - command failed

Definition at line 449 of file DS28E18.c.

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 }

◆ DS28E18_RerunLastSequence()

bool DS28E18_RerunLastSequence ( unsigned int  length)

Run last locally constructed and loaded command sequencer packet in DS28E18's sequence memory and wait long enough for completion. Presumes start at 0x000. DRN addition. Does NOT fetch any response; use DS28E18_ReadSequencer for that.

Definition at line 745 of file DS28E18.c.

References DS28E18_RunSequencer().

745  {
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 }
bool DS28E18_RunSequencer(unsigned short nineBitStartingAddress, unsigned short runLength)
Definition: DS28E18.c:501

◆ DS28E18_RunSequencer()

bool DS28E18_RunSequencer ( unsigned short  nineBitStartingAddress,
unsigned short  runLength 
)

Device Function Command: Run Sequencer (33h) - Command DS28E18 over 1wire to run a command sequence already placed in DS28E18 sequence memory

Parameters
nineBitStartingAddressTarget run address
runLengthNumber of data bytes to run from the sequencer memory starting from the target run address
Returns
true - command successful
false - command failed

Definition at line 501 of file DS28E18.c.

Referenced by DS28E18_BuildPacket_WriteAndRun(), and DS28E18_RerunLastSequence().

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 }

◆ DS28E18_SetOnewireSpeed()

int DS28E18_SetOnewireSpeed ( one_wire_speeds  spd)

Set desired 1-Wire speed between Standard and Overdrive for both, 1-Wire master and slave.

Returns
0 - At least one device is detected after a 1-Wire reset is performed on new speed. 1 - Failure.

Definition at line 197 of file DS28E18.c.

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 }

◆ DS28E18_SetRomCommand()

void DS28E18_SetRomCommand ( DS28E18_one_wire_rom_commands_T  rom_cmd)

Set 1-Wire 'current_ROM_command' (normally MATCH_ROM, SKIP_ROM during device search). Does not send anything to lower-level code; just sets the operating mode for this DS28E18 layer.

Definition at line 232 of file DS28E18.c.

References MATCH_ROM, and SKIP_ROM.

233 {
234  assert(rom_cmd==MATCH_ROM || rom_cmd==SKIP_ROM);
235  current_ROM_command = rom_cmd;
236 }
don&#39;t use ROM ID (applicable only when there is only 1 slave on the bus)
Definition: DS28E18.h:78
address a specific slave by ROM ID
Definition: DS28E18.h:76

◆ DS28E18_WriteConfiguration()

bool DS28E18_WriteConfiguration ( DS28E18_protocol_speed_T  SPD,
DS28E18_ignore_nack_T  INACK,
DS28E18_protocol_T  PROT,
DS28E18_spi_mode_T  SPI_MODE 
)

Device Function Command: Write Configuration (55h)

Parameters
SPDDesired protocol speed from macros
INACKDesired INACK configuration from macros
PROTDesired protocol from macros
SPI_MODEDesired SPI Mode from macros
Returns
true - command successful
false - command failed

Definition at line 586 of file DS28E18.c.

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 }

◆ DS28E18_WriteGpioConfiguration()

bool DS28E18_WriteGpioConfiguration ( DS28E18_target_configuration_register_T  CFG_REG_TARGET,
uint8_t  GPIO_HI,
uint8_t  GPIO_LO 
)

Device Function Command: Write GPIO Configuration (83h)

Parameters
CFG_REG_TARGETDesired GPIO Configuration Register to write to
GPIO_HIControl/Buffer register high byte
GPIO_LOControl/Buffer register low byte
Returns
true - command successful
false - command failed
Note
Use GPIO Configuration functions to help build GPIO_HI/GPIO_LO parameter.

Definition at line 635 of file DS28E18.c.

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 }

◆ DS28E18_WriteSequencer()

bool DS28E18_WriteSequencer ( unsigned short  nineBitStartingAddress,
const uint8_t *  txData,
int  txDataSize 
)

Device Function Command: Write Sequencer (11h) - Write command sequence into DS28E28 sequencer memory over 1Wire

Parameters
nineBitStartingAddressTarget write address
txDataArray of data to be written into the sequencer memory starting from the target write address
txDataSizeNumber of elements found in txData array
Returns
true - command successful
false - command failed
Note
Use Sequencer Commands functions to help build txData array.

Definition at line 423 of file DS28E18.c.

Referenced by DS28E18_BuildPacket_WriteAndRun().

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 }