Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
7886222e
Commit
7886222e
authored
Jul 14, 2015
by
devsaurus
Browse files
Merge remote-tracking branch 'upstream/dev' into dev
parents
93a762a7
239008d5
Changes
2
Show whitespace changes
Inline
Side-by-side
app/modules/wifi.c
View file @
7886222e
...
...
@@ -17,6 +17,13 @@
static
int
wifi_smart_succeed
=
LUA_NOREF
;
static
uint8
getap_output_format
=
0
;
//variables for wifi event monitor
static
sint32_t
wifi_status_cb_ref
[
6
]
=
{
LUA_NOREF
,
LUA_NOREF
,
LUA_NOREF
,
LUA_NOREF
,
LUA_NOREF
,
LUA_NOREF
};
static
volatile
os_timer_t
wifi_sta_status_timer
;
static
uint8
prev_wifi_status
=
0
;
#if defined( NODE_SMART_OLDSTYLE )
#else
static
lua_State
*
smart_L
=
NULL
;
...
...
@@ -852,6 +859,171 @@ static int wifi_station_status( lua_State* L )
return
1
;
}
/**
* wifi.sta.eventMonStop()
* Description:
* Stop wifi station event monitor
* Syntax:
* wifi.sta.eventMonStop()
* wifi.sta.eventMonStop("unreg all")
* Parameters:
* "unreg all": unregister all previously registered functions
* Returns:
* Nothing.
*
* Example:
--stop wifi event monitor
wifi.sta.eventMonStop()
--stop wifi event monitor and unregister all callbacks
wifi.sta.eventMonStop("unreg all")
*/
static
void
wifi_station_event_mon_stop
(
lua_State
*
L
)
{
os_timer_disarm
(
&
wifi_sta_status_timer
);
if
(
lua_isstring
(
L
,
1
))
{
if
(
c_strcmp
(
luaL_checkstring
(
L
,
1
),
"unreg all"
)
==
0
)
{
int
i
;
for
(
i
=
0
;
i
<
6
;
i
++
)
{
if
(
wifi_status_cb_ref
[
i
]
!=
LUA_NOREF
)
{
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
wifi_status_cb_ref
[
i
]);
wifi_status_cb_ref
[
i
]
=
LUA_NOREF
;
}
}
}
}
}
static
void
wifi_status_cb
(
int
arg
)
{
if
(
wifi_get_opmode
()
==
2
)
{
os_timer_disarm
(
&
wifi_sta_status_timer
);
return
;
}
int
wifi_status
=
wifi_station_get_connect_status
();
if
(
wifi_status
!=
prev_wifi_status
)
{
if
(
wifi_status_cb_ref
[
wifi_status
]
!=
LUA_NOREF
)
{
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
wifi_status_cb_ref
[
wifi_status
]);
lua_call
(
gL
,
0
,
0
);
}
}
prev_wifi_status
=
wifi_status
;
}
/**
* wifi.sta.eventMonReg()
* Description:
* Register callback for wifi station status event
* Syntax:
* wifi.sta.eventMonReg(wifi_status, function)
* wifi.sta.eventMonReg(wifi.status, "unreg") //unregister callback
* Parameters:
* wifi_status: wifi status you would like to set callback for
* Valid wifi states:
* wifi.STA_IDLE
* wifi.STA_CONNECTING
* wifi.STA_WRONGPWD
* wifi.STA_APNOTFOUND
* wifi.STA_FAIL
* wifi.STA_GOTIP
* function: function to perform
* "unreg": unregister previously registered function
* Returns:
* Nothing.
*
* Example:
--register callback
wifi.sta.eventMonReg(0, function() print("STATION_IDLE") end)
wifi.sta.eventMonReg(1, function() print("STATION_CONNECTING") end)
wifi.sta.eventMonReg(2, function() print("STATION_WRONG_PASSWORD") end)
wifi.sta.eventMonReg(3, function() print("STATION_NO_AP_FOUND") end)
wifi.sta.eventMonReg(4, function() print("STATION_CONNECT_FAIL") end)
wifi.sta.eventMonReg(5, function() print("STATION_GOT_IP") end)
--unregister callback
wifi.sta.eventMonReg(0, "unreg")
*/
static
int
wifi_station_event_mon_reg
(
lua_State
*
L
)
{
gL
=
L
;
uint8
id
=
luaL_checknumber
(
L
,
1
);
if
(
!
(
id
>=
0
&&
id
<=
5
))
{
return
luaL_error
(
L
,
"valid wifi status:0-5"
);
}
if
(
lua_type
(
L
,
2
)
==
LUA_TFUNCTION
||
lua_type
(
L
,
2
)
==
LUA_TLIGHTFUNCTION
)
{
lua_pushvalue
(
L
,
2
);
// copy argument (func) to the top of stack
if
(
wifi_status_cb_ref
[
id
]
!=
LUA_NOREF
)
{
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
wifi_status_cb_ref
[
id
]);
}
wifi_status_cb_ref
[
id
]
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
}
else
if
(
c_strcmp
(
luaL_checkstring
(
L
,
2
),
"unreg"
)
==
0
)
{
if
(
wifi_status_cb_ref
[
id
]
!=
LUA_NOREF
)
{
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
wifi_status_cb_ref
[
id
]);
wifi_status_cb_ref
[
id
]
=
LUA_NOREF
;
}
}
return
0
;
}
/**
* wifi.sta.eventMonStart()
* Description:
* Start wifi station event monitor
* Syntax:
* wifi.sta.eventMonStart()
* wifi.sta.eventMonStart(mS)
* Parameters:
* mS:interval between checks in milliseconds. defaults to 150 mS if not provided
* Returns:
* Nothing.
*
* Example:
--start wifi event monitor with default interval
wifi.sta.eventMonStart()
--start wifi event monitor with 100 mS interval
wifi.sta.eventMonStart(100)
*/
static
int
wifi_station_event_mon_start
(
lua_State
*
L
)
{
if
(
wifi_get_opmode
()
==
SOFTAP_MODE
)
{
return
luaL_error
(
L
,
"Can't monitor station in SOFTAP mode"
);
}
if
(
wifi_status_cb_ref
[
0
]
==
LUA_NOREF
&&
wifi_status_cb_ref
[
1
]
==
LUA_NOREF
&&
wifi_status_cb_ref
[
2
]
==
LUA_NOREF
&&
wifi_status_cb_ref
[
3
]
==
LUA_NOREF
&&
wifi_status_cb_ref
[
4
]
==
LUA_NOREF
&&
wifi_status_cb_ref
[
5
]
==
LUA_NOREF
)
{
return
luaL_error
(
L
,
"No callbacks defined"
);
}
uint32
ms
=
150
;
if
(
lua_isnumber
(
L
,
1
))
{
ms
=
luaL_checknumber
(
L
,
1
);
}
os_timer_disarm
(
&
wifi_sta_status_timer
);
os_timer_setfn
(
&
wifi_sta_status_timer
,
(
os_timer_func_t
*
)
wifi_status_cb
,
NULL
);
os_timer_arm
(
&
wifi_sta_status_timer
,
ms
,
1
);
return
0
;
}
// Lua: wifi.ap.getmac()
static
int
wifi_ap_getmac
(
lua_State
*
L
){
return
wifi_getmac
(
L
,
SOFTAP_IF
);
...
...
@@ -1112,6 +1284,9 @@ static const LUA_REG_TYPE wifi_station_map[] =
{
LSTRKEY
(
"setmac"
),
LFUNCVAL
(
wifi_station_setmac
)
},
{
LSTRKEY
(
"getap"
),
LFUNCVAL
(
wifi_station_listap
)
},
{
LSTRKEY
(
"status"
),
LFUNCVAL
(
wifi_station_status
)
},
{
LSTRKEY
(
"eventMonReg"
),
LFUNCVAL
(
wifi_station_event_mon_reg
)
},
{
LSTRKEY
(
"eventMonStart"
),
LFUNCVAL
(
wifi_station_event_mon_start
)
},
{
LSTRKEY
(
"eventMonStop"
),
LFUNCVAL
(
wifi_station_event_mon_stop
)
},
{
LNILKEY
,
LNILVAL
}
};
...
...
@@ -1174,12 +1349,12 @@ const LUA_REG_TYPE wifi_map[] =
{
LSTRKEY
(
"WPA2_PSK"
),
LNUMVAL
(
AUTH_WPA2_PSK
)
},
{
LSTRKEY
(
"WPA_WPA2_PSK"
),
LNUMVAL
(
AUTH_WPA_WPA2_PSK
)
},
//
{ LSTRKEY( "STA_IDLE" ), LNUMVAL( STATION_IDLE ) },
//
{ LSTRKEY( "STA_CONNECTING" ), LNUMVAL( STATION_CONNECTING ) },
//
{ LSTRKEY( "STA_WRONGPWD" ), LNUMVAL( STATION_WRONG_PASSWORD ) },
//
{ LSTRKEY( "STA_APNOTFOUND" ), LNUMVAL( STATION_NO_AP_FOUND ) },
//
{ LSTRKEY( "STA_FAIL" ), LNUMVAL( STATION_CONNECT_FAIL ) },
//
{ LSTRKEY( "STA_GOTIP" ), LNUMVAL( STATION_GOT_IP ) },
{
LSTRKEY
(
"STA_IDLE"
),
LNUMVAL
(
STATION_IDLE
)
},
{
LSTRKEY
(
"STA_CONNECTING"
),
LNUMVAL
(
STATION_CONNECTING
)
},
{
LSTRKEY
(
"STA_WRONGPWD"
),
LNUMVAL
(
STATION_WRONG_PASSWORD
)
},
{
LSTRKEY
(
"STA_APNOTFOUND"
),
LNUMVAL
(
STATION_NO_AP_FOUND
)
},
{
LSTRKEY
(
"STA_FAIL"
),
LNUMVAL
(
STATION_CONNECT_FAIL
)
},
{
LSTRKEY
(
"STA_GOTIP"
),
LNUMVAL
(
STATION_GOT_IP
)
},
{
LSTRKEY
(
"__metatable"
),
LROVAL
(
wifi_map
)
},
#endif
...
...
app/modules/ws2812.c
View file @
7886222e
...
...
@@ -5,27 +5,55 @@
#include "lrotable.h"
#include "c_stdlib.h"
#include "c_string.h"
/**
* All this code is mostly from http://www.esp8266.com/viewtopic.php?f=21&t=1143&sid=a620a377672cfe9f666d672398415fcb
* from user Markus Gritsch.
* I just put this code into its own module and pushed into a forked repo,
* to easily create a pull request. Thanks to Markus Gritsch for the code.
*/
// ----------------------------------------------------------------------------
// -- This WS2812 code must be compiled with -O2 to get the timing right. Read this:
// -- http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
// -- The ICACHE_FLASH_ATTR is there to trick the compiler and get the very first pulse width correct.
static
void
ICACHE_FLASH_ATTR
__attribute__
((
optimize
(
"O2"
)))
send_ws_0
(
uint8_t
gpio
){
uint8_t
i
;
i
=
4
;
while
(
i
--
)
GPIO_REG_WRITE
(
GPIO_OUT_W1TS_ADDRESS
,
1
<<
gpio
);
i
=
9
;
while
(
i
--
)
GPIO_REG_WRITE
(
GPIO_OUT_W1TC_ADDRESS
,
1
<<
gpio
);
#include "user_interface.h"
static
inline
uint32_t
_getCycleCount
(
void
)
{
uint32_t
cycles
;
__asm__
__volatile__
(
"rsr %0,ccount"
:
"=a"
(
cycles
));
return
cycles
;
}
static
void
ICACHE_FLASH_ATTR
__attribute__
((
optimize
(
"O2"
)))
send_ws_1
(
uint8_t
gpio
){
uint8_t
i
;
i
=
8
;
while
(
i
--
)
GPIO_REG_WRITE
(
GPIO_OUT_W1TS_ADDRESS
,
1
<<
gpio
);
i
=
6
;
while
(
i
--
)
GPIO_REG_WRITE
(
GPIO_OUT_W1TC_ADDRESS
,
1
<<
gpio
);
// This algorithm reads the cpu clock cycles to calculate the correct
// pulse widths. It works in both 80 and 160 MHz mode.
// The values for t0h, t1h, ttot have been tweaked and it doesn't get faster than this.
// The datasheet is confusing and one might think that a shorter pulse time can be achieved.
// The period has to be at least 1.25us, even if the datasheet says:
// T0H: 0.35 (+- 0.15) + T0L: 0.8 (+- 0.15), which is 0.85<->1.45 us.
// T1H: 0.70 (+- 0.15) + T1L: 0.6 (+- 0.15), which is 1.00<->1.60 us.
// Anything lower than 1.25us will glitch in the long run.
static
void
ICACHE_RAM_ATTR
ws2812_write
(
uint8_t
pin
,
uint8_t
*
pixels
,
uint32_t
length
)
{
uint8_t
*
p
,
*
end
,
pixel
,
mask
;
uint32_t
t
,
t0h
,
t1h
,
ttot
,
c
,
start_time
,
pin_mask
;
pin_mask
=
1
<<
pin
;
p
=
pixels
;
end
=
p
+
length
;
pixel
=
*
p
++
;
mask
=
0x80
;
start_time
=
0
;
t0h
=
(
1000
*
system_get_cpu_freq
())
/
3333
;
// 0.30us (spec=0.35 +- 0.15)
t1h
=
(
1000
*
system_get_cpu_freq
())
/
1666
;
// 0.60us (spec=0.70 +- 0.15)
ttot
=
(
1000
*
system_get_cpu_freq
())
/
800
;
// 1.25us (MUST be >= 1.25)
while
(
true
)
{
if
(
pixel
&
mask
)
{
t
=
t1h
;
}
else
{
t
=
t0h
;
}
while
(((
c
=
_getCycleCount
())
-
start_time
)
<
ttot
);
// Wait for the previous bit to finish
GPIO_REG_WRITE
(
GPIO_OUT_W1TS_ADDRESS
,
pin_mask
);
// Set pin high
start_time
=
c
;
// Save the start time
while
(((
c
=
_getCycleCount
())
-
start_time
)
<
t
);
// Wait for high time to finish
GPIO_REG_WRITE
(
GPIO_OUT_W1TC_ADDRESS
,
pin_mask
);
// Set pin low
if
(
!
(
mask
>>=
1
))
{
// Next bit/byte
if
(
p
>=
end
)
{
break
;
}
pixel
=
*
p
++
;
mask
=
0x80
;
}
}
}
// Lua: ws2812.writergb(pin, "string")
...
...
@@ -44,14 +72,11 @@ static int ICACHE_FLASH_ATTR ws2812_writergb(lua_State* L)
const
uint8_t
pin
=
luaL_checkinteger
(
L
,
1
);
size_t
length
;
const
char
*
rgb
=
luaL_checklstring
(
L
,
2
,
&
length
);
// dont modify lua-internal lstring - make a copy instead
char
*
buffer
=
(
char
*
)
c_malloc
(
length
);
c_memcpy
(
buffer
,
rgb
,
length
);
// Initialize the output pin:
platform_gpio_mode
(
pin
,
PLATFORM_GPIO_OUTPUT
,
PLATFORM_GPIO_FLOAT
);
platform_gpio_write
(
pin
,
0
);
// Ignore incomplete Byte triples at the end of buffer:
length
-=
length
%
3
;
...
...
@@ -64,19 +89,13 @@ static int ICACHE_FLASH_ATTR ws2812_writergb(lua_State* L)
buffer
[
i
+
1
]
=
r
;
}
//
Do not remove these:
os_delay_us
(
1
);
os_delay_us
(
1
);
//
Initialize the output pin and wait a bit
platform_gpio_mode
(
pin
,
PLATFORM_GPIO_OUTPUT
,
PLATFORM_GPIO_FLOAT
);
platform_gpio_write
(
pin
,
0
);
// Send the buffer
:
// Send the buffer
os_intr_lock
();
for
(
i
=
0
;
i
<
length
;
i
++
)
{
uint8_t
mask
=
0x80
;
while
(
mask
)
{
(
buffer
[
i
]
&
mask
)
?
send_ws_1
(
pin_num
[
pin
])
:
send_ws_0
(
pin_num
[
pin
]);
mask
>>=
1
;
}
}
ws2812_write
(
pin_num
[
pin
],
(
uint8_t
*
)
buffer
,
length
);
os_intr_unlock
();
c_free
(
buffer
);
...
...
@@ -96,20 +115,13 @@ static int ICACHE_FLASH_ATTR ws2812_writegrb(lua_State* L) {
size_t
length
;
const
char
*
buffer
=
luaL_checklstring
(
L
,
2
,
&
length
);
// Initialize the output pin
platform_gpio_mode
(
pin
,
PLATFORM_GPIO_OUTPUT
,
PLATFORM_GPIO_FLOAT
);
platform_gpio_write
(
pin
,
0
);
os_delay_us
(
10
);
// Send the buffer
os_intr_lock
();
const
char
*
const
end
=
buffer
+
length
;
while
(
buffer
!=
end
)
{
uint8_t
mask
=
0x80
;
while
(
mask
)
{
(
*
buffer
&
mask
)
?
send_ws_1
(
pin_num
[
pin
])
:
send_ws_0
(
pin_num
[
pin
]);
mask
>>=
1
;
}
++
buffer
;
}
ws2812_write
(
pin_num
[
pin
],
(
uint8_t
*
)
buffer
,
length
);
os_intr_unlock
();
return
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment