Skip to content

Commit ef4dc17

Browse files
committed
libs/base: Add Speaker Base support.
Signed-off-by: lbuque <[email protected]>
1 parent b3474d5 commit ef4dc17

File tree

9 files changed

+224
-1
lines changed

9 files changed

+224
-1
lines changed

docs/en/base/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ Base
88
atom_socket.rst
99
echo.rst
1010
motion.rst
11+
speaker.rst

docs/en/base/speaker.rst

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
Atomic Speaker Base
2+
===================
3+
4+
.. sku: A098
5+
6+
.. include:: ../refs/base.speaker.ref
7+
8+
The following products are supported:
9+
10+
|Atomic Speaker Base|
11+
12+
Below is the detailed support for Speaker on the host:
13+
14+
.. table::
15+
:widths: auto
16+
:align: center
17+
18+
+-----------------+---------+---------+
19+
|Controller | NS4168 | SDCard |
20+
+=================+=========+=========+
21+
| Atom Echo | |O| | |O| |
22+
+-----------------+---------+---------+
23+
| Atom Lite | |S| | |S| |
24+
+-----------------+---------+---------+
25+
| Atom Matrix | |O| | |S| |
26+
+-----------------+---------+---------+
27+
| AtomS3 | |O| | |S| |
28+
+-----------------+---------+---------+
29+
| AtomS3 Lite | |S| | |S| |
30+
+-----------------+---------+---------+
31+
| AtomS3R | |S| | |S| |
32+
+-----------------+---------+---------+
33+
| AtomS3R-CAM | |S| | |S| |
34+
+-----------------+---------+---------+
35+
| AtomS3R-Ext | |S| | |S| |
36+
+-----------------+---------+---------+
37+
38+
.. |S| unicode:: U+2705
39+
.. |O| unicode:: U+2B55
40+
41+
|S|: Supported.
42+
43+
|O|: Optional, It conflicts with some internal resource of the host.
44+
45+
46+
Micropython Example:
47+
48+
.. literalinclude:: ../../../examples/base/speaker/atoms3_speaker_example.py
49+
:language: python
50+
:linenos:
51+
52+
53+
UIFLOW2 Example:
54+
55+
|example.png|
56+
57+
58+
.. only:: builder_html
59+
60+
|atoms3_speaker_example.m5f2|
61+
62+
63+
class ATOMEchoBase
64+
------------------
65+
66+
Constructors
67+
------------
68+
69+
.. class:: SpeakerBase(_id, sck, ws, sd)
70+
71+
Create an SpeakerBase object.
72+
73+
:param int _id: The I2S port number.
74+
:param int sck: The I2S SCK pin.
75+
:param int ws: The I2S WS pin.
76+
:param int sd: The I2S DI pin.
77+
78+
UIFLOW2:
79+
80+
|SpeakerBase.png|
81+
82+
Micropython::
83+
84+
from base import SpeakerBase
85+
86+
# atoms3 lite / atoms3 / atoms3r / atoms3r-cam / atoms3-ext
87+
spk = SpeakerBase(1, 5, 39, 38)
88+
89+
# atom lite / atom matrix / atom echo
90+
spk = SpeakerBase(1, 22, 21, 25)
91+
92+
SpeakerBase class inherits M5.Speaker class, See :ref:`hardware.Speaker.Methods <hardware.Speaker.Methods>` for more details.
93+
94+
95+
class SDCard
96+
------------
97+
98+
Constructors
99+
------------
100+
101+
.. class:: SDCard(slot=2, width=1, sck=None, miso=None, mosi=None, cs=None, freq=20000000)
102+
103+
Create an SDCard object.
104+
105+
:param int slot: The slot number of the SD card. Default is 2.
106+
:param int width: width selects the bus width for the SD/MMC interface.
107+
:param int sck: sck can be used to specify an SPI clock pin.
108+
:param int miso: miso can be used to specify an SPI miso pin.
109+
:param int mosi: mosi can be used to specify an SPI mosi pin.
110+
:param int cs: cs can be used to specify an SPI chip select pin.
111+
:param int freq: freq selects the SD/MMC interface frequency in Hz.
112+
113+
UIFLOW2:
114+
115+
|SDCard.png|
116+
117+
Micropython::
118+
119+
from hardware import sdcard
120+
121+
# atoms lite / atom martrix / atom echo: SPI2
122+
sd = sdcard.SDCard(slot=3, width=1, sck=23, miso=33, mosi=19, cs=None, freq=20000000)
123+
124+
# atoms3 / atoms3 lite / atoms3r / atoms3r-cam / atoms3-ext: SPI2
125+
sd = SDCard(slot=3, width=1, sck=7, miso=8, mosi=6, cs=None, freq=20000000)
126+

