Skip to content

Commit 993d9fa

Browse files
committed
Add support for Skip ROM and different Write buffer length
If the Serial Number is not passed we use Skip ROM command to communicate. (This work only if a single slave is present) We also support a write buffer with size up to 8 bytes. Now you can write a single byte if needed. Now we can skip the READ verification process. If the PF bit fail we force the verify process. If the verify process fail we attempt to read again the scratchpad.
1 parent 0e20a5d commit 993d9fa

File tree

2 files changed

+113
-57
lines changed

2 files changed

+113
-57
lines changed

DS2431.cpp

Lines changed: 75 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
MIT License
33
44
Copyright (c) 2017 Tom Magnier
5+
Modified 2018 by Nicolò Veronese
56
67
Permission is hereby granted, free of charge, to any person obtaining a copy
78
of this software and associated documentation files (the "Software"), to deal
@@ -26,92 +27,121 @@ SOFTWARE.
2627

2728
DS2431::DS2431(OneWire &ow)
2829
: _ow(ow)
29-
{
30+
{
31+
_skiprom = true;
3032
}
3133

32-
void DS2431::begin(uint8_t serialNumber[8])
34+
void DS2431::begin(uint8_t serialNumber[ONE_WIRE_MAC_SIZE])
3335
{
34-
memcpy(_serialNumber, serialNumber, 8);
35-
_init = true;
36+
memcpy(_serialNumber, serialNumber, ONE_WIRE_MAC_SIZE);
37+
_skiprom = false;
3638
}
3739

38-
int DS2431::read(uint16_t address)
40+
uint8_t DS2431::read(uint16_t address)
3941
{
4042
uint8_t res = 0xFF;
43+
read(address, &res, 1);
4144

42-
if(!read(address, &res, 1))
43-
return -1;
44-
4545
return res;
4646
}
4747

48-
bool DS2431::read(uint16_t address, uint8_t *buf, uint16_t len)
48+
void DS2431::read(uint16_t address, uint8_t *buf, uint16_t len)
4949
{
50-
if (!_init)
51-
return false;
52-
_ow.reset();
53-
_ow.select(_serialNumber);
50+
_startTransmission();
51+
5452
_ow.write(READ_MEMORY, 1);
5553
_ow.write(lowByte(address), 1);
5654
_ow.write(highByte(address), 1);
5755

5856
for (int i = 0; i < len; i++)
59-
buf[i] = _ow.read();
57+
buf[i] = _ow.read();
6058

6159
_ow.depower();
62-
63-
return true;
6460
}
6561

66-
bool DS2431::write(uint16_t address, uint8_t buf[8])
62+
bool DS2431::write(uint16_t address, const uint8_t *buf, uint16_t count, bool verify /* = 0 */)
63+
{
64+
bool ret = _write(address, buf, count, verify);
65+
_ow.depower();
66+
return ret;
67+
}
68+
69+
bool DS2431::_write(uint16_t address, const uint8_t *buf, uint16_t count, bool verify)
6770
{
68-
if (address >= EEPROM_SIZE || address % 8 != 0) //Address has to be aligned on an 8-byte boundary
71+
uint8_t error_count = 0;
72+
uint8_t buffer[DS2431_BUFFER_SIZE];
73+
uint8_t crc16[DS2431_CRC_SIZE];
74+
75+
//Address has to be aligned on an 8-byte boundary
76+
if (address >= DS2431_EEPROM_SIZE || address % 8 != 0)
6977
return false;
7078

71-
//Write scratchpad with CRC check
72-
uint8_t buffer[13];
79+
// Prepare buffer data
7380
buffer[0] = WRITE_SCRATCHPAD;
7481
buffer[1] = lowByte(address);
7582
buffer[2] = highByte(address);
76-
memcpy(&buffer[3], buf, 8);
83+
memcpy(&buffer[DS2431_CMD_SIZE], buf, count);
7784

78-
_ow.reset();
79-
_ow.select(_serialNumber);
80-
_ow.write_bytes(buffer, 11, 1);
81-
_ow.read_bytes(&buffer[11], 2); //Read CRC-16
85+
//Write scratchpad with CRC check
86+
_startTransmission();
87+
_ow.write_bytes(buffer, DS2431_CMD_SIZE + count, 1); // Write CMD + LSB Adr + MSB Adr
88+
_ow.read_bytes(crc16, DS2431_CRC_SIZE); //Read CRC-16
8289

83-
if (!_ow.check_crc16(buffer, 11, &buffer[11]))
84-
return false; //CRC not matching
90+
if (!_ow.check_crc16(buffer, DS2431_CMD_SIZE + count, crc16)){
91+
verify = true; //CRC not matching, try to read again
92+
}
8593

86-
//Read scratchpad
94+
// Read verification
95+
// Prepare buffer data
8796
buffer[0] = READ_SCRATCHPAD;
97+
do {
98+
//Read scratchpad to compare with the data sent
99+
_startTransmission();
100+
_ow.write(buffer[0], 1); // Write CMD
101+
_ow.read_bytes(&buffer[1], DS2431_CMD_SIZE); //Read TA1, TA2, E/S, scratchpad
102+
103+
if (buffer[3] != DS2431_PF_MASK) {
104+
verify = true;
105+
}
88106

89-
_ow.reset();
90-
_ow.select(_serialNumber);
91-
_ow.write(buffer[0], 1);
92-
_ow.read_bytes(&buffer[1], 13); //Read TA1, TA2, E/S, scratchpad and CRC
107+
if(verify) {
108+
_ow.read_bytes(&buffer[4], count); //Read scratchpad
109+
_ow.read_bytes(crc16, DS2431_CRC_SIZE); //Read CRC-16
93110

94-
if (!_ow.check_crc16(buffer, 12, &buffer[12]))
95-
return false; //CRC not matching. TODO this does not indicate that scratchpad data is invalid, retry read instead ?
111+
if (!_ow.check_crc16(buffer, 12, crc16)) {
112+
error_count++; //CRC not matching.
113+
continue;
114+
}
96115

97-
if (address != ((buffer[2] << 8) + buffer[1]))
98-
return false; //Address not matching
116+
if (address != ((buffer[2] << 8) + buffer[1])) {
117+
return false; //Address not matching
118+
}
99119

100-
if (buffer[3] != 0x07)
101-
return false; //Invalid transfer or data already copied (wrong value for E/S).
120+
if (buffer[3] != DS2431_PF_MASK) {
121+
return false; //Invalid transfer or data already copied (wrong value for E/S).
122+
}
102123

103-
if (memcmp(&buffer[4], buf, 8) != 0)
104-
return false; //Data in the scratchpad is invalid.
124+
if (memcmp(&buffer[4], buf, 8) != 0) {
125+
return false; //Data in the scratchpad is invalid.
126+
}
127+
}
128+
129+
break;
130+
} while(error_count < DS2431_READ_RETRY);
131+
132+
// Prepare buffer data
133+
buffer[0] = COPY_SCRATCHPAD;
105134

106135
//Copy scratchpad
107-
_ow.reset();
108-
_ow.select(_serialNumber);
109-
_ow.write(COPY_SCRATCHPAD, 1);
110-
_ow.write_bytes(&buffer[1], 3, 1); //Send authorization code (TA1, TA2, E/S)
136+
_startTransmission();
137+
_ow.write_bytes(buffer, DS2431_CMD_SIZE + 1, 1); //Send authorization code (TA1, TA2, E/S)
111138
delay(15); // t_PROG = 12.5ms worst case.
112139

113-
if (_ow.read() != 0xAA)
140+
uint8_t res = _ow.read();
141+
142+
if (res != DS2431_WRITE_MASK) {
114143
return false;
144+
}
115145

116146
return true;
117147
}

DS2431.h

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
MIT License
33
44
Copyright (c) 2017 Tom Magnier
5+
Modified 2018 by Nicolò Veronese
56
67
Permission is hereby granted, free of charge, to any person obtaining a copy
78
of this software and associated documentation files (the "Software"), to deal
@@ -29,39 +30,64 @@ SOFTWARE.
2930

3031
class DS2431 {
3132
public:
33+
const static uint8_t ONE_WIRE_MAC_SIZE = 8;
34+
3235
const static uint8_t ONE_WIRE_FAMILY_CODE = 0x2D;
3336

37+
const static uint8_t DS2431_EEPROM_SIZE = 128;
38+
const static uint8_t DS2431_ROW_SIZE = 8;
39+
3440
DS2431(OneWire &ow); // OneWire class
35-
36-
void begin(uint8_t serialNumber[8]); // family code, 48bit serial number and CRC as returned by OneWire search function
41+
42+
void begin(uint8_t serialNumber[ONE_WIRE_MAC_SIZE]); // family code, 48bit serial number and CRC as returned by OneWire search function
3743

3844
/* Single byte read
3945
*/
40-
int read(uint16_t address);
46+
uint8_t read(uint16_t address);
4147

4248
/* Multiple byte read.
4349
*/
44-
bool read(uint16_t address, uint8_t *buf, uint16_t len);
50+
void read(uint16_t address, uint8_t *buf, uint16_t len);
4551

46-
/* Full row (8 byte) write. Please note : address must be a multiple of 8.
47-
Return true if operation was successful.
48-
The OneWire bus should be de-powered after calling this function.
52+
/* Multiple byte write.
53+
Please note : address must be a multiple of 8. Write up to 8 bytes
54+
Return true if operation was successful.
55+
The OneWire bus should be de-powered after calling this function.
4956
*/
50-
bool write(uint16_t address, uint8_t buf[8]);
57+
bool write(uint16_t address, const uint8_t *buf, uint16_t count, bool verify = false);
5158

5259
private:
53-
OneWire &_ow;
54-
uint8_t _serialNumber[8];
55-
bool _init;
60+
const static uint8_t DS2431_PF_MASK = 0x07;
61+
const static uint8_t DS2431_WRITE_MASK = 0xAA;
62+
63+
const static uint8_t DS2431_CMD_SIZE = 3;
64+
const static uint8_t DS2431_CRC_SIZE = 2;
5665

57-
const static uint16_t EEPROM_SIZE = 128;
66+
const static uint8_t DS2431_READ_RETRY = 2;
67+
68+
const static uint16_t DS2431_BUFFER_SIZE = DS2431_ROW_SIZE + DS2431_CMD_SIZE + DS2431_CRC_SIZE;
69+
70+
OneWire &_ow;
71+
uint8_t _serialNumber[ONE_WIRE_MAC_SIZE];
72+
bool _skiprom;
5873

5974
enum Commands {
6075
WRITE_SCRATCHPAD = 0x0F,
6176
READ_SCRATCHPAD = 0xAA,
6277
COPY_SCRATCHPAD = 0x55,
6378
READ_MEMORY = 0xF0
6479
};
80+
81+
bool _write(uint16_t address, const uint8_t *buf, uint16_t count, bool verify);
82+
83+
inline void _startTransmission()
84+
{
85+
_ow.reset();
86+
if (_skiprom)
87+
_ow.skip();
88+
else
89+
_ow.select(_serialNumber);
90+
}
6591
};
6692

6793
#endif // _DS2431_H

0 commit comments

Comments
 (0)