328 lines
8.0 KiB
C
328 lines
8.0 KiB
C
|
// Module for interfacing with the OneWire interface
|
||
|
|
||
|
//#include "lua.h"
|
||
|
#include "lualib.h"
|
||
|
#include "lauxlib.h"
|
||
|
#include "auxmods.h"
|
||
|
#include "lrotable.h"
|
||
|
#include "driver/onewire.h"
|
||
|
|
||
|
// Lua: ow.setup( id )
|
||
|
static int ICACHE_FLASH_ATTR ow_setup( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
|
||
|
if(id==0)
|
||
|
return luaL_error( L, "no 1-wire for D0" );
|
||
|
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
|
||
|
onewire_init( id );
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Lua: r = ow.reset( id )
|
||
|
static int ICACHE_FLASH_ATTR ow_reset( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
lua_pushinteger( L, onewire_reset(id) );
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// Lua: ow.skip( id )
|
||
|
static int ICACHE_FLASH_ATTR ow_skip( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
onewire_skip(id);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Lua: ow.select( id, buf[8])
|
||
|
static int ICACHE_FLASH_ATTR ow_select( lua_State *L )
|
||
|
{
|
||
|
uint8_t rom[8];
|
||
|
size_t datalen;
|
||
|
int numdata, i;
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
const char *pdata;
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
|
||
|
if( lua_istable( L, 2 ) )
|
||
|
{
|
||
|
datalen = lua_objlen( L, 2 );
|
||
|
if (datalen!=8)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
for( i = 0; i < datalen; i ++ )
|
||
|
{
|
||
|
lua_rawgeti( L, 2, i + 1 );
|
||
|
numdata = ( int )luaL_checkinteger( L, -1 );
|
||
|
lua_pop( L, 1 );
|
||
|
if( numdata > 255 )
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
rom[i] = (uint8_t)numdata;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pdata = luaL_checklstring( L, 2, &datalen );
|
||
|
if (datalen!=8)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
for( i = 0; i < datalen; i ++ ){
|
||
|
rom[i] = pdata[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onewire_select(id, rom);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Lua: ow.write( id, v, power)
|
||
|
static int ICACHE_FLASH_ATTR ow_write( lua_State *L )
|
||
|
{
|
||
|
int power = 0;
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
|
||
|
int v = (int)luaL_checkinteger( L, 2 );
|
||
|
if( v > 255 )
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
if(lua_isnumber(L, 3))
|
||
|
power = lua_tointeger(L, 3);
|
||
|
if(power!=0)
|
||
|
power = 1;
|
||
|
|
||
|
onewire_write((uint8_t)id, (uint8_t)v, (uint8_t)power);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Lua: ow.write_bytes( id, buf, power)
|
||
|
static int ICACHE_FLASH_ATTR ow_write_bytes( lua_State *L )
|
||
|
{
|
||
|
int power = 0;
|
||
|
size_t datalen;
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
|
||
|
const uint8_t *pdata = luaL_checklstring( L, 2, &datalen );
|
||
|
|
||
|
if(lua_isnumber(L, 3))
|
||
|
power = lua_tointeger(L, 3);
|
||
|
if(power!=0)
|
||
|
power = 1;
|
||
|
|
||
|
onewire_write_bytes((uint8_t)id, pdata, (uint16_t)datalen, (uint8_t)power);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Lua: r = ow.read( id )
|
||
|
static int ICACHE_FLASH_ATTR ow_read( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
lua_pushinteger( L, onewire_read(id) );
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// Lua: r = ow.read_bytes( id, size )
|
||
|
static int ICACHE_FLASH_ATTR ow_read_bytes( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
u32 size = ( u32 )luaL_checkinteger( L, 2 );
|
||
|
if( size == 0 )
|
||
|
return 0;
|
||
|
|
||
|
luaL_Buffer b;
|
||
|
luaL_buffinit( L, &b );
|
||
|
char *p = luaL_prepbuffer(&b);
|
||
|
|
||
|
onewire_read_bytes(id, (uint8_t *)p, size);
|
||
|
|
||
|
luaL_addsize(&b, size);
|
||
|
luaL_pushresult( &b );
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// Lua: ow.depower( id )
|
||
|
static int ICACHE_FLASH_ATTR ow_depower( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
onewire_depower(id);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#if ONEWIRE_SEARCH
|
||
|
// Clear the search state so that if will start from the beginning again.
|
||
|
// Lua: ow.reset_search( id )
|
||
|
static int ICACHE_FLASH_ATTR ow_reset_search( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
onewire_reset_search(id);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Setup the search to find the device type 'family_code' on the next call
|
||
|
// to search(*newAddr) if it is present.
|
||
|
// Lua: ow.target_search( id, family_code)
|
||
|
static int ICACHE_FLASH_ATTR ow_target_search( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
|
||
|
int code = (int)luaL_checkinteger( L, 2 );
|
||
|
if( code > 255 )
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
|
||
|
onewire_target_search((uint8_t)id, (uint8_t)code);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Look for the next device. Returns 1 if a new address has been
|
||
|
// returned. A zero might mean that the bus is shorted, there are
|
||
|
// no devices, or you have already retrieved all of them. It
|
||
|
// 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.
|
||
|
|
||
|
// Lua: r = ow.search( id )
|
||
|
static int ICACHE_FLASH_ATTR ow_search( lua_State *L )
|
||
|
{
|
||
|
unsigned id = luaL_checkinteger( L, 1 );
|
||
|
MOD_CHECK_ID( ow, id );
|
||
|
|
||
|
luaL_Buffer b;
|
||
|
luaL_buffinit( L, &b );
|
||
|
char *p = luaL_prepbuffer(&b);
|
||
|
|
||
|
if(onewire_search(id, (uint8_t *)p)){
|
||
|
luaL_addsize(&b, 8);
|
||
|
luaL_pushresult( &b );
|
||
|
} else {
|
||
|
luaL_pushresult(&b); /* close buffer */
|
||
|
lua_pop(L,1);
|
||
|
lua_pushnil(L);
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if ONEWIRE_CRC
|
||
|
// uint8_t onewire_crc8(const uint8_t *addr, uint8_t len);
|
||
|
// Lua: r = ow.crc8( buf )
|
||
|
static int ICACHE_FLASH_ATTR ow_crc8( lua_State *L )
|
||
|
{
|
||
|
size_t datalen;
|
||
|
const uint8_t *pdata = luaL_checklstring( L, 1, &datalen );
|
||
|
if(datalen > 255)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
lua_pushinteger( L, onewire_crc8(pdata, (uint8_t)datalen) );
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
#if ONEWIRE_CRC16
|
||
|
// bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc);
|
||
|
// Lua: b = ow.check_crc16( buf, inverted_crc0, inverted_crc1, crc )
|
||
|
static int ICACHE_FLASH_ATTR ow_check_crc16( lua_State *L )
|
||
|
{
|
||
|
size_t datalen;
|
||
|
uint8_t inverted_crc[2];
|
||
|
const uint8_t *pdata = luaL_checklstring( L, 1, &datalen );
|
||
|
if(datalen > 65535)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
|
||
|
int crc = 0;
|
||
|
crc = luaL_checkinteger( L, 2 );
|
||
|
if(datalen > 255)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
inverted_crc[0] = (uint8_t)crc;
|
||
|
|
||
|
crc = luaL_checkinteger( L, 3 );
|
||
|
if(datalen > 255)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
inverted_crc[1] = (uint8_t)crc;
|
||
|
|
||
|
crc = 0;
|
||
|
if(lua_isnumber(L, 4))
|
||
|
crc = lua_tointeger(L, 4);
|
||
|
if(crc > 65535)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
|
||
|
lua_pushboolean( L, onewire_check_crc16(pdata, (uint16_t)datalen, inverted_crc, (uint16_t)crc) );
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc);
|
||
|
// Lua: r = ow.crc16( buf, crc )
|
||
|
static int ICACHE_FLASH_ATTR ow_crc16( lua_State *L )
|
||
|
{
|
||
|
size_t datalen;
|
||
|
const uint8_t *pdata = luaL_checklstring( L, 1, &datalen );
|
||
|
if(datalen > 65535)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
int crc = 0;
|
||
|
if(lua_isnumber(L, 2))
|
||
|
crc = lua_tointeger(L, 2);
|
||
|
if(crc > 65535)
|
||
|
return luaL_error( L, "wrong arg range" );
|
||
|
|
||
|
lua_pushinteger( L, onewire_crc16(pdata, (uint16_t)datalen, (uint16_t)crc) );
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
// Module function map
|
||
|
#define MIN_OPT_LEVEL 2
|
||
|
#include "lrodefs.h"
|
||
|
const LUA_REG_TYPE ow_map[] =
|
||
|
{
|
||
|
{ LSTRKEY( "setup" ), LFUNCVAL( ow_setup ) },
|
||
|
{ LSTRKEY( "reset" ), LFUNCVAL( ow_reset ) },
|
||
|
{ LSTRKEY( "skip" ), LFUNCVAL( ow_skip ) },
|
||
|
{ LSTRKEY( "select" ), LFUNCVAL( ow_select ) },
|
||
|
{ LSTRKEY( "write" ), LFUNCVAL( ow_write ) },
|
||
|
{ LSTRKEY( "write_bytes" ), LFUNCVAL( ow_write_bytes ) },
|
||
|
{ LSTRKEY( "read" ), LFUNCVAL( ow_read ) },
|
||
|
{ LSTRKEY( "read_bytes" ), LFUNCVAL( ow_read_bytes ) },
|
||
|
{ LSTRKEY( "depower" ), LFUNCVAL( ow_depower ) },
|
||
|
#if ONEWIRE_SEARCH
|
||
|
{ LSTRKEY( "reset_search" ), LFUNCVAL( ow_reset_search ) },
|
||
|
{ LSTRKEY( "target_search" ), LFUNCVAL( ow_target_search ) },
|
||
|
{ LSTRKEY( "search" ), LFUNCVAL( ow_search ) },
|
||
|
#endif
|
||
|
#if ONEWIRE_CRC
|
||
|
{ LSTRKEY( "crc8" ), LFUNCVAL( ow_crc8 ) },
|
||
|
#if ONEWIRE_CRC16
|
||
|
{ LSTRKEY( "check_crc16" ), LFUNCVAL( ow_check_crc16 ) },
|
||
|
{ LSTRKEY( "crc16" ), LFUNCVAL( ow_crc16 ) },
|
||
|
#endif
|
||
|
#endif
|
||
|
#if LUA_OPTIMIZE_MEMORY > 0
|
||
|
|
||
|
#endif
|
||
|
{ LNILKEY, LNILVAL }
|
||
|
};
|
||
|
|
||
|
LUALIB_API int ICACHE_FLASH_ATTR luaopen_ow( lua_State *L )
|
||
|
{
|
||
|
#if LUA_OPTIMIZE_MEMORY > 0
|
||
|
return 0;
|
||
|
#else // #if LUA_OPTIMIZE_MEMORY > 0
|
||
|
luaL_register( L, AUXLIB_OW, ow_map );
|
||
|
|
||
|
// Add the constants
|
||
|
|
||
|
return 1;
|
||
|
#endif // #if LUA_OPTIMIZE_MEMORY > 0
|
||
|
}
|