docs/en/module/gpsv2.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ UIFLOW2 Example:
2727
|gpsv2_core2_example.m5f2|
2828

2929
class GPSV2Module
30-
----------------
30+
-----------------
3131

3232
Constructors
3333
------------

docs/en/refs/base.speaker.ref

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
.. |Atomic Speaker Base| image:: https://static-cdn.m5stack.com/resource/docs/products/atom/Atomic%20SPK%20Base/img-f5cdbea1-3dac-4d19-90be-949fb4d0f859.webp
3+
:target: https://docs.m5stack.com/en/atom/Atomic%20SPK%20Base
4+
:height: 200px
5+
:width: 200px
6+
7+
.. |SpeakerBase.png| image:: https://static-cdn.m5stack.com/mpy_docs/base/speaker/init.png
8+
9+
.. |example.png| image:: https://static-cdn.m5stack.com/mpy_docs/base/speaker/example.png
10+
11+
.. |SDCard.png| image:: https://static-cdn.m5stack.com/mpy_docs/base/speaker/sdcard_init.png
12+
13+
.. |atoms3_speaker_example.m5f2| raw:: html
14+
15+
<a
16+
href="https://uiflow2.m5stack.com/?example=https://raw.githubusercontent.com/m5stack/uiflow-micropython/examples/base/speaker/atoms3_speaker_example.m5f2"
17+
target="_blank"
18+
>
19+
atoms3_speaker_example.m5f2
20+
</a>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":"V2.0","versionNumber":"V2.2.1","type":"atoms3","components":[{"name":"screen","type":"screen","layer":0,"screenId":"builtin","screenName":"","id":"__atoms3_screen","createTime":1737084553743,"x":0,"y":0,"width":128,"height":128,"backgroundColor":"#000000","size":0,"isSelected":true}],"resources":[{"hardware":["hardware_button","hardware_pin_button","imu","ir","i2c"]},{"base":["base_spk"]}],"units":[],"hats":[],"bases":[{"type":"base_spk","name":"base_spk","id":"xSb2_fCmI7wD0DB+","createTime":1737085696901,"initBlockType":"base_spk_init"}],"i2cs":[{"id":"i2c1","portType":"base","userPort":[22,21],"freq":"100000","blockId":"*s+UDC|ce#xZ2`(CF4;8"}],"blockly":"<block type=\"basic_on_setup\" id=\"setup_block\" deletable=\"false\" x=\"50\" y=\"51\"><mutation isBegin=\"true\"></mutation><field name=\"UPDATEOP\">true</field><statement name=\"FUNC\"><block type=\"system_m5_begin\" id=\"system_m5_begin\"><next><block type=\"base_spk_init\" id=\"lHHoF;~Y_b1v|}1%q@e4\"><value name=\"ID\"><shadow type=\"base_spk_id_option\" id=\"`)BS3Opz)?mQUy^(tJV0\"><field name=\"VALUE\">1</field></shadow></value><value name=\"SCK\"><shadow type=\"math_number\" id=\"Ir]r_S~.#~A1/Ml6CS1x\"><mutation max=\"Infinity\" min=\"-Infinity\" precision=\"0\"></mutation><field name=\"NUM\">5</field></shadow></value><value name=\"WS\"><shadow type=\"math_number\" id=\"V[nUYzSkAJ?7m*x`:3Tl\"><mutation max=\"Infinity\" min=\"-Infinity\" precision=\"0\"></mutation><field name=\"NUM\">39</field></shadow></value><value name=\"SD\"><shadow type=\"math_number\" id=\"5U$R;VPgjTDb8FJWYUbf\"><mutation max=\"Infinity\" min=\"-Infinity\" precision=\"0\"></mutation><field name=\"NUM\">38</field></shadow></value><next><block type=\"base_spk_sdcard_init\" id=\"8-7clW6`hIKL[[0F/L?p\"><value name=\"SLOT\"><shadow type=\"base_spk_sdcard_init_slot_option\" id=\"G]R~N@,WX24kZypwR(1O\"><field name=\"VALUE\">3</field></shadow></value><value name=\"SCK\"><shadow type=\"math_number\" id=\"3EIFsyE6qGYEo|xozIj/\"><mutation max=\"Infinity\" min=\"-Infinity\" precision=\"0\"></mutation><field name=\"NUM\">7</field></shadow></value><value name=\"MISO\"><shadow type=\"math_number\" id=\"r22[m)p]QN5V`oUye7O^\"><mutation max=\"Infinity\" min=\"-Infinity\" precision=\"0\"></mutation><field name=\"NUM\">8</field></shadow></value><value name=\"MOSI\"><shadow type=\"math_number\" id=\"Ycf_|SWOn%+z)5]Bac}B\"><mutation max=\"Infinity\" min=\"-Infinity\" precision=\"0\"></mutation><field name=\"NUM\">6</field></shadow></value><value name=\"CS\"><shadow type=\"math_number\" id=\".fuMNNsv5irNI|h?SGz+\"><mutation max=\"Infinity\" min=\"-Infinity\" precision=\"0\"></mutation><field name=\"NUM\">-1</field></shadow></value><value name=\"FREQ\"><shadow type=\"base_spk_sdcard_init_freq_option\" id=\"M!kL+J@7]YxiQb3BU1{$\"><field name=\"VALUE\">20000000</field></shadow></value><next><block type=\"base_spk_playwav_file\" id=\"TI/NFc3`UUk6[$Fp[hZA\"><field name=\"TYPE\">flash</field><value name=\"FILE\"><shadow type=\"text\" id=\"wkz`Gw@czy=B^G1M~)}u\"><field name=\"TEXT\">66.wav</field></shadow></value><next><block type=\"base_spk_playwav_file\" id=\"]L}-Ua4/xCbFT`yV__1F\"><field name=\"TYPE\">sd</field><value name=\"FILE\"><shadow type=\"text\" id=\"]kFkRCeU;%.KjHJ76Jiv\"><field name=\"TEXT\">66.wav</field></shadow></value></block></next></block></next></block></next></block></next></block></statement></block><block type=\"basic_on_loop\" id=\"loop_block\" deletable=\"false\" x=\"450\" y=\"50\"><mutation isUpdate=\"true\"></mutation><field name=\"UPDATEOP\">true</field><statement name=\"FUNC\"><block type=\"system_m5_update\" id=\"system_m5_update\"></block></statement></block>","screen":[{"simulationName":"Built-in","type":"builtin","width":128,"height":128,"scale":1.3,"screenName":"","blockId":"","screenColorType":0,"id":"builtin","createTime":1737084553743}],"logicWhenNum":0,"customList":[]}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import os, sys, io
6+
import M5
7+
from M5 import *
8+
from base import SpeakerBase
9+
from hardware import sdcard
10+
11+
12+
base_spk = None
13+
14+
15+
def setup():
16+
global base_spk
17+
18+
M5.begin()
19+
base_spk = SpeakerBase(1, 5, 39, 38)
20+
sdcard.SDCard(slot=3, width=1, sck=7, miso=8, mosi=6, cs=None, freq=20000000)
21+
base_spk.playWavFile("/flash/res/audio/66.wav")
22+
base_spk.playWavFile("/sd/66.wav")
23+
24+
25+
def loop():
26+
global base_spk
27+
M5.update()
28+
29+
30+
if __name__ == "__main__":
31+
try:
32+
setup()
33+
while True:
34+
loop()
35+
except (Exception, KeyboardInterrupt) as e:
36+
try:
37+
from utility import print_error_msg
38+
39+
print_error_msg(e)
40+
except ImportError:
41+
print("please update to latest firmware")

