Skip to content

Commit b7f8ae5

Browse files
2 parents bf69b19 + bcbd596 commit b7f8ae5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+488
-331
lines changed

README.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,19 @@ python get.py
5151

5252
### Using PlatformIO
5353

54-
[PlatformIO](http://platformio.org) is an open source ecosystem for IoT
54+
[PlatformIO](http://platformio.org?utm_source=github&utm_medium=arduino-esp8266) is an open source ecosystem for IoT
5555
development with cross platform build system, library manager and full support
5656
for Espressif (ESP8266) development. It works on the popular host OS: macOS, Windows,
5757
Linux 32/64, Linux ARM (like Raspberry Pi, BeagleBone, CubieBoard).
5858

59-
- [What is PlatformIO?](http://docs.platformio.org/page/what-is-platformio.html)
60-
- [PlatformIO IDE](http://platformio.org/platformio-ide)
61-
- Quick Start with [PlatformIO IDE](http://docs.platformio.org/page/ide/atom.html#quick-start) or [PlatformIO Core](http://docs.platformio.org/page/core.html)
62-
- [Advanced usage](http://docs.platformio.org/page/platforms/espressif.html) -
63-
custom settings, uploading to SPIFFS, Over-the-Air (OTA) or using stage version
64-
- [Integration with Cloud and Standalone IDEs](http://docs.platformio.org/page/ide.html) -
65-
Cloud9, Codeanywhere, Eclipse Che (Codenvy), Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, VIM and Visual Studio
66-
- [Project Examples](http://docs.platformio.org/page/platforms/espressif.html#examples)
59+
- [What is PlatformIO?](http://docs.platformio.org/en/latest/what-is-platformio.html?utm_source=github&utm_medium=arduino-esp8266)
60+
- [PlatformIO IDE](http://platformio.org/platformio-ide?utm_source=github&utm_medium=arduino-esp8266)
61+
- [PlatformIO Core](http://docs.platformio.org/en/latest/core.html?utm_source=github&utm_medium=arduino-esp8266) (command line tool)
62+
- [Advanced usage](http://docs.platformio.org/en/latest/platforms/espressif8266.html?utm_source=github&utm_medium=arduino-esp8266) -
63+
custom settings, uploading to SPIFFS, Over-the-Air (OTA), staging version
64+
- [Integration with Cloud and Standalone IDEs](http://docs.platformio.org/en/latest/ide.html?utm_source=github&utm_medium=arduino-esp8266) -
65+
Cloud9, Codeanywhere, Eclipse Che (Codenvy), Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, VIM, Visual Studio, and VSCode
66+
- [Project Examples](http://docs.platformio.org/en/latest/platforms/espressif8266.html?utm_source=github&utm_medium=arduino-esp8266#examples)
6767

6868
### Building with make
6969

boards.txt

+104-96
Large diffs are not rendered by default.

cores/esp8266/Esp.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,22 @@ void EspClass::wdtFeed(void)
107107

108108
extern "C" void esp_yield();
109109

110-
void EspClass::deepSleep(uint32_t time_us, WakeMode mode)
110+
void EspClass::deepSleep(uint64_t time_us, WakeMode mode)
111111
{
112112
system_deep_sleep_set_option(static_cast<int>(mode));
113113
system_deep_sleep(time_us);
114114
esp_yield();
115115
}
116116

117+
//this calculation was taken verbatim from the SDK api reference for SDK 2.1.0.
118+
//Note: system_rtc_clock_cali_proc() returns a uint32_t, even though system_deep_sleep() takes a uint64_t.
119+
uint64_t EspClass::deepSleepMax()
120+
{
121+
//cali*(2^31-1)/(2^12)
122+
return (uint64_t)system_rtc_clock_cali_proc()*(0x80000000-1)/(0x1000);
123+
124+
}
125+
117126
bool EspClass::rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size)
118127
{
119128
if (size + offset > 512) {

cores/esp8266/Esp.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ class EspClass {
9292
void wdtDisable();
9393
void wdtFeed();
9494

95-
void deepSleep(uint32_t time_us, RFMode mode = RF_DEFAULT);
95+
void deepSleep(uint64_t time_us, RFMode mode = RF_DEFAULT);
96+
uint64_t deepSleepMax();
9697

9798
bool rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size);
9899
bool rtcUserMemoryWrite(uint32_t offset, uint32_t *data, size_t size);

cores/esp8266/core_esp8266_i2s.c

+31-3
Original file line numberDiff line numberDiff line change
@@ -212,15 +212,43 @@ static uint32_t _i2s_sample_rate;
212212
void ICACHE_FLASH_ATTR i2s_set_rate(uint32_t rate){ //Rate in HZ
213213
if(rate == _i2s_sample_rate) return;
214214
_i2s_sample_rate = rate;
215-
uint32_t i2s_clock_div = (I2SBASEFREQ/(_i2s_sample_rate*32)) & I2SCDM;
216-
uint8_t i2s_bck_div = (I2SBASEFREQ/(_i2s_sample_rate*i2s_clock_div*2)) & I2SBDM;
215+
216+
uint32_t scaled_base_freq = I2SBASEFREQ/32;
217+
float delta_best = scaled_base_freq;
218+
219+
uint8_t sbd_div_best=1;
220+
uint8_t scd_div_best=1;
221+
for (uint8_t i=1; i<64; i++){
222+
for (uint8_t j=i; j<64; j++){
223+
float new_delta = fabs(((float)scaled_base_freq/i/j) - rate);
224+
if (new_delta < delta_best){
225+
delta_best = new_delta;
226+
sbd_div_best = i;
227+
scd_div_best = j;
228+
}
229+
}
230+
}
231+
217232
//os_printf("Rate %u Div %u Bck %u Frq %u\n", _i2s_sample_rate, i2s_clock_div, i2s_bck_div, I2SBASEFREQ/(i2s_clock_div*i2s_bck_div*2));
218233

219234
//!trans master, !bits mod, rece slave mod, rece msb shift, right first, msb right
220235
I2SC &= ~(I2STSM | (I2SBMM << I2SBM) | (I2SBDM << I2SBD) | (I2SCDM << I2SCD));
221-
I2SC |= I2SRF | I2SMR | I2SRSM | I2SRMS | ((i2s_bck_div-1) << I2SBD) | ((i2s_clock_div-1) << I2SCD);
236+
I2SC |= I2SRF | I2SMR | I2SRSM | I2SRMS | ((sbd_div_best) << I2SBD) | ((scd_div_best) << I2SCD);
237+
}
238+
239+
void ICACHE_FLASH_ATTR i2s_set_dividers(uint8_t div1, uint8_t div2){
240+
div1 &= I2SBDM;
241+
div2 &= I2SCDM;
242+
243+
I2SC &= ~(I2STSM | (I2SBMM << I2SBM) | (I2SBDM << I2SBD) | (I2SCDM << I2SCD));
244+
I2SC |= I2SRF | I2SMR | I2SRSM | I2SRMS | (div1 << I2SBD) | (div2 << I2SCD);
222245
}
223246

247+
float ICACHE_FLASH_ATTR i2s_get_real_rate(){
248+
return (float)I2SBASEFREQ/32/((I2SC>>I2SBD) & I2SBDM)/((I2SC >> I2SCD) & I2SCDM);
249+
}
250+
251+
224252
void ICACHE_FLASH_ATTR i2s_begin(){
225253
_i2s_sample_rate = 0;
226254
i2s_slc_begin();

cores/esp8266/esp8266_peri.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ extern uint8_t esp8266_gpioToFn[16];
754754
#define i2c_bbpll_en_audio_clock_out_msb 7
755755
#define i2c_bbpll_en_audio_clock_out_lsb 7
756756
#define I2S_CLK_ENABLE() i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1)
757-
#define I2SBASEFREQ (12000000L)
757+
#define I2SBASEFREQ (160000000L)
758758

759759
#define I2STXF ESP8266_REG(0xe00) //I2STXFIFO (32bit)
760760
#define I2SRXF ESP8266_REG(0xe04) //I2SRXFIFO (32bit)

cores/esp8266/i2s.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ extern "C" {
4343
void i2s_begin();
4444
void i2s_end();
4545
void i2s_set_rate(uint32_t rate);//Sample Rate in Hz (ex 44100, 48000)
46+
void i2s_set_dividers(uint8_t div1, uint8_t div2);//Direct control over output rate
47+
float i2s_get_real_rate();//The actual Sample Rate on output
4648
bool i2s_write_sample(uint32_t sample);//32bit sample with channels being upper and lower 16 bits (blocking when DMA is full)
4749
bool i2s_write_sample_nb(uint32_t sample);//same as above but does not block when DMA is full and returns false instead
4850
bool i2s_write_lr(int16_t left, int16_t right);//combines both channels and calls i2s_write_sample with the result
@@ -54,4 +56,4 @@ int16_t i2s_available();// returns the number of samples than can be written bef
5456
}
5557
#endif
5658

57-
#endif
59+
#endif

cores/esp8266/spiffs_api.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ class SPIFFSFileImpl : public FileImpl
329329
if (mode == SeekEnd) {
330330
offset = -offset;
331331
}
332-
auto rc = SPIFFS_lseek(_fs->getFs(), _fd, pos, (int) mode);
332+
auto rc = SPIFFS_lseek(_fs->getFs(), _fd, offset, (int) mode);
333333
if (rc < 0) {
334334
DEBUGV("SPIFFS_lseek rc=%d\r\n", rc);
335335
return false;

cores/esp8266/umm_malloc/umm_malloc.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -1685,7 +1685,9 @@ void *umm_calloc( size_t num, size_t item_size ) {
16851685

16861686
size += POISON_SIZE(size);
16871687
ret = _umm_malloc(size);
1688-
memset(ret, 0x00, size);
1688+
if (ret) {
1689+
memset(ret, 0x00, size);
1690+
}
16891691

16901692
ret = GET_POISONED(ret, size);
16911693

doc/esp8266wifi/client-class.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,4 @@ Other Function Calls
5959
Documentation for the above functions is not yet prepared.
6060

6161
For code samples please refer to separate section with `examples
62-
:arrow\_right: <client-examples.md>`__ dedicated specifically to the Client Class.
62+
:arrow\_right: <client-examples.rst>`__ dedicated specifically to the Client Class.

doc/esp8266wifi/client-examples.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ This time we are going to concentrate just on retrieving a web page contents sen
2828
Get Connected to Wi-Fi
2929
~~~~~~~~~~~~~~~~~~~~~~
3030

31-
We should start with connecting the module to an access point to obtain an access to internet. The code to provide this functionality has been already discussed in chapter `Quick Start <readme.md#quick-start>`__. Please refer to it for details.
31+
We should start with connecting the module to an access point to obtain an access to internet. The code to provide this functionality has been already discussed in chapter `Quick Start <readme.rst#quick-start>`__. Please refer to it for details.
3232

3333
Select a Server
3434
~~~~~~~~~~~~~~~
@@ -257,4 +257,4 @@ For more client examples please check
257257

258258
- `WiFiClient.ino <https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino>`__ - this sketch sends data via HTTP GET requests to data.sparkfun.com service.
259259

260-
For the list of functions provided to manage clients, please refer to the `Client Class :arrow\_right: <client-class.md>`__ documentation.
260+
For the list of functions provided to manage clients, please refer to the `Client Class :arrow\_right: <client-class.rst>`__ documentation.

doc/esp8266wifi/client-secure-class.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,4 @@ Other Function Calls
9898
9999
Documentation for the above functions is not yet prepared.
100100

101-
For code samples please refer to separate section with `examples <client-secure-examples.md>`__ dedicated specifically to the Client Secure Class.
101+
For code samples please refer to separate section with `examples <client-secure-examples.rst>`__ dedicated specifically to the Client Secure Class.

doc/esp8266wifi/client-secure-examples.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Client Secure
44
-------------
55

6-
The client secure is a `client <#client>`__ but secure. Application example below will be easier to follow if you check similar and simpler `example <client-examples.md>`__ for the "ordinary" client. That being said we will concentrate on discussing the code that is specific to the client secure.
6+
The client secure is a `client <#client>`__ but secure. Application example below will be easier to follow if you check similar and simpler `example <client-examples.rst>`__ for the "ordinary" client. That being said we will concentrate on discussing the code that is specific to the client secure.
77

88
Table of Contents
99
-----------------
@@ -71,7 +71,7 @@ We can obtain the ``fingerprint`` for specific ``host`` using a web browser. For
7171

7272
alt text
7373

74-
Remaining steps look almost identical as for the `non-secure client example <client-examples.md>`__.
74+
Remaining steps look almost identical as for the `non-secure client example <client-examples.rst>`__.
7575

7676
Connect to the Server
7777
~~~~~~~~~~~~~~~~~~~~~
@@ -106,7 +106,7 @@ If this check fails, it is up to you to decide if to proceed further or abort co
106106
GET Response from the Server
107107
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
108108

109-
In the next steps we should execute GET command. This is done is similar way as discussed in `non-secure client example <client-examples.md>`__.
109+
In the next steps we should execute GET command. This is done is similar way as discussed in `non-secure client example <client-examples.rst>`__.
110110

111111
.. code:: cpp
112112

doc/esp8266wifi/generic-class.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ WiFiEventHandler
2727
WiFiEventHandler onSoftAPModeStationConnected (std::function< void(const WiFiEventSoftAPModeStationConnected &)>)
2828
WiFiEventHandler onSoftAPModeStationDisconnected (std::function< void(const WiFiEventSoftAPModeStationDisconnected &)>)
2929
30-
To see a sample application with ``WiFiEventHandler``, please check separate section with `examples :arrow\_right: <generic-examples.md>`__ dedicated specifically to the Generic Class..
30+
To see a sample application with ``WiFiEventHandler``, please check separate section with `examples :arrow\_right: <generic-examples.rst>`__ dedicated specifically to the Generic Class..
3131

3232
persistent
3333
~~~~~~~~~~

doc/esp8266wifi/generic-examples.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Generic
44
-------
55

6-
In the first `example <readme.md#quick-start>`__ of the ESP8266WiFi library documentation we have discussed how to check when module connects to the Wi-Fi network. We were waiting until connection is established. If network is not available, the module could wait like that for ever doing nothing else. Another `example <scan-examples.md#async-scan>`__ on the Wi-Fi asynchronous scan mode demonstrated how to wait for scan result and do in parallel something else - blink a LED not disturbing the blink pattern. Let's apply similar functionality when connecting the module to an access point.
6+
In the first `example <readme.rst#quick-start>`__ of the ESP8266WiFi library documentation we have discussed how to check when module connects to the Wi-Fi network. We were waiting until connection is established. If network is not available, the module could wait like that for ever doing nothing else. Another `example <scan-examples.rst#async-scan>`__ on the Wi-Fi asynchronous scan mode demonstrated how to wait for scan result and do in parallel something else - blink a LED not disturbing the blink pattern. Let's apply similar functionality when connecting the module to an access point.
77

88
Table of Contents
99
-----------------
@@ -29,7 +29,7 @@ We would like to write a code that will inform us that connection to Wi-Fi netwo
2929
Event Driven Methods
3030
~~~~~~~~~~~~~~~~~~~~
3131

32-
The list of all such methods is provided in `Generic Class <generic-class.md>`__ documentation.
32+
The list of all such methods is provided in `Generic Class <generic-class.rst>`__ documentation.
3333

3434
We would like to use two of them: \* ``onStationModeGotIP`` called when station is assigned IP address. This assignment may be done by DHCP client or by executing ``WiFi.config(...)``. \* ``onStationModeDisconnected`` called when station is disconnected from Wi-Fi network. The reason of disconnection does not matter. Event will be triggered both if disconnection is done from the code by executing ``WiFi.disconnect()``, because the Wi-Fi signal is weak, or because the access point is switched off.
3535

@@ -122,4 +122,4 @@ Conclusion
122122

123123
Check out events from generic class. They will help you to write more compact code. Use them to practice splitting your code into separate tasks that are executed asynchronously.
124124

125-
For review of functions included in generic class, please refer to the `Generic Class <generic-class.md>`__ documentation.
125+
For review of functions included in generic class, please refer to the `Generic Class <generic-class.rst>`__ documentation.

doc/esp8266wifi/readme.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ The same sketch without ``Serial.setDebugOutput(true)`` will print out only the
302302
Enable Debugging in IDE
303303
~~~~~~~~~~~~~~~~~~~~~~~
304304

305-
Arduino IDE provides convenient method to `enable debugging <https://github.com/esp8266/Arduino/blob/master/doc/Troubleshooting/debugging.md>`__ for specific libraries.
305+
Arduino IDE provides convenient method to `enable debugging <https://github.com/esp8266/Arduino/blob/master/doc/Troubleshooting/debugging.rst>`__ for specific libraries.
306306

307307
What's Inside?
308308
--------------

doc/esp8266wifi/scan-class.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,4 @@ The ``networkItem`` is a zero based index of network discovered during scan. All
235235
5: , Ch:11 (-77dBm) hidden
236236
6: UPC Wi-Free, Ch:11 (-79dBm)
237237

238-
For code samples please refer to separate section with `examples <scan-examples.md>`__ dedicated specifically to the Scan Class.
238+
For code samples please refer to separate section with `examples <scan-examples.rst>`__ dedicated specifically to the Scan Class.

doc/esp8266wifi/scan-examples.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,4 @@ Conclusion
240240

241241
The scan class API provides comprehensive set of methods to do scanning in both synchronous as well as in asynchronous mode. Therefore we can easy implement code that is doing scanning in background without disturbing other processes running on ESP8266 module.
242242

243-
For the list of functions provided to manage scan mode please refer to the `Scan Class <scan-class.md>`__ documentation.
243+
For the list of functions provided to manage scan mode please refer to the `Scan Class <scan-class.rst>`__ documentation.

doc/esp8266wifi/station-examples.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Station
44
-------
55

6-
Example of connecting to an access point has been shown in chapter `Quick Start <readme.md#quick-start>`__. In case connection is lost, ESP8266 will automatically reconnect to the last used access point, once it is again available.
6+
Example of connecting to an access point has been shown in chapter `Quick Start <readme.rst#quick-start>`__. In case connection is lost, ESP8266 will automatically reconnect to the last used access point, once it is again available.
77

88
Can we provide more robust connection to Wi-Fi than that?
99

@@ -19,7 +19,7 @@ Table of Contents
1919
Introduction
2020
~~~~~~~~~~~~
2121

22-
Following the example in\ `Quick Start <readme.md#quick-start>`__, we would like to go one step further and made ESP connect to next available access point if current connection is lost. This functionality is provided with 'ESP8266WiFiMulti' class and demonstrated in sketch below.
22+
Following the example in\ `Quick Start <readme.rst#quick-start>`__, we would like to go one step further and made ESP connect to next available access point if current connection is lost. This functionality is provided with 'ESP8266WiFiMulti' class and demonstrated in sketch below.
2323

2424
.. code:: cpp
2525
@@ -100,7 +100,7 @@ Function ``monitorWiFi()`` is in place to show when connection is lost by displa
100100
Can we Make it Simpler?
101101
~~~~~~~~~~~~~~~~~~~~~~~
102102

103-
Please note that you may simplify this sketch by removing function ``monitorWiFi()`` and putting inside ``loop()`` only ``wifiMulti.run()``. ESP will still reconnect between configured access points if required. Now you won't be able to see it on serial monitor unless you add ``Serial.setDebugOutput(true)`` as described in point `Enable Wi-Fi Diagnostic <readme.md#enable-wi-fi-diagnostic>`__.
103+
Please note that you may simplify this sketch by removing function ``monitorWiFi()`` and putting inside ``loop()`` only ``wifiMulti.run()``. ESP will still reconnect between configured access points if required. Now you won't be able to see it on serial monitor unless you add ``Serial.setDebugOutput(true)`` as described in point `Enable Wi-Fi Diagnostic <readme.rst#enable-wi-fi-diagnostic>`__.
104104

105105
Updated sketch for such scenario will look as follows:
106106

doc/esp8266wifi/udp-examples.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Once we have libraries in place we need to create a ``WiFiUDP`` object. Then we
4141
Wi-Fi Connection
4242
~~~~~~~~~~~~~~~~
4343

44-
At the beginning of ``setup()`` let's implement typical code to connect to an access point. This has been discussed in `Quick Start <readme.md#quick-start>`__. Please refer to it if required.
44+
At the beginning of ``setup()`` let's implement typical code to connect to an access point. This has been discussed in `Quick Start <readme.rst#quick-start>`__. Please refer to it if required.
4545

4646
UDP Setup
4747
~~~~~~~~~

doc/faq/a01-espcomm_sync-failed.rst

+5-5
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ following three things right: 1. Module is provided with enough power,
4242
resistors, 3. Module is put into boot loader mode.
4343

4444
For specific details please refer to section on `Generic ESP8266
45-
modules <../boards.md#generic-esp8266-modules>`__. Example modules
45+
modules <../boards.rst#generic-esp8266-modules>`__. Example modules
4646
without USB to serial converter on board are shown below.
4747

4848
.. figure:: pictures/a01-example-boards-without-usb.png
@@ -128,7 +128,7 @@ follows:
128128
``ets Jan 8 2013,rst cause:2, boot mode:(1,7)``
129129

130130
If you see similar message but different values then decode them using
131-
`Boot Messages and Modes <../boards.md#boot-messages-and-modes>`__. The
131+
`Boot Messages and Modes <../boards.rst#boot-messages-and-modes>`__. The
132132
key information is contained in first digit / three right-most bits of
133133
the boot mode message as shown below.
134134

@@ -140,9 +140,9 @@ the boot mode message as shown below.
140140
For instance message ``boot mode (3,3)`` indicates that pins GPIO2 and
141141
GPIO0 are set HIGH and GPIO15 is set LOW. This is configuration for
142142
`normal
143-
operation <../boards.md#minimal-hardware-setup-for-running-only>`__ of
143+
operation <../boards.rst#minimal-hardware-setup-for-running-only>`__ of
144144
module (to execute application from flash), not for `boot
145-
loading <../boards.md#minimal-hardware-setup-for-bootloading-only>`__
145+
loading <../boards.rst#minimal-hardware-setup-for-bootloading-only>`__
146146
(flash programming).
147147

148148
Note: Without having this step right you will not be able to upload
@@ -391,4 +391,4 @@ Test stand used for checking of ck reset method is shown above.
391391

392392
No any ESP module has been harmed during preparation of this FAQ item.
393393

394-
`FAQ list :back: <readme.md>`__
394+
`FAQ list :back: <readme.rst>`__

0 commit comments

Comments
 (0)