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
34e486fb
Commit
34e486fb
authored
Apr 29, 2017
by
zelll
Committed by
devsaurus
Oct 13, 2018
Browse files
i2s extension
parent
166474b9
Changes
4
Hide whitespace changes
Inline
Side-by-side
components/modules/Kconfig
View file @
34e486fb
...
...
@@ -105,6 +105,12 @@ config LUA_MODULE_I2C
help
Includes the I2C module (recommended).
config LUA_MODULE_I2S
bool "I2S module"
default "n"
help
Includes the I2S module.
config LUA_MODULE_LEDC
bool "LEDC module"
default "n"
...
...
components/modules/i2s.c
0 → 100644
View file @
34e486fb
// Module for interfacing with i2s hardware
#include "module.h"
#include "lauxlib.h"
#include "lmem.h"
#include "platform.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_task.h"
#include "task/task.h"
#include "driver/i2s.h"
#define MAX_I2C_NUM 2
#define I2S_CHECK_ID(id) if(id >= MAX_I2C_NUM) luaL_error( L, "i2s not exists" )
typedef
struct
{
xTaskHandle
taskHandle
;
QueueHandle_t
*
event_queue
;
int
event_cb
;
}
i2s_status_t
;
typedef
struct
{
i2s_event_t
event
;
i2s_status_t
*
status
;
}
i2s_event_post_type
;
static
task_handle_t
i2s_event_task_id
;
static
i2s_status_t
i2s_status
[
MAX_I2C_NUM
];
// LUA
static
void
i2s_event_task
(
task_param_t
param
,
task_prio_t
prio
)
{
i2s_event_post_type
*
post
=
(
i2s_event_post_type
*
)
param
;
lua_State
*
L
=
lua_getstate
();
int
event_cb
=
post
->
status
->
event_cb
;
if
(
event_cb
==
LUA_NOREF
)
{
free
(
post
);
return
;
}
lua_rawgeti
(
L
,
LUA_REGISTRYINDEX
,
event_cb
);
if
(
post
->
event
.
type
==
I2S_EVENT_TX_DONE
)
lua_pushstring
(
L
,
"sent"
);
else
if
(
post
->
event
.
type
==
I2S_EVENT_RX_DONE
)
lua_pushstring
(
L
,
"data"
);
else
lua_pushstring
(
L
,
"error"
);
lua_pushinteger
(
L
,
post
->
event
.
size
);
free
(
post
);
lua_call
(
L
,
2
,
0
);
}
// RTOS
static
void
task_I2S
(
void
*
pvParameters
){
i2s_status_t
*
is
=
(
i2s_status_t
*
)
pvParameters
;
i2s_event_post_type
*
post
=
NULL
;
for
(;;){
if
(
post
==
NULL
)
{
post
=
(
i2s_event_post_type
*
)
malloc
(
sizeof
(
i2s_event_post_type
)
);
post
->
status
=
is
;
}
if
(
xQueueReceive
(
is
->
event_queue
,
&
(
post
->
event
),
3
*
portTICK_PERIOD_MS
)
==
pdTRUE
){
task_post_high
(
i2s_event_task_id
,
(
task_param_t
)
post
);
post
=
NULL
;
}
}
}
// Lua: start( i2s_id, {}, callback )
static
int
node_i2s_start
(
lua_State
*
L
)
{
int
i2s_id
=
luaL_checkinteger
(
L
,
1
);
I2S_CHECK_ID
(
i2s_id
);
luaL_checkanytable
(
L
,
2
);
i2s_config_t
i2s_config
;
i2s_pin_config_t
pin_config
;
lua_getfield
(
L
,
2
,
"mode"
);
i2s_config
.
mode
=
luaL_optint
(
L
,
-
1
,
I2S_MODE_MASTER
|
I2S_MODE_TX
);
lua_getfield
(
L
,
2
,
"rate"
);
i2s_config
.
sample_rate
=
luaL_optint
(
L
,
-
1
,
44100
);
lua_getfield
(
L
,
2
,
"bits"
);
i2s_config
.
bits_per_sample
=
16
;
lua_getfield
(
L
,
2
,
"channel"
);
i2s_config
.
channel_format
=
luaL_optint
(
L
,
-
1
,
I2S_CHANNEL_FMT_RIGHT_LEFT
);
lua_getfield
(
L
,
2
,
"format"
);
i2s_config
.
communication_format
=
luaL_optint
(
L
,
-
1
,
I2S_COMM_FORMAT_I2S
|
I2S_COMM_FORMAT_I2S_MSB
);
lua_getfield
(
L
,
2
,
"buffer_count"
);
i2s_config
.
dma_buf_count
=
luaL_optint
(
L
,
-
1
,
2
);
lua_getfield
(
L
,
2
,
"buffer_len"
);
i2s_config
.
dma_buf_len
=
luaL_optint
(
L
,
-
1
,
i2s_config
.
sample_rate
/
100
);
i2s_config
.
intr_alloc_flags
=
ESP_INTR_FLAG_LEVEL2
;
lua_getfield
(
L
,
2
,
"bck_pin"
);
pin_config
.
bck_io_num
=
luaL_optint
(
L
,
-
1
,
I2S_PIN_NO_CHANGE
);
lua_getfield
(
L
,
2
,
"ws_pin"
);
pin_config
.
ws_io_num
=
luaL_optint
(
L
,
-
1
,
I2S_PIN_NO_CHANGE
);
lua_getfield
(
L
,
2
,
"data_out_pin"
);
pin_config
.
data_out_num
=
luaL_optint
(
L
,
-
1
,
I2S_PIN_NO_CHANGE
);
lua_getfield
(
L
,
2
,
"data_in_pin"
);
pin_config
.
data_in_num
=
luaL_optint
(
L
,
-
1
,
I2S_PIN_NO_CHANGE
);
lua_settop
(
L
,
3
);
i2s_status
[
i2s_id
].
event_cb
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
i2s_driver_install
(
i2s_id
,
&
i2s_config
,
i2s_config
.
dma_buf_count
,
&
i2s_status
[
i2s_id
].
event_queue
);
i2s_set_pin
(
i2s_id
,
&
pin_config
);
char
pcName
[
5
];
snprintf
(
pcName
,
5
,
"I2S%d"
,
i2s_id
);
pcName
[
4
]
=
'\0'
;
xTaskCreate
(
&
task_I2S
,
pcName
,
2048
,
&
i2s_status
[
i2s_id
],
ESP_TASK_MAIN_PRIO
+
1
,
&
i2s_status
[
i2s_id
].
taskHandle
);
return
0
;
}
// Lua: stop( i2s_id )
static
int
node_i2s_stop
(
lua_State
*
L
)
{
int
i2s_id
=
luaL_checkinteger
(
L
,
1
);
I2S_CHECK_ID
(
i2s_id
);
i2s_driver_uninstall
(
i2s_id
);
i2s_status
[
i2s_id
].
event_queue
=
NULL
;
if
(
i2s_status
[
i2s_id
].
taskHandle
!=
NULL
)
{
vTaskDelete
(
i2s_status
[
i2s_id
].
taskHandle
);
i2s_status
[
i2s_id
].
taskHandle
=
NULL
;
}
if
(
i2s_status
[
i2s_id
].
event_cb
!=
LUA_NOREF
)
{
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
i2s_status
[
i2s_id
].
event_cb
);
i2s_status
[
i2s_id
].
event_cb
=
LUA_NOREF
;
}
return
0
;
}
// Lua: read( i2s_id, bytes[, wait_ms] )
static
int
node_i2s_read
(
lua_State
*
L
)
{
int
i2s_id
=
luaL_checkinteger
(
L
,
1
);
I2S_CHECK_ID
(
i2s_id
);
size_t
bytes
=
luaL_checkinteger
(
L
,
2
);
int
wait_ms
=
luaL_optint
(
L
,
3
,
0
);
char
*
data
=
luaM_malloc
(
L
,
bytes
);
size_t
read
=
i2s_read_bytes
(
i2s_id
,
data
,
bytes
,
wait_ms
/
portTICK_RATE_MS
);
lua_pushlstring
(
L
,
data
,
read
);
luaM_free
(
L
,
data
);
return
1
;
}
// Lua: write( i2s_id, data[, wait_ms] )
static
int
node_i2s_write
(
lua_State
*
L
)
{
int
i2s_id
=
luaL_checkinteger
(
L
,
1
);
I2S_CHECK_ID
(
i2s_id
);
size_t
bytes
;
char
*
data
;
if
(
lua_istable
(
L
,
2
)
)
{
bytes
=
lua_objlen
(
L
,
2
);
data
=
(
char
*
)
luaM_malloc
(
L
,
bytes
);
for
(
int
i
=
0
;
i
<
bytes
;
i
++
)
{
lua_rawgeti
(
L
,
2
,
i
+
1
);
data
[
i
]
=
(
uint8_t
)
luaL_checkinteger
(
L
,
-
1
);
}
}
else
{
data
=
(
char
*
)
luaL_checklstring
(
L
,
2
,
&
bytes
);
}
int
wait_ms
=
luaL_optint
(
L
,
3
,
0
);
size_t
wrote
=
i2s_write_bytes
(
i2s_id
,
data
,
bytes
,
wait_ms
/
portTICK_RATE_MS
);
if
(
lua_istable
(
L
,
2
)
)
luaM_free
(
L
,
data
);
lua_pushinteger
(
L
,
(
lua_Integer
)
wrote
);
return
1
;
}
// Module function map
static
const
LUA_REG_TYPE
i2s_map
[]
=
{
{
LSTRKEY
(
"start"
),
LFUNCVAL
(
node_i2s_start
)
},
{
LSTRKEY
(
"stop"
),
LFUNCVAL
(
node_i2s_stop
)
},
{
LSTRKEY
(
"read"
),
LFUNCVAL
(
node_i2s_read
)
},
{
LSTRKEY
(
"write"
),
LFUNCVAL
(
node_i2s_write
)
},
{
LSTRKEY
(
"FORMAT_I2S"
),
LNUMVAL
(
I2S_COMM_FORMAT_I2S
)
},
{
LSTRKEY
(
"FORMAT_I2S_MSB"
),
LNUMVAL
(
I2S_COMM_FORMAT_I2S_MSB
)
},
{
LSTRKEY
(
"FORMAT_I2S_LSB"
),
LNUMVAL
(
I2S_COMM_FORMAT_I2S_LSB
)
},
{
LSTRKEY
(
"FORMAT_PCM"
),
LNUMVAL
(
I2S_COMM_FORMAT_PCM
)
},
{
LSTRKEY
(
"FORMAT_PCM_SHORT"
),
LNUMVAL
(
I2S_COMM_FORMAT_PCM_SHORT
)
},
{
LSTRKEY
(
"FORMAT_PCM_LONG"
),
LNUMVAL
(
I2S_COMM_FORMAT_PCM_LONG
)
},
{
LSTRKEY
(
"CHANNEL_RIGHT_LEFT"
),
LNUMVAL
(
I2S_CHANNEL_FMT_RIGHT_LEFT
)
},
{
LSTRKEY
(
"CHANNEL_ALL_LEFT"
),
LNUMVAL
(
I2S_CHANNEL_FMT_ALL_LEFT
)
},
{
LSTRKEY
(
"CHANNEL_ONLY_LEFT"
),
LNUMVAL
(
I2S_CHANNEL_FMT_ONLY_LEFT
)
},
{
LSTRKEY
(
"CHANNEL_ALL_RIGHT"
),
LNUMVAL
(
I2S_CHANNEL_FMT_ALL_RIGHT
)
},
{
LSTRKEY
(
"CHANNEL_ONLY_RIGHT"
),
LNUMVAL
(
I2S_CHANNEL_FMT_ONLY_RIGHT
)
},
{
LSTRKEY
(
"MODE_MASTER"
),
LNUMVAL
(
I2S_MODE_MASTER
)
},
{
LSTRKEY
(
"MODE_SLAVE"
),
LNUMVAL
(
I2S_MODE_SLAVE
)
},
{
LSTRKEY
(
"MODE_TX"
),
LNUMVAL
(
I2S_MODE_TX
)
},
{
LSTRKEY
(
"MODE_RX"
),
LNUMVAL
(
I2S_MODE_RX
)
},
{
LSTRKEY
(
"MODE_DAC_BUILT_IN"
),
LNUMVAL
(
I2S_MODE_DAC_BUILT_IN
)
},
{
LNILKEY
,
LNILVAL
}
};
int
luaopen_i2s
(
lua_State
*
L
)
{
for
(
int
i2s_id
=
0
;
i2s_id
<
MAX_I2C_NUM
;
i2s_id
++
)
{
i2s_status
[
i2s_id
].
event_queue
=
NULL
;
i2s_status
[
i2s_id
].
taskHandle
=
NULL
;
i2s_status
[
i2s_id
].
event_cb
=
LUA_NOREF
;
}
i2s_event_task_id
=
task_get_id
(
i2s_event_task
);
return
0
;
}
NODEMCU_MODULE
(
I2S
,
"i2s"
,
i2s_map
,
luaopen_i2s
);
docs/en/modules/i2s.md
0 → 100644
View file @
34e486fb
# I2S Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2017-04-29 | | |
[
i2s.c
](
../../../components/modules/i2s.c
)
|
The I2S module provides access to the in-built I2S.
mkdocs.yml
View file @
34e486fb
...
...
@@ -40,6 +40,7 @@ pages:
-
'
file'
:
'
en/modules/file.md'
-
'
gpio'
:
'
en/modules/gpio.md'
-
'
i2c'
:
'
en/modules/i2c.md'
-
'
i2s'
:
'
en/modules/i2s.md'
-
'
ledc'
:
'
en/modules/ledc.md'
-
'
mqtt'
:
'
en/modules/mqtt.md'
-
'
net'
:
'
en/modules/net.md'
...
...
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