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];
|
||||
#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)
|
||||
{
|
||||
// pinMode(pin, INPUT);
|
||||
|
@ -108,13 +122,13 @@ uint8_t onewire_reset(uint8_t pin)
|
|||
noInterrupts();
|
||||
DIRECT_WRITE_LOW(pin);
|
||||
interrupts();
|
||||
delayMicroseconds(480);
|
||||
delayMicroseconds(onewire_timings.reset_tx);
|
||||
noInterrupts();
|
||||
DIRECT_MODE_INPUT(pin); // allow it to float
|
||||
delayMicroseconds(70);
|
||||
delayMicroseconds(onewire_timings.reset_wait);
|
||||
r = !DIRECT_READ(pin);
|
||||
interrupts();
|
||||
delayMicroseconds(410);
|
||||
delayMicroseconds(onewire_timings.reset_rx);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -127,7 +141,7 @@ static void onewire_write_bit(uint8_t pin, uint8_t v, uint8_t power)
|
|||
if (v & 1) {
|
||||
noInterrupts();
|
||||
DIRECT_WRITE_LOW(pin);
|
||||
delayMicroseconds(5);
|
||||
delayMicroseconds(onewire_timings.w_1_low);
|
||||
if (power) {
|
||||
DIRECT_WRITE_HIGH(pin);
|
||||
} else {
|
||||
|
@ -135,18 +149,18 @@ static void onewire_write_bit(uint8_t pin, uint8_t v, uint8_t power)
|
|||
}
|
||||
delayMicroseconds(8);
|
||||
interrupts();
|
||||
delayMicroseconds(52);
|
||||
delayMicroseconds(onewire_timings.w_1_high);
|
||||
} else {
|
||||
noInterrupts();
|
||||
DIRECT_WRITE_LOW(pin);
|
||||
delayMicroseconds(65);
|
||||
delayMicroseconds(onewire_timings.w_0_low);
|
||||
if (power) {
|
||||
DIRECT_WRITE_HIGH(pin);
|
||||
} else {
|
||||
DIRECT_MODE_INPUT(pin); // drive output high by the pull-up
|
||||
}
|
||||
interrupts();
|
||||
delayMicroseconds(5);
|
||||
delayMicroseconds(onewire_timings.w_0_high);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,12 +175,12 @@ static uint8_t onewire_read_bit(uint8_t pin)
|
|||
noInterrupts();
|
||||
DIRECT_WRITE_LOW(pin);
|
||||
|
||||
delayMicroseconds(5);
|
||||
delayMicroseconds(onewire_timings.r_low);
|
||||
DIRECT_MODE_INPUT(pin); // let pin float, pull up will raise
|
||||
delayMicroseconds(8);
|
||||
delayMicroseconds(onewire_timings.r_wait);
|
||||
r = DIRECT_READ(pin);
|
||||
interrupts();
|
||||
delayMicroseconds(52);
|
||||
delayMicroseconds(onewire_timings.r_delay);
|
||||
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
|
||||
// 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 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
|
||||
onewire_write(pin, 0xF0, owDefaultPower);
|
||||
onewire_write(pin, alarm_search ? 0xEC : 0xF0, owDefaultPower);
|
||||
|
||||
// loop to do the search
|
||||
do
|
||||
|
|
|
@ -47,6 +47,24 @@
|
|||
#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))
|
||||
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
// get garbage. The order is deterministic. You will always get
|
||||
// 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
|
||||
|
||||
#if ONEWIRE_CRC
|
||||
|
|
|
@ -201,8 +201,15 @@ static int ow_search( lua_State *L )
|
|||
luaL_Buffer b;
|
||||
luaL_buffinit( L, &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_pushresult( &b );
|
||||
} else {
|
||||
|
@ -281,6 +288,33 @@ static int ow_crc16( lua_State *L )
|
|||
#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
|
||||
LROT_BEGIN(ow, NULL, 0)
|
||||
LROT_FUNCENTRY( setup, ow_setup )
|
||||
|
@ -304,6 +338,7 @@ LROT_BEGIN(ow, NULL, 0)
|
|||
LROT_FUNCENTRY( crc16, ow_crc16 )
|
||||
#endif
|
||||
#endif
|
||||
LROT_FUNCENTRY( set_timings, ow_set_timings )
|
||||
LROT_END(ow, NULL, 0)
|
||||
|
||||
|
||||
|
|
|
@ -60,14 +60,14 @@ Stops forcing power onto the bus. You only need to do this if you used the 'powe
|
|||
#### Returns
|
||||
`nil`
|
||||
|
||||
####See also
|
||||
#### See also
|
||||
- [ow.write()](#owwrite)
|
||||
- [ow.write_bytes()](#owwrite_bytes)
|
||||
|
||||
## ow.read()
|
||||
Reads a byte.
|
||||
|
||||
####Syntax
|
||||
#### Syntax
|
||||
`ow.read(pin)`
|
||||
|
||||
#### Parameters
|
||||
|
@ -118,10 +118,11 @@ Clears the search state so that it will start from the beginning again.
|
|||
Looks for the next device.
|
||||
|
||||
#### Syntax
|
||||
`ow.search(pin)`
|
||||
`ow.search(pin, [alarm_search])`
|
||||
|
||||
#### 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
|
||||
`rom_code` string with length of 8 upon success. It contains the rom code of slave device. Returns `nil` if search was unsuccessful.
|
||||
|
@ -190,7 +191,7 @@ else
|
|||
end
|
||||
```
|
||||
|
||||
####See also
|
||||
#### See also
|
||||
[ow.reset()](#owreset)
|
||||
|
||||
## ow.setup()
|
||||
|
@ -230,7 +231,7 @@ Sets up the search to find the device type `family_code`. The search itself has
|
|||
#### Returns
|
||||
`nil`
|
||||
|
||||
####See also
|
||||
#### See also
|
||||
[ow.search()](#owsearch)
|
||||
|
||||
## ow.write()
|
||||
|
@ -247,7 +248,7 @@ Writes a byte. If `power` is 1 then the wire is held high at the end for parasit
|
|||
#### Returns
|
||||
`nil`
|
||||
|
||||
####See also
|
||||
#### See also
|
||||
[ow.depower()](#owdepower)
|
||||
|
||||
## ow.write_bytes()
|
||||
|
@ -264,5 +265,48 @@ Writes multi bytes. If `power` is 1 then the wire is held high at the end for pa
|
|||
#### Returns
|
||||
`nil`
|
||||
|
||||
####See also
|
||||
#### See also
|
||||
[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