ow: add alarm scans and timing tweaking (#3461)
This commit is contained in:
parent
9b477e0aae
commit
77e5359087
|
@ -75,6 +75,20 @@ static uint8_t LastFamilyDiscrepancy[NUM_OW];
|
||||||
static uint8_t LastDeviceFlag[NUM_OW];
|
static uint8_t LastDeviceFlag[NUM_OW];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct onewire_timings_s onewire_timings = {
|
||||||
|
.reset_tx = 480,
|
||||||
|
.reset_wait = 70,
|
||||||
|
.reset_rx = 410,
|
||||||
|
.w_1_low = 5,
|
||||||
|
.w_1_high = 52,
|
||||||
|
.w_0_low = 65,
|
||||||
|
.w_0_high = 5,
|
||||||
|
.r_low = 5,
|
||||||
|
.r_wait = 8,
|
||||||
|
.r_delay = 52
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void onewire_init(uint8_t pin)
|
void onewire_init(uint8_t pin)
|
||||||
{
|
{
|
||||||
// pinMode(pin, INPUT);
|
// pinMode(pin, INPUT);
|
||||||
|
@ -108,13 +122,13 @@ uint8_t onewire_reset(uint8_t pin)
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
DIRECT_WRITE_LOW(pin);
|
DIRECT_WRITE_LOW(pin);
|
||||||
interrupts();
|
interrupts();
|
||||||
delayMicroseconds(480);
|
delayMicroseconds(onewire_timings.reset_tx);
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
DIRECT_MODE_INPUT(pin); // allow it to float
|
DIRECT_MODE_INPUT(pin); // allow it to float
|
||||||
delayMicroseconds(70);
|
delayMicroseconds(onewire_timings.reset_wait);
|
||||||
r = !DIRECT_READ(pin);
|
r = !DIRECT_READ(pin);
|
||||||
interrupts();
|
interrupts();
|
||||||
delayMicroseconds(410);
|
delayMicroseconds(onewire_timings.reset_rx);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +141,7 @@ static void onewire_write_bit(uint8_t pin, uint8_t v, uint8_t power)
|
||||||
if (v & 1) {
|
if (v & 1) {
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
DIRECT_WRITE_LOW(pin);
|
DIRECT_WRITE_LOW(pin);
|
||||||
delayMicroseconds(5);
|
delayMicroseconds(onewire_timings.w_1_low);
|
||||||
if (power) {
|
if (power) {
|
||||||
DIRECT_WRITE_HIGH(pin);
|
DIRECT_WRITE_HIGH(pin);
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,18 +149,18 @@ static void onewire_write_bit(uint8_t pin, uint8_t v, uint8_t power)
|
||||||
}
|
}
|
||||||
delayMicroseconds(8);
|
delayMicroseconds(8);
|
||||||
interrupts();
|
interrupts();
|
||||||
delayMicroseconds(52);
|
delayMicroseconds(onewire_timings.w_1_high);
|
||||||
} else {
|
} else {
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
DIRECT_WRITE_LOW(pin);
|
DIRECT_WRITE_LOW(pin);
|
||||||
delayMicroseconds(65);
|
delayMicroseconds(onewire_timings.w_0_low);
|
||||||
if (power) {
|
if (power) {
|
||||||
DIRECT_WRITE_HIGH(pin);
|
DIRECT_WRITE_HIGH(pin);
|
||||||
} else {
|
} else {
|
||||||
DIRECT_MODE_INPUT(pin); // drive output high by the pull-up
|
DIRECT_MODE_INPUT(pin); // drive output high by the pull-up
|
||||||
}
|
}
|
||||||
interrupts();
|
interrupts();
|
||||||
delayMicroseconds(5);
|
delayMicroseconds(onewire_timings.w_0_high);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,12 +175,12 @@ static uint8_t onewire_read_bit(uint8_t pin)
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
DIRECT_WRITE_LOW(pin);
|
DIRECT_WRITE_LOW(pin);
|
||||||
|
|
||||||
delayMicroseconds(5);
|
delayMicroseconds(onewire_timings.r_low);
|
||||||
DIRECT_MODE_INPUT(pin); // let pin float, pull up will raise
|
DIRECT_MODE_INPUT(pin); // let pin float, pull up will raise
|
||||||
delayMicroseconds(8);
|
delayMicroseconds(onewire_timings.r_wait);
|
||||||
r = DIRECT_READ(pin);
|
r = DIRECT_READ(pin);
|
||||||
interrupts();
|
interrupts();
|
||||||
delayMicroseconds(52);
|
delayMicroseconds(onewire_timings.r_delay);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +303,7 @@ void onewire_target_search(uint8_t pin, uint8_t family_code)
|
||||||
// Return TRUE : device found, ROM number in ROM_NO buffer
|
// Return TRUE : device found, ROM number in ROM_NO buffer
|
||||||
// FALSE : device not found, end of search
|
// FALSE : device not found, end of search
|
||||||
//
|
//
|
||||||
uint8_t onewire_search(uint8_t pin, uint8_t *newAddr)
|
uint8_t onewire_search(uint8_t pin, uint8_t *newAddr, uint8_t alarm_search)
|
||||||
{
|
{
|
||||||
uint8_t id_bit_number;
|
uint8_t id_bit_number;
|
||||||
uint8_t last_zero, rom_byte_number, search_result;
|
uint8_t last_zero, rom_byte_number, search_result;
|
||||||
|
@ -318,7 +332,7 @@ uint8_t onewire_search(uint8_t pin, uint8_t *newAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// issue the search command
|
// issue the search command
|
||||||
onewire_write(pin, 0xF0, owDefaultPower);
|
onewire_write(pin, alarm_search ? 0xEC : 0xF0, owDefaultPower);
|
||||||
|
|
||||||
// loop to do the search
|
// loop to do the search
|
||||||
do
|
do
|
||||||
|
|
|
@ -47,6 +47,24 @@
|
||||||
#define DIRECT_WRITE_LOW(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0))
|
#define DIRECT_WRITE_LOW(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0))
|
||||||
#define DIRECT_WRITE_HIGH(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1))
|
#define DIRECT_WRITE_HIGH(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1))
|
||||||
|
|
||||||
|
// This allows tweaking of individual timings when doing onewire operations
|
||||||
|
struct onewire_timings_s {
|
||||||
|
uint16_t reset_tx;
|
||||||
|
uint16_t reset_wait;
|
||||||
|
uint16_t reset_rx;
|
||||||
|
|
||||||
|
uint8_t w_1_low;
|
||||||
|
uint8_t w_1_high;
|
||||||
|
uint8_t w_0_low;
|
||||||
|
uint8_t w_0_high;
|
||||||
|
|
||||||
|
uint8_t r_low;
|
||||||
|
uint8_t r_wait;
|
||||||
|
uint8_t r_delay;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct onewire_timings_s onewire_timings;
|
||||||
|
|
||||||
void onewire_init(uint8_t pin);
|
void onewire_init(uint8_t pin);
|
||||||
|
|
||||||
// Perform a 1-Wire reset cycle. Returns 1 if a device responds
|
// Perform a 1-Wire reset cycle. Returns 1 if a device responds
|
||||||
|
@ -101,7 +119,8 @@ void onewire_target_search(uint8_t pin, uint8_t family_code);
|
||||||
// might be a good idea to check the CRC to make sure you didn't
|
// might be a good idea to check the CRC to make sure you didn't
|
||||||
// get garbage. The order is deterministic. You will always get
|
// get garbage. The order is deterministic. You will always get
|
||||||
// the same devices in the same order.
|
// the same devices in the same order.
|
||||||
uint8_t onewire_search(uint8_t pin, uint8_t *newAddr);
|
// If alarm_search is non-zero, it only looks for devices with the Alarm Flag set (if supported)
|
||||||
|
uint8_t onewire_search(uint8_t pin, uint8_t *newAddr, uint8_t alarm_search);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ONEWIRE_CRC
|
#if ONEWIRE_CRC
|
||||||
|
|
|
@ -201,8 +201,15 @@ static int ow_search( lua_State *L )
|
||||||
luaL_Buffer b;
|
luaL_Buffer b;
|
||||||
luaL_buffinit( L, &b );
|
luaL_buffinit( L, &b );
|
||||||
char *p = luaL_prepbuffer(&b);
|
char *p = luaL_prepbuffer(&b);
|
||||||
|
uint8_t alarm_search = 0;
|
||||||
|
|
||||||
if(onewire_search(id, (uint8_t *)p)){
|
if(lua_isnumber(L, 2))
|
||||||
|
alarm_search = lua_tointeger(L, 2);
|
||||||
|
if(alarm_search != 0)
|
||||||
|
alarm_search = 1;
|
||||||
|
|
||||||
|
|
||||||
|
if(onewire_search(id, (uint8_t *)p, alarm_search)){
|
||||||
luaL_addsize(&b, 8);
|
luaL_addsize(&b, 8);
|
||||||
luaL_pushresult( &b );
|
luaL_pushresult( &b );
|
||||||
} else {
|
} else {
|
||||||
|
@ -281,6 +288,33 @@ static int ow_crc16( lua_State *L )
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Lua: r = ow.set_timings( reset_tx, reset_wait, reset_rx, w1_low, w1_high, w0_low, w0_high, r_low, r_wait, r_delay )
|
||||||
|
static int ow_set_timings( lua_State *L )
|
||||||
|
{
|
||||||
|
if(lua_isnumber(L, 1))
|
||||||
|
onewire_timings.reset_tx = lua_tointeger(L, 1);
|
||||||
|
if(lua_isnumber(L, 2))
|
||||||
|
onewire_timings.reset_wait = lua_tointeger(L, 2);
|
||||||
|
if(lua_isnumber(L, 3))
|
||||||
|
onewire_timings.reset_rx = lua_tointeger(L, 3);
|
||||||
|
if(lua_isnumber(L, 4))
|
||||||
|
onewire_timings.w_1_low = lua_tointeger(L, 4);
|
||||||
|
if(lua_isnumber(L, 5))
|
||||||
|
onewire_timings.w_1_high = lua_tointeger(L, 5);
|
||||||
|
if(lua_isnumber(L, 6))
|
||||||
|
onewire_timings.w_0_low = lua_tointeger(L, 6);
|
||||||
|
if(lua_isnumber(L, 7))
|
||||||
|
onewire_timings.w_0_high = lua_tointeger(L, 7);
|
||||||
|
if(lua_isnumber(L, 8))
|
||||||
|
onewire_timings.r_low = lua_tointeger(L, 8);
|
||||||
|
if(lua_isnumber(L, 9))
|
||||||
|
onewire_timings.r_wait = lua_tointeger(L, 9);
|
||||||
|
if(lua_isnumber(L, 10))
|
||||||
|
onewire_timings.r_delay = lua_tointeger(L, 10);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Module function map
|
// Module function map
|
||||||
LROT_BEGIN(ow, NULL, 0)
|
LROT_BEGIN(ow, NULL, 0)
|
||||||
LROT_FUNCENTRY( setup, ow_setup )
|
LROT_FUNCENTRY( setup, ow_setup )
|
||||||
|
@ -304,6 +338,7 @@ LROT_BEGIN(ow, NULL, 0)
|
||||||
LROT_FUNCENTRY( crc16, ow_crc16 )
|
LROT_FUNCENTRY( crc16, ow_crc16 )
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
LROT_FUNCENTRY( set_timings, ow_set_timings )
|
||||||
LROT_END(ow, NULL, 0)
|
LROT_END(ow, NULL, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,10 +118,11 @@ Clears the search state so that it will start from the beginning again.
|
||||||
Looks for the next device.
|
Looks for the next device.
|
||||||
|
|
||||||
#### Syntax
|
#### Syntax
|
||||||
`ow.search(pin)`
|
`ow.search(pin, [alarm_search])`
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
`pin` 1~12, I/O index
|
- `pin` 1~12, I/O index
|
||||||
|
- `alarm_search` 1 / 0, if 0 a regular 0xF0 search is performed (default if parameter is absent), if 1 a 0xEC ALARM SEARCH is performed.
|
||||||
|
|
||||||
#### Returns
|
#### Returns
|
||||||
`rom_code` string with length of 8 upon success. It contains the rom code of slave device. Returns `nil` if search was unsuccessful.
|
`rom_code` string with length of 8 upon success. It contains the rom code of slave device. Returns `nil` if search was unsuccessful.
|
||||||
|
@ -266,3 +267,46 @@ Writes multi bytes. If `power` is 1 then the wire is held high at the end for pa
|
||||||
|
|
||||||
#### See also
|
#### See also
|
||||||
[ow.depower()](#owdepower)
|
[ow.depower()](#owdepower)
|
||||||
|
|
||||||
|
## ow.set_timings()
|
||||||
|
Tweak different bit timing parameters. Some slow custom devices might not work perfectly well with NodeMCU as 1-wire master. Since NodeMCU ow module is bit-banging the 1-wire protocol, it is possible to adjust the timings a bit.
|
||||||
|
|
||||||
|
Note that you can break the protocol totally if you tweak some numbers too much. This should never be needed with normal devices.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`ow.set_timings(reset_tx, reset_wait, reset_rx, w1_low, w1_high, w0_low, w0_high, r_low, r_wait, r_delay)`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
Each parameter specifies number of microseconds to delay at different stages in the 1-wire bit-banging process.
|
||||||
|
A nil value will leave the value unmodified.
|
||||||
|
|
||||||
|
- `reset_tx` pull bus low during reset (default 480)
|
||||||
|
- `reset_wait` wait for presence pulse after reset (default 70)
|
||||||
|
- `reset_rx` delay after presence pulse have been checked (default 410)
|
||||||
|
- `w1_low` pull bus low during write 1 slot (default 5)
|
||||||
|
- `w1_high` leave bus high during write 1 slot (default 52)
|
||||||
|
- `w0_low` pull bus low during write 1 slot (default 65)
|
||||||
|
- `w0_high` leave bus high during write 1 slot (default 5)
|
||||||
|
- `r_low` pull bus low during read slot (default 5)
|
||||||
|
- `r_wait` wait before reading bus level during read slot (default 8)
|
||||||
|
- `r_delay` delay after reading bus level (default 52)
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
`nil`
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
```lua
|
||||||
|
-- Give 300uS longer read/write slots for slow MCU based 1-wire slave
|
||||||
|
ow.set_timings(
|
||||||
|
nil, -- reset_tx
|
||||||
|
nil, -- reset_wait
|
||||||
|
nil, -- reset_rx
|
||||||
|
nil, -- w1_low
|
||||||
|
352, -- w1_high
|
||||||
|
nil, -- w0_low
|
||||||
|
305, -- w0_high
|
||||||
|
nil, -- r_low
|
||||||
|
nil, -- r_wait
|
||||||
|
352 -- r_delay
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in New Issue