Commit 4911d2db authored by Arnim Läuger's avatar Arnim Läuger
Browse files

Merge pull request #1336 from nodemcu/dev

1.5.1 master drop
parents c8037568 2e109686
......@@ -806,6 +806,9 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
return nptr;
}
LUALIB_API void luaL_assertfail(const char *file, int line, const char *message) {
c_printf("ASSERT@%s(%d): %s\n", file, line, message);
}
static int panic (lua_State *L) {
(void)L; /* to avoid warnings */
......
......@@ -100,7 +100,7 @@ LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
const char *fname, int szhint);
LUALIB_API void luaL_assertfail(const char *file, int line, const char *message);
/*
......
......@@ -11,6 +11,8 @@
#include "c_string.h"
#include "flash_fs.h"
#include "user_version.h"
#include "driver/readline.h"
#include "driver/uart.h"
#define lua_c
......@@ -466,7 +468,7 @@ int lua_main (int argc, char **argv) {
void lua_handle_input (bool force)
{
if (force || readline (&gLoad))
if (gLoad.L && (force || readline (&gLoad)))
dojob (&gLoad);
}
......
......@@ -19,6 +19,7 @@
#include "c_stdarg.h"
#include "c_stddef.h"
#include "c_types.h"
#include <ctype.h>
#endif
#include "luaconf.h"
......
......@@ -632,7 +632,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
/*
@@ The luai_num* macros define the primitive operations over numbers.
*/
#if defined(LUA_CORE)
#if defined(LUA_CORE) || defined(LUA_LIB)
#ifdef LUA_CROSS_COMPILER
#include <math.h>
#else
......@@ -880,10 +880,6 @@ union luai_Cast { double l_d; long l_l; };
#define LUA_INTFRMLEN "l"
#define LUA_INTFRM_T long
#ifndef LUA_CROSS_COMPILER
typedef short int16_t;
typedef long int32_t;
#endif
#endif
......
......@@ -847,7 +847,7 @@ espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_info, ui
break;
case ESPCONN_UDP:
while(plist != NULL){
if (plist->pespconn && plist->pespconn->type == ESPCONN_UDP){
if (plist->pespconn == pespconn){
premot[pespconn->link_cnt].state = plist->pespconn->state;
premot[pespconn->link_cnt].remote_port = plist->pcommon.remote_port;
os_memcpy(premot[pespconn->link_cnt].remote_ip, plist->pcommon.remote_ip, 4);
......@@ -860,6 +860,8 @@ espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_info, ui
break;
}
*pcon_info = premot;
if (pespconn->link_cnt == 0)
return ESPCONN_ARG;
return ESPCONN_OK;
}
......@@ -954,12 +956,43 @@ espconn_disconnect(struct espconn *espconn)
/*protect for redisconnection*/
if (espconn->state == ESPCONN_CLOSE)
return ESPCONN_INPROGRESS;
espconn_tcp_disconnect(pnode);
espconn_tcp_disconnect(pnode,0); //1 force, 0 normal
return ESPCONN_OK;
} else
return ESPCONN_ARG;
}
/******************************************************************************
* FunctionName : espconn_abort
* Description : Forcely abort with host
* Parameters : espconn -- the espconn used to disconnect the connection
* Returns : none
*******************************************************************************/
sint8 ICACHE_FLASH_ATTR
espconn_abort(struct espconn *espconn)
{
espconn_msg *pnode = NULL;
bool value = false;
if (espconn == NULL) {
return ESPCONN_ARG;;
} else if (espconn ->type != ESPCONN_TCP)
return ESPCONN_ARG;
/*Find the node depend on the espconn message*/
value = espconn_find_connection(espconn, &pnode);
if (value){
/*protect for redisconnection*/
if (espconn->state == ESPCONN_CLOSE)
return ESPCONN_INPROGRESS;
espconn_tcp_disconnect(pnode,1); //1 force, 0 normal
return ESPCONN_OK;
} else
return ESPCONN_ARG;
}
/******************************************************************************
* FunctionName : espconn_get_packet_info
* Description : get the packet info with host
......@@ -1215,7 +1248,7 @@ espconn_port(void)
static uint32 randnum = 0;
do {
port = system_get_time();
port = os_random();
if (port < 0) {
port = os_random() - port;
......
......@@ -38,12 +38,12 @@ os_event_t espconn_TaskQueue[espconn_TaskQueueLen];
static err_t
espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static void
espconn_client_close(void *arg, struct tcp_pcb *pcb);
espconn_client_close(void *arg, struct tcp_pcb *pcb,u8 type);
static err_t
espconn_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
static void
espconn_server_close(void *arg, struct tcp_pcb *pcb);
espconn_server_close(void *arg, struct tcp_pcb *pcb,u8 type);
///////////////////////////////common function/////////////////////////////////
/******************************************************************************
......@@ -495,14 +495,14 @@ espconn_tcp_sent(void *arg, uint8 *psent, uint16 length)
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR espconn_tcp_disconnect(espconn_msg *pdiscon)
void ICACHE_FLASH_ATTR espconn_tcp_disconnect(espconn_msg *pdiscon,u8 type)
{
if (pdiscon != NULL){
/*disconnect with the host by send the FIN frame*/
if (pdiscon->preverse != NULL)
espconn_server_close(pdiscon, pdiscon->pcommon.pcb);
espconn_server_close(pdiscon, pdiscon->pcommon.pcb,type);
else
espconn_client_close(pdiscon, pdiscon->pcommon.pcb);
espconn_client_close(pdiscon, pdiscon->pcommon.pcb,type);
} else{
espconn_printf("espconn_tcp_disconnect err.\n");
}
......@@ -517,7 +517,7 @@ void ICACHE_FLASH_ATTR espconn_tcp_disconnect(espconn_msg *pdiscon)
* Returns : none
*******************************************************************************/
static void ICACHE_FLASH_ATTR
espconn_client_close(void *arg, struct tcp_pcb *pcb)
espconn_client_close(void *arg, struct tcp_pcb *pcb, u8 type)
{
err_t err;
espconn_msg *pclose = arg;
......@@ -525,7 +525,11 @@ espconn_client_close(void *arg, struct tcp_pcb *pcb)
pclose->pcommon.pcb = pcb;
/*avoid recalling the disconnect function*/
tcp_recv(pcb, NULL);
err = tcp_close(pcb);
if(type == 0)
err = tcp_close(pcb);
else
{tcp_abort(pcb); err = ERR_OK;}
if (err != ERR_OK) {
/* closing failed, try again later */
......@@ -647,7 +651,7 @@ espconn_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
}
if (err == ERR_OK && p == NULL) {
espconn_client_close(precv_cb, pcb);
espconn_client_close(precv_cb, pcb,0);
}
return ERR_OK;
......@@ -943,7 +947,7 @@ espconn_tcp_client(struct espconn *espconn)
* Returns : none
*******************************************************************************/
static void ICACHE_FLASH_ATTR
espconn_server_close(void *arg, struct tcp_pcb *pcb)
espconn_server_close(void *arg, struct tcp_pcb *pcb,u8 type)
{
err_t err;
espconn_msg *psclose = arg;
......@@ -951,7 +955,11 @@ espconn_server_close(void *arg, struct tcp_pcb *pcb)
psclose->pcommon.pcb = pcb;
/*avoid recalling the disconnect function*/
tcp_recv(pcb, NULL);
err = tcp_close(pcb);
if(type ==0)
err = tcp_close(pcb);
else
{tcp_abort(pcb); err = ERR_OK;}
if (err != ERR_OK) {
/* closing failed, try again later */
......@@ -1024,7 +1032,7 @@ espconn_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
pbuf_free(p);
}
espconn_server_close(precv_cb, pcb);
espconn_server_close(precv_cb, pcb,0);
}
return ERR_OK;
......@@ -1086,7 +1094,7 @@ espconn_server_poll(void *arg, struct tcp_pcb *pcb)
if (pspoll_cb->pcommon.timeout != 0){/*no data sent in one active connection's set timeout, close.*/
if (pspoll_cb->pcommon.recv_check >= pspoll_cb->pcommon.timeout) {
pspoll_cb->pcommon.recv_check = 0;
espconn_server_close(pspoll_cb, pcb);
espconn_server_close(pspoll_cb, pcb,0);
}
} else {
espconn_msg *ptime_msg = pserver_list;
......@@ -1095,7 +1103,7 @@ espconn_server_poll(void *arg, struct tcp_pcb *pcb)
if (ptime_msg->pcommon.timeout != 0){/*no data sent in server's set timeout, close.*/
if (pspoll_cb->pcommon.recv_check >= ptime_msg->pcommon.timeout){
pspoll_cb->pcommon.recv_check = 0;
espconn_server_close(pspoll_cb, pcb);
espconn_server_close(pspoll_cb, pcb,0);
}
} else {/*don't close for ever*/
pspoll_cb->pcommon.recv_check = 0;
......@@ -1106,7 +1114,7 @@ espconn_server_poll(void *arg, struct tcp_pcb *pcb)
}
}
} else {
espconn_server_close(pspoll_cb, pcb);
espconn_server_close(pspoll_cb, pcb,0);
}
return ERR_OK;
......
......@@ -301,7 +301,7 @@ espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
if (wifi_get_opmode() != 1) {
wifi_get_ip_info(1, &ipconfig);
if (!ip_addr_netcmp((struct ip_addr *)precv->pespconn->proto.udp->remote_ip, &ipconfig.ip, &ipconfig.netmask)) {
if (!ip_addr_netcmp(addr, &ipconfig.ip, &ipconfig.netmask)) {
wifi_get_ip_info(0, &ipconfig);
}
} else {
......
......@@ -193,8 +193,8 @@ static char host_name[MDNS_NAME_LENGTH];
static char service_name[MDNS_NAME_LENGTH];
static char server_name[MDNS_NAME_LENGTH];
//static char puck_datasheet[PUCK_DATASHEET_SIZE];
static struct udp_pcb *mdns_pcb;
static struct udp_pcb *mdns_pcb = NULL;
static struct mdns_info * ms_info = NULL;
static struct ip_addr multicast_addr;
static struct ip_addr host_addr;
static uint8 register_flag = 0;
......@@ -887,7 +887,7 @@ mdns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
}
goto memerr2;
memerr2:
mem_free(mdns_payload);
os_memset(mdns_payload , 0 ,DNS_MSG_SIZE);
memerr1:
/* free pbuf */
pbuf_free(p);
......@@ -900,8 +900,12 @@ mdns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
void ICACHE_FLASH_ATTR
mdns_close(void)
{
if (mdns_pcb != NULL)
if (mdns_pcb != NULL && ms_info != NULL)
udp_remove(mdns_pcb);
os_free(ms_info);
mdns_pcb = NULL;
ms_info = NULL;
}
void ICACHE_FLASH_ATTR
......@@ -1030,26 +1034,33 @@ mdns_init(struct mdns_info *info) {
multicast_addr.addr = DNS_MULTICAST_ADDRESS;
struct ip_addr ap_host_addr;
struct ip_info ipconfig;
if (info->ipAddr == 0) {
ms_info = (struct mdns_info *)os_zalloc(sizeof(struct mdns_info));
if (ms_info != NULL) {
os_memcpy(ms_info,info,sizeof(struct mdns_info));
} else {
os_printf("ms_info alloc failed\n");
return;
}
if (ms_info->ipAddr == 0) {
os_printf("mdns ip error!\n ");
return;
}
host_addr.addr = info->ipAddr ;
host_addr.addr = ms_info->ipAddr ;
LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n"));
//get the datasheet from PUCK
mdns_set_hostname(info->host_name);
mdns_set_servername(info->server_name);
mdns_set_name(info->host_name);
mdns_set_hostname(ms_info->host_name);
mdns_set_servername(ms_info->server_name);
mdns_set_name(ms_info->host_name);
// get the host name as instrumentName_serialNumber for MDNS
// set the name of the service, the same as host name
os_printf("host_name = %s\n", host_name);
os_printf("server_name = %s\n", PUCK_SERVICE);
if (info->server_port == 0)
if (ms_info->server_port == 0)
{
PUCK_PORT = 80;
} else {
PUCK_PORT = info->server_port;
PUCK_PORT = ms_info->server_port;
}
/* initialize mDNS */
......@@ -1080,14 +1091,14 @@ mdns_init(struct mdns_info *info) {
/*loopback function for the multicast(224.0.0.251) messages received at port 5353*/
// mdns_enable();
udp_recv(mdns_pcb, mdns_recv, info);
udp_recv(mdns_pcb, mdns_recv, ms_info);
mdns_flag = 1;
/*
* Register the name of the instrument
*/
os_timer_disarm(&mdns_timer);
os_timer_setfn(&mdns_timer, (os_timer_func_t *)mdns_reg,info);
os_timer_setfn(&mdns_timer, (os_timer_func_t *)mdns_reg,ms_info);
os_timer_arm(&mdns_timer, 1000, 1);
}
}
......
......@@ -632,15 +632,19 @@ tcp_new_port(void)
int i;
struct tcp_pcb *pcb;
#ifndef TCP_LOCAL_PORT_RANGE_START
#define TCP_LOCAL_PORT_RANGE_START 4096
#define TCP_LOCAL_PORT_RANGE_START 1024
#define TCP_LOCAL_PORT_RANGE_END 0x7fff
#endif
static u16_t port __attribute__((section(".port"))) = TCP_LOCAL_PORT_RANGE_START;
static u16_t port = TCP_LOCAL_PORT_RANGE_START;
again:
if (++port >= TCP_LOCAL_PORT_RANGE_END) {
port = TCP_LOCAL_PORT_RANGE_START;
}
// if (++port >= TCP_LOCAL_PORT_RANGE_END) {
// port = TCP_LOCAL_PORT_RANGE_START;
// }
port = os_random();
port %= TCP_LOCAL_PORT_RANGE_END;
if (port < TCP_LOCAL_PORT_RANGE_START)
port += TCP_LOCAL_PORT_RANGE_START;
/* Check all PCB lists. */
for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
......
......@@ -15,6 +15,8 @@ ifndef PDIR
GEN_LIBS = libmodules.a
endif
STD_CFLAGS=-std=gnu11 -Wimplicit
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
......@@ -45,11 +47,11 @@ INCLUDES += -I ../u8glib
INCLUDES += -I ../ucglib
INCLUDES += -I ../lua
INCLUDES += -I ../platform
INCLUDES += -I ../wofs
INCLUDES += -I ../spiffs
INCLUDES += -I ../smart
INCLUDES += -I ../cjson
INCLUDES += -I ../dhtlib
INCLUDES += -I ../http
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......@@ -24,10 +24,49 @@ static int adc_readvdd33( lua_State* L )
return 1;
}
// Lua: adc.force_init_mode(x)
static int adc_init107( lua_State *L )
{
uint8_t byte107 = luaL_checkinteger (L, 1);
uint32 init_sector = flash_safe_get_sec_num () - 4;
// Note 32bit alignment so we can safely cast to uint32 for the flash api
char init_data[SPI_FLASH_SEC_SIZE] __attribute__((aligned(4)));
if (SPI_FLASH_RESULT_OK != flash_safe_read (
init_sector * SPI_FLASH_SEC_SIZE,
(uint32 *)init_data, sizeof(init_data)))
return luaL_error(L, "flash read error");
// If it's already the correct value, we don't need to force it
if (init_data[107] == byte107)
{
lua_pushboolean (L, false);
return 1;
}
// Nope, it differs, we need to rewrite it
init_data[107] = byte107;
if (SPI_FLASH_RESULT_OK != flash_safe_erase_sector (init_sector))
return luaL_error(L, "flash erase error");
if (SPI_FLASH_RESULT_OK != flash_safe_write (
init_sector * SPI_FLASH_SEC_SIZE,
(uint32 *)init_data, sizeof(init_data)))
return luaL_error(L, "flash write error");
lua_pushboolean (L, true);
return 1;
}
// Module function map
static const LUA_REG_TYPE adc_map[] = {
{ LSTRKEY( "read" ), LFUNCVAL( adc_sample ) },
{ LSTRKEY( "readvdd33" ), LFUNCVAL( adc_readvdd33) },
{ LSTRKEY( "readvdd33" ), LFUNCVAL( adc_readvdd33 ) },
{ LSTRKEY( "force_init_mode" ), LFUNCVAL( adc_init107 ) },
{ LSTRKEY( "INIT_ADC" ), LNUMVAL( 0x00 ) },
{ LSTRKEY( "INIT_VDD33" ),LNUMVAL( 0xff ) },
{ LNILKEY, LNILVAL }
};
......
/*
* app/modules/am2320.c
*
* Copyright (c) 2016 Henk Vergonet <Henk.Vergonet@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "module.h"
#include "lauxlib.h"
#include "platform.h"
#include "lwip/udp.h"
#include <errno.h>
static const uint32_t am2320_i2c_id = 0;
static const uint8_t am2320_i2c_addr = 0xb8 >> 1;
static uint16_t crc16(uint8_t *ptr, unsigned int len)
{
uint16_t crc =0xFFFF;
uint8_t i;
while(len--) {
crc ^= *ptr++;
for(i=0;i<8;i++) {
if(crc & 0x01) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
/* make sure buf has lenght len+2 in order to accommodate for extra bytes */
static int _read(uint32_t id, void *buf, uint8_t len, uint8_t off)
{
int i;
uint8_t *b = (uint8_t *)buf;
uint16_t crc;
// step 1: Wake sensor
platform_i2c_send_start(id);
platform_i2c_send_address(id, am2320_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
os_delay_us(800);
platform_i2c_send_stop(id);
// step 2: Send read command
platform_i2c_send_start(id);
platform_i2c_send_address(id, am2320_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(id, 0x03);
platform_i2c_send_byte(id, off);
platform_i2c_send_byte(id, len);
platform_i2c_send_stop(id);
// step 3: Read the data
os_delay_us(1500);
platform_i2c_send_start(id);
platform_i2c_send_address(id, am2320_i2c_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
os_delay_us(30);
for(i=0; i<len+2; i++)
b[i] = platform_i2c_recv_byte(id,1);
crc = platform_i2c_recv_byte(id,1);
crc |= platform_i2c_recv_byte(id,0) << 8;
platform_i2c_send_stop(id);
if(b[0] != 0x3 || b[1] != len)
return -EIO;
if(crc != crc16(b,len+2))
return -EIO;
return 0;
}
static int am2320_init(lua_State* L)
{
uint32_t sda;
uint32_t scl;
int ret;
struct {
uint8_t cmd;
uint8_t len;
uint16_t model;
uint8_t version;
uint32_t id;
} nfo;
if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2)) {
return luaL_error(L, "wrong arg range");
}
sda = luaL_checkinteger(L, 1);
scl = luaL_checkinteger(L, 2);
if (scl == 0 || sda == 0) {
return luaL_error(L, "no i2c for D0");
}
platform_i2c_setup(am2320_i2c_id, sda, scl, PLATFORM_I2C_SPEED_SLOW);
os_delay_us(1500); // give some time to settle things down
ret = _read(am2320_i2c_id, &nfo, sizeof(nfo)-2, 0x08);
if(ret)
return luaL_error(L, "transmission error");
lua_pushinteger(L, ntohs(nfo.model));
lua_pushinteger(L, nfo.version);
lua_pushinteger(L, ntohl(nfo.id));
return 3;
}
static int am2320_read(lua_State* L)
{
int ret;
struct {
uint8_t cmd;
uint8_t len;
uint16_t rh;
uint16_t temp;
} nfo;
ret = _read(am2320_i2c_id, &nfo, sizeof(nfo)-2, 0x00);
if(ret)
return luaL_error(L, "transmission error");
ret = ntohs(nfo.temp);
if(ret & 0x8000)
ret = -(ret & 0x7fff);
lua_pushinteger(L, ntohs(nfo.rh));
lua_pushinteger(L, ret);
return 2;
}
static const LUA_REG_TYPE am2320_map[] = {
{ LSTRKEY( "read" ), LFUNCVAL( am2320_read )},
{ LSTRKEY( "init" ), LFUNCVAL( am2320_init )},
{ LNILKEY, LNILVAL}
};
NODEMCU_MODULE(AM2320, "am2320", am2320_map, NULL);
#include "c_stdlib.h"
#include "c_string.h"
#include "lualib.h"
#include "lauxlib.h"
#include "lrotable.h"
#include "module.h"
#include "platform.h"
#include "user_interface.h"
#define NOP asm volatile(" nop \n\t")
static inline void apa102_send_byte(uint32_t data_pin, uint32_t clock_pin, uint8_t byte) {
int i;
for (i = 0; i < 8; i++) {
if (byte & 0x80) {
GPIO_OUTPUT_SET(data_pin, PLATFORM_GPIO_HIGH); // Set pin high
} else {
GPIO_OUTPUT_SET(data_pin, PLATFORM_GPIO_LOW); // Set pin low
}
GPIO_OUTPUT_SET(clock_pin, PLATFORM_GPIO_HIGH); // Set pin high
byte <<= 1;
NOP;
NOP;
GPIO_OUTPUT_SET(clock_pin, PLATFORM_GPIO_LOW); // Set pin low
NOP;
NOP;
}
}
static void apa102_send_buffer(uint32_t data_pin, uint32_t clock_pin, uint32_t *buf, uint32_t nbr_frames) {
int i;
// Send 32-bit Start Frame that's all 0x00
apa102_send_byte(data_pin, clock_pin, 0x00);
apa102_send_byte(data_pin, clock_pin, 0x00);
apa102_send_byte(data_pin, clock_pin, 0x00);
apa102_send_byte(data_pin, clock_pin, 0x00);
// Send 32-bit LED Frames
for (i = 0; i < nbr_frames; i++) {
uint8_t *byte = (uint8_t *) buf++;
// Set the first 3 bits of that byte to 1.
// This makes the lua interface easier to use since you
// don't have to worry about creating invalid LED Frames.
byte[0] |= 0xE0;
apa102_send_byte(data_pin, clock_pin, byte[0]);
apa102_send_byte(data_pin, clock_pin, byte[1]);
apa102_send_byte(data_pin, clock_pin, byte[2]);
apa102_send_byte(data_pin, clock_pin, byte[3]);
}
// Send 32-bit End Frames
uint32_t required_postamble_frames = (nbr_frames + 1) / 2;
for (i = 0; i < required_postamble_frames; i++) {
apa102_send_byte(data_pin, clock_pin, 0xFF);
apa102_send_byte(data_pin, clock_pin, 0xFF);
apa102_send_byte(data_pin, clock_pin, 0xFF);
apa102_send_byte(data_pin, clock_pin, 0xFF);
}
}
// Lua: apa102.write(data_pin, clock_pin, "string")
// Byte quads in the string are interpreted as (brightness, B, G, R) values.
// Only the first 5 bits of the brightness value is actually used (0-31).
// This function does not corrupt your buffer.
//
// apa102.write(1, 3, string.char(31, 0, 255, 0)) uses GPIO5 for DATA and GPIO0 for CLOCK and sets the first LED green, with the brightness 31 (out of 0-32)
// apa102.write(5, 6, string.char(255, 0, 0, 255):rep(10)) uses GPIO14 for DATA and GPIO12 for CLOCK and sets ten LED to red, with the brightness 31 (out of 0-32).
// Brightness values are clamped to 0-31.
static int apa102_write(lua_State* L) {
uint8_t data_pin = luaL_checkinteger(L, 1);
MOD_CHECK_ID(gpio, data_pin);
uint32_t alt_data_pin = pin_num[data_pin];
uint8_t clock_pin = luaL_checkinteger(L, 2);
MOD_CHECK_ID(gpio, clock_pin);
uint32_t alt_clock_pin = pin_num[clock_pin];
size_t buf_len;
const char *buf = luaL_checklstring(L, 3, &buf_len);
uint32_t nbr_frames = buf_len / 4;
if (nbr_frames > 100000) {
return luaL_error(L, "The supplied buffer is too long, and might cause the callback watchdog to bark.");
}
// Initialize the output pins
platform_gpio_mode(data_pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT);
GPIO_OUTPUT_SET(alt_data_pin, PLATFORM_GPIO_HIGH); // Set pin high
platform_gpio_mode(clock_pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT);
GPIO_OUTPUT_SET(alt_clock_pin, PLATFORM_GPIO_LOW); // Set pin low
// Send the buffers
apa102_send_buffer(alt_data_pin, alt_clock_pin, (uint32_t *) buf, (uint32_t) nbr_frames);
return 0;
}
const LUA_REG_TYPE apa102_map[] =
{
{ LSTRKEY( "write" ), LFUNCVAL( apa102_write )},
{ LNILKEY, LNILVAL}
};
LUALIB_API int luaopen_apa102(lua_State *L) {
LREGISTER(L, "apa102", apa102_map);
return 0;
}
NODEMCU_MODULE(APA102, "apa102", apa102_map, luaopen_apa102);
This diff is collapsed.
This diff is collapsed.
......@@ -43,6 +43,7 @@
#include "c_limits.h"
#include "lauxlib.h"
#include "flash_api.h"
#include "ctype.h"
#include "strbuf.h"
#include "cjson_mem.h"
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment