13
13
wave test currently works. The problem is that pure Python code is currently
14
14
too slow to keep up with feeding data to the VS1053 fast enough. There's no
15
15
interrupt support so Python code has to monitor the DREQ line and provide a
16
- small buffer of data when ready, but the overhead of the interpretor means we
16
+ small buffer of data when ready, but the overhead of the interpreter means we
17
17
can't keep up. Optimizing SPI to use DMA transfers could help but ultimately
18
18
an interrupt-based approach is likely what can make this work better (or C
19
19
functions built in to custom builds that monitor the DREQ line and feed a
45
45
from micropython import const
46
46
from adafruit_bus_device .spi_device import SPIDevice
47
47
48
+ try :
49
+ from typing import Optional
50
+ from circuitpython_typing import ReadableBuffer
51
+ from microcontroller import Pin
52
+ from busio import SPI
53
+ except ImportError :
54
+ pass
55
+
48
56
__version__ = "0.0.0+auto.0"
49
57
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_VS1053.git"
50
58
@@ -91,7 +99,7 @@ class VS1053:
91
99
# This is NOT thread/re-entrant safe (by design, for less memory hit).
92
100
_SCI_SPI_BUFFER = bytearray (4 )
93
101
94
- def __init__ (self , spi , cs , xdcs , dreq ) :
102
+ def __init__ (self , spi : SPI , cs : Pin , xdcs : Pin , dreq : Pin ) -> None :
95
103
# Create SPI device for VS1053
96
104
self ._cs = digitalio .DigitalInOut (cs )
97
105
self ._vs1053_spi = SPIDevice (
@@ -107,12 +115,10 @@ def __init__(self, spi, cs, xdcs, dreq):
107
115
# Check version is 4 (VS1053 ID).
108
116
if self .version != 4 :
109
117
raise RuntimeError (
110
- "Expected version 4 (VS1053) but got: {} Check wiring!" .format (
111
- self .version
112
- )
118
+ f"Expected version 4 (VS1053) but got: { self .version } Check wiring!"
113
119
)
114
120
115
- def _sci_write (self , address , value ) :
121
+ def _sci_write (self , address : int , value : int ) -> None :
116
122
# Write a 16-bit big-endian value to the provided 8-bit address.
117
123
self ._SCI_SPI_BUFFER [0 ] = _VS1053_SCI_WRITE
118
124
self ._SCI_SPI_BUFFER [1 ] = address & 0xFF
@@ -123,7 +129,7 @@ def _sci_write(self, address, value):
123
129
spi .configure (baudrate = _COMMAND_BAUDRATE )
124
130
spi .write (self ._SCI_SPI_BUFFER )
125
131
126
- def _sci_read (self , address ) :
132
+ def _sci_read (self , address : int ) -> int :
127
133
# Read a 16-bit big-endian value from the provided 8-bit address.
128
134
# Write a 16-bit big-endian value to the provided 8-bit address.
129
135
self ._SCI_SPI_BUFFER [0 ] = _VS1053_SCI_READ
@@ -137,59 +143,59 @@ def _sci_read(self, address):
137
143
# pylint: enable=no-member
138
144
return (self ._SCI_SPI_BUFFER [0 ] << 8 ) | self ._SCI_SPI_BUFFER [1 ]
139
145
140
- def soft_reset (self ):
146
+ def soft_reset (self ) -> None :
141
147
"""Perform a quick soft reset of the VS1053."""
142
148
self ._sci_write (
143
149
_VS1053_REG_MODE , _VS1053_MODE_SM_SDINEW | _VS1053_MODE_SM_RESET
144
150
)
145
151
time .sleep (0.1 )
146
152
147
- def reset (self ):
153
+ def reset (self ) -> None :
148
154
"""Perform a longer full reset with clock and volume reset too."""
149
155
self ._xdcs .value = True
150
156
self .soft_reset ()
151
157
time .sleep (0.1 )
152
158
self ._sci_write (_VS1053_REG_CLOCKF , 0x6000 )
153
159
self .set_volume (40 , 40 )
154
160
155
- def set_volume (self , left , right ) :
161
+ def set_volume (self , left : int , right : int ) -> None :
156
162
"""Set the volume of the left and right channels to the provided byte
157
163
value (0-255), the lower the louder.
158
164
"""
159
165
volume = ((left & 0xFF ) << 8 ) | (right & 0xFF )
160
166
self ._sci_write (_VS1053_REG_VOLUME , volume )
161
167
162
168
@property
163
- def ready_for_data (self ):
169
+ def ready_for_data (self ) -> bool :
164
170
"""Return True if the VS1053 is ready to accept data, false otherwise."""
165
171
return self ._dreq .value
166
172
167
173
@property
168
- def version (self ):
174
+ def version (self ) -> int :
169
175
"""Return the status register version value."""
170
176
return (self ._sci_read (_VS1053_REG_STATUS ) >> 4 ) & 0x0F
171
177
172
178
@property
173
- def decode_time (self ):
179
+ def decode_time (self ) -> int :
174
180
"""Return the decode time register value. This is the amount of time
175
181
the current file has been played back in seconds."""
176
182
return self ._sci_read (_VS1053_REG_DECODETIME )
177
183
178
184
@decode_time .setter
179
- def decode_time (self , value ) :
185
+ def decode_time (self , value : int ) -> None :
180
186
"""Set the decode time register value."""
181
187
# From datasheet, set twice to ensure it is correctly set (pg. 43)
182
188
self ._sci_write (_VS1053_REG_DECODETIME , value )
183
189
184
190
@property
185
- def byte_rate (self ):
191
+ def byte_rate (self ) -> int :
186
192
"""Return the bit rate in bytes per second (computed each second).
187
193
Useful to know if a song is being played and how fast it's happening.
188
194
"""
189
195
self ._sci_write (_VS1053_REG_WRAMADDR , 0x1E05 )
190
196
return self ._sci_read (_VS1053_REG_WRAM )
191
197
192
- def start_playback (self ):
198
+ def start_playback (self ) -> None :
193
199
"""Prepare for playback of a file. After calling this check the
194
200
ready_for_data property continually until true and then send in
195
201
buffers of music data to the play_data function.
@@ -204,14 +210,16 @@ def start_playback(self):
204
210
# Set time to zero.
205
211
self .decode_time = 0
206
212
207
- def stop_playback (self ):
213
+ def stop_playback (self ) -> None :
208
214
"""Stop any playback of audio."""
209
215
self ._sci_write (
210
216
_VS1053_REG_MODE ,
211
217
_VS1053_MODE_SM_LINE1 | _VS1053_MODE_SM_SDINEW | _VS1053_MODE_SM_CANCEL ,
212
218
)
213
219
214
- def play_data (self , data_buffer , start = 0 , end = None ):
220
+ def play_data (
221
+ self , data_buffer : ReadableBuffer , start : int = 0 , end : Optional [int ] = None
222
+ ):
215
223
"""Send a buffer of file data to the VS1053 for playback. Make sure
216
224
the ready_for_data property is True before calling!
217
225
"""
@@ -227,7 +235,7 @@ def play_data(self, data_buffer, start=0, end=None):
227
235
finally :
228
236
self ._xdcs .value = True
229
237
230
- def sine_test (self , n , seconds ) :
238
+ def sine_test (self , n : int , seconds : float ) -> None :
231
239
"""Play a sine wave for the specified number of seconds. Useful to
232
240
test the VS1053 is working.
233
241
"""
0 commit comments