123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- // Module for interfacing with the OneWire interface
- #include "module.h"
- #include "lauxlib.h"
- #include <stdint.h>
- #include "platform.h"
- static int ow_bus_table_ref;
- // Lua: ow.setup( pin )
- static int ow_setup( lua_State *L )
- {
- int pin = luaL_checkint( L, 1 );
- luaL_argcheck( L, pin >= 0, 1, "invalid pin" );
- if (platform_onewire_init( pin ) != PLATFORM_OK)
- luaL_error( L, "failed" );
- return 0;
- }
- // Lua: r = ow.reset( pin )
- static int ow_reset( lua_State *L )
- {
- int pin = luaL_checkint( L, 1 );
- luaL_argcheck( L, pin >= 0, 1, "invalid pin" );
- uint8_t presence;
- if (platform_onewire_reset( pin, &presence ) != PLATFORM_OK)
- luaL_error( L, "failed" );
- lua_pushinteger( L, presence );
- return 1;
- }
- // Lua: ow.write( pin, v, power)
- static int ow_write( lua_State *L )
- {
- int stack = 0;
- int pin = luaL_checkint( L, ++stack );
- luaL_argcheck( L, pin >= 0, stack, "invalid pin" );
- int data = luaL_checkint( L, ++stack );
- luaL_argcheck( L, data >= 0 && data < 256, stack, "invalid data" );
- int power = luaL_optint( L, ++stack, 0 ) != 0 ? 1 : 0;
- uint8_t d = data;
- if (platform_onewire_write_bytes( pin, &d, 1, power ) != PLATFORM_OK)
- luaL_error( L, "failed" );
- return 0;
- }
- // Lua: ow.write_bytes( pin, buf, power)
- static int ow_write_bytes( lua_State *L )
- {
- int stack = 0;
- size_t datalen;
- int pin = luaL_checkint( L, ++stack );
- luaL_argcheck( L, pin >= 0, stack, "invalid pin" );
- const char *pdata = luaL_checklstring( L, ++stack, &datalen );
- int power = luaL_optint( L, ++stack, 0 ) != 0 ? 1 : 0;
- platform_onewire_write_bytes( pin, (uint8_t *)pdata, datalen, power);
- return 0;
- }
- // Lua: r = ow.read( pin )
- static int ow_read( lua_State *L )
- {
- int pin = luaL_checkint( L, 1 );
- luaL_argcheck( L, pin >= 0, 1, "invalid pin" );
- uint8_t data;
- if (platform_onewire_read_bytes( pin, &data, 1 ) != PLATFORM_OK)
- luaL_error( L, "failed" );
- lua_pushinteger( L, data );
- return 1;
- }
- // Lua: r = ow.read_bytes( pin, size )
- static int ow_read_bytes( lua_State *L )
- {
- int stack = 0;
- int pin = luaL_checkint( L, ++stack );
- luaL_argcheck( L, pin >= 0, stack, "invalid pin" );
- int size = luaL_checkint( L, ++stack );
- if (size == 0)
- return 0;
- luaL_argcheck( L, size <= LUAL_BUFFERSIZE, stack, "Attempt to read too many characters" );
- luaL_Buffer b;
- luaL_buffinit( L, &b );
- char *p = luaL_prepbuffer( &b );
- if (platform_onewire_read_bytes( pin, (uint8_t *)p, size ) != PLATFORM_OK)
- luaL_error( L, "failed" );
- luaL_addsize( &b, size );
- luaL_pushresult( &b );
- return 1;
- }
- // Lua: ow.select( pin, buf[8] )
- static int ow_select( lua_State *L )
- {
- int stack = 0;
- uint8_t rom[1+8];
- size_t datalen;
- int numdata, i;
- const char *pdata;
- int pin = luaL_checkint( L, ++stack );
- luaL_argcheck( L, pin >= 0, stack, "invalid pin" );
- if( lua_istable( L, ++stack ) )
- {
- datalen = lua_objlen( L, stack );
- luaL_argcheck( L, datalen == 8, stack, "wrong arg range" );
- for (i = 0; i < datalen; i ++) {
- lua_rawgeti( L, stack, i + 1 );
- numdata = ( int )luaL_checkinteger( L, -1 );
- lua_pop( L, 1 );
- if (numdata > 255)
- return luaL_error( L, "wrong arg range" );
- rom[1+i] = (uint8_t)numdata;
- }
- } else {
- pdata = luaL_checklstring( L, stack, &datalen );
- luaL_argcheck( L, datalen == 8, stack, "wrong arg range" );
- for (i = 0; i < datalen; i++) {
- rom[1+i] = pdata[i];
- }
- }
- rom[0] = 0x55; // select command
- if (platform_onewire_write_bytes( pin, rom, 1+8, 0 ) != PLATFORM_OK)
- luaL_error( L, "write failed" );
- return 0;
- }
- // Lua: ow.skip( pin )
- static int ow_skip( lua_State *L )
- {
- int pin = luaL_checkint( L, 1 );
- luaL_argcheck( L, pin >= 0, 1, "invalid pin" );
- const uint8_t cmd = 0xCC; // skip command
- if (platform_onewire_write_bytes( pin, &cmd, 1, 0 ) != PLATFORM_OK)
- luaL_error( L, "write failed" );
- return 0;
- }
- // Lua: ow.depower( pin )
- static int ow_depower( lua_State *L )
- {
- int pin = luaL_checkint( L, 1 );
- luaL_argcheck( L, pin >= 0, 1, "invalid pin" );
- platform_onewire_depower( pin );
- return 0;
- }
- // Clear the search state so that if will start from the beginning again.
- // Lua: ow.reset_search( pin )
- static int ow_reset_search( lua_State *L )
- {
- int pin = luaL_checkint( L, 1 );
- luaL_argcheck( L, pin >= 0, 1, "invalid pin" );
- // set up new userdata for this pin
- lua_rawgeti( L, LUA_REGISTRYINDEX, ow_bus_table_ref );
- platform_onewire_bus_t *bus = (platform_onewire_bus_t *)lua_newuserdata( L, sizeof( platform_onewire_bus_t ));
- lua_rawseti( L, -2, pin );
- // remove table from stack
- lua_pop( L, 1 );
- platform_onewire_reset_search( bus );
- 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( pin, family_code )
- static int ow_target_search( lua_State *L )
- {
- int stack = 0;
- int pin = luaL_checkint( L, ++stack );
- luaL_argcheck( L, pin >= 0, stack, "invalid pin" );
- int code = (int)luaL_checkinteger( L, ++stack );
- luaL_argcheck( L, code >= 0 && code < 256, stack, "wrong arg range" );
- // set up new userdata for this pin
- lua_rawgeti( L, LUA_REGISTRYINDEX, ow_bus_table_ref );
- platform_onewire_bus_t *bus = (platform_onewire_bus_t *)lua_newuserdata( L, sizeof( platform_onewire_bus_t ));
- lua_rawseti( L, -2, pin );
- // remove table from stack
- lua_pop( L, 1 );
- platform_onewire_target_search( (uint8_t)code, bus );
- 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( pin )
- static int ow_search( lua_State *L )
- {
- int pin = luaL_checkint( L, 1 );
- luaL_argcheck( L, pin >= 0, 1, "invalid pin" );
- // look-up bus userdata for this pin
- lua_rawgeti( L, LUA_REGISTRYINDEX, ow_bus_table_ref );
- lua_rawgeti( L, -1, pin );
- platform_onewire_bus_t *bus = (platform_onewire_bus_t *)lua_touserdata( L, -1 );
- if (!bus)
- return luaL_error( L, "search not initialized" );
- // removed temps from stack
- lua_pop( L, 2 );
- luaL_Buffer b;
- luaL_buffinit( L, &b );
- char *p = luaL_prepbuffer( &b );
- if (platform_onewire_search( pin, (uint8_t *)p, bus )){
- luaL_addsize( &b, 8 );
- luaL_pushresult( &b );
- } else {
- luaL_pushresult( &b ); /* close buffer */
- lua_pop( L, 1 );
- // remove bus userdata from table
- lua_rawgeti( L, LUA_REGISTRYINDEX, ow_bus_table_ref );
- lua_pushnil( L );
- lua_rawseti( L, -2, pin );
- // remove table from stack
- lua_pop( L, 1 );
- lua_pushnil( L );
- }
- return 1;
- }
- // uint8_t onewire_crc8(const uint8_t *addr, uint8_t len);
- // Lua: r = ow.crc8( buf )
- static int ow_crc8( lua_State *L )
- {
- size_t datalen;
- const char *pdata = luaL_checklstring( L, 1, &datalen );
- if(datalen > 255)
- return luaL_error( L, "wrong arg range" );
- lua_pushinteger( L, platform_onewire_crc8((uint8_t *)pdata, datalen) );
- return 1;
- }
- // 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 ow_check_crc16( lua_State *L )
- {
- size_t datalen;
- uint8_t inverted_crc[2];
- const char *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, platform_onewire_check_crc16((uint8_t *)pdata, datalen, inverted_crc, 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 ow_crc16( lua_State *L )
- {
- int stack = 0;
- size_t datalen;
- const char *pdata = luaL_checklstring( L, ++stack, &datalen );
- luaL_argcheck( L, datalen <= 65535, stack, "wrong arg range" );
- int crc = 0;
- if(lua_isnumber(L, ++stack))
- crc = lua_tointeger(L, stack);
- luaL_argcheck( L, crc >= 0 && crc <= 65535, stack, "wrong arg range" );
- lua_pushinteger( L, platform_onewire_crc16((uint8_t *)pdata, datalen, crc) );
- return 1;
- }
- static 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 ) },
- { LSTRKEY( "reset_search" ), LFUNCVAL( ow_reset_search ) },
- { LSTRKEY( "target_search" ), LFUNCVAL( ow_target_search ) },
- { LSTRKEY( "search" ), LFUNCVAL( ow_search ) },
- { LSTRKEY( "crc8" ), LFUNCVAL( ow_crc8 ) },
- { LSTRKEY( "check_crc16" ), LFUNCVAL( ow_check_crc16 ) },
- { LSTRKEY( "crc16" ), LFUNCVAL( ow_crc16 ) },
- { LNILKEY, LNILVAL }
- };
- int luaopen_ow( lua_State *L )
- {
- // create the table to store bus userdata for search operations
- lua_newtable( L );
- ow_bus_table_ref = luaL_ref( L, LUA_REGISTRYINDEX );
- return 0;
- }
- NODEMCU_MODULE(OW, "ow", ow_map, luaopen_ow);
|