m5stack/libs/base/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"ATOMEchoBase": "echo",
99
"Motion": "motion",
1010
"MotionBase": "motion",
11+
"SpeakerBase": "speaker",
1112
}
1213

1314

m5stack/libs/base/manifest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"atom_socket.py",
1010
"echo.py",
1111
"motion.py",
12+
"speaker.py",
1213
),
1314
base_path="..",
1415
opt=3,

m5stack/libs/base/speaker.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import M5
2+
3+
4+
class SpeakerBase:
5+
_instance = None
6+
7+
def __new__(cls, _id, sck, ws, sd):
8+
if cls._instance:
9+
cls._instance.end()
10+
11+
if cls._instance is None:
12+
cls._instance = M5.createSpeaker()
13+
14+
cls._instance.config(
15+
pin_data_out=sd,
16+
pin_bck=sck,
17+
pin_ws=ws,
18+
sample_rate=48000,
19+
stereo=False,
20+
buzzer=False,
21+
use_dac=False,
22+
dac_zero_level=0,
23+
magnification=16,
24+
dma_buf_len=256,
25+
dma_buf_count=8,
26+
task_priority=2,
27+
task_pinned_core=255,
28+
i2s_port=_id,
29+
)
30+
cls._instance.begin()
31+
cls._instance.setVolume(80)
32+
return cls._instance

0 commit comments

Comments
 (0)