summaryrefslogtreecommitdiff
path: root/components/drivers
diff options
context:
space:
mode:
authorcliff-cmc <[email protected]>2021-02-26 11:09:27 +0800
committerCliff Chen <[email protected]>2021-02-26 11:45:19 +0800
commiteea0c3d74a40f73235da45c6f77e8b411ac94cf2 (patch)
treea6906f1aed7118ab53dbe18f2ee4727a754583af /components/drivers
parent1a9ecf27f31277750d92c921b62503f75275e122 (diff)
parentfae0fa8eea4c0e797940bf1eddc8ee6c1711734a (diff)
Add memtrace command for memheap.c
Diffstat (limited to 'components/drivers')
-rwxr-xr-xcomponents/drivers/Kconfig23
-rw-r--r--components/drivers/audio/audio.c12
-rw-r--r--components/drivers/audio/audio_pipe.c2
-rw-r--r--components/drivers/audio/audio_pipe.h5
-rw-r--r--components/drivers/hwtimer/hwtimer.c9
-rw-r--r--components/drivers/i2c/i2c-bit-ops.c14
-rw-r--r--components/drivers/include/drivers/alarm.h9
-rw-r--r--components/drivers/include/drivers/dac.h42
-rw-r--r--components/drivers/include/drivers/hwtimer.h2
-rw-r--r--components/drivers/include/drivers/i2c.h12
-rw-r--r--components/drivers/include/drivers/phy.h87
-rw-r--r--components/drivers/include/drivers/phy_mdio.h43
-rw-r--r--components/drivers/include/drivers/pin.h3
-rw-r--r--components/drivers/include/drivers/pm.h50
-rw-r--r--components/drivers/include/drivers/rt_drv_pwm.h8
-rw-r--r--components/drivers/include/drivers/spi.h26
-rw-r--r--components/drivers/include/drivers/usb_common.h16
-rw-r--r--components/drivers/include/ipc/dataqueue.h13
-rw-r--r--components/drivers/include/ipc/ringbuffer.h1
-rw-r--r--components/drivers/include/rtdevice.h9
-rw-r--r--components/drivers/misc/SConscript3
-rw-r--r--components/drivers/misc/dac.c231
-rw-r--r--components/drivers/misc/pin.c22
-rw-r--r--components/drivers/misc/rt_drv_pwm.c74
-rw-r--r--components/drivers/phy/SConscript8
-rw-r--r--components/drivers/phy/phy.c78
-rw-r--r--components/drivers/pm/pm.c354
-rw-r--r--components/drivers/rtc/alarm.c236
-rw-r--r--components/drivers/rtc/rtc.c40
-rw-r--r--components/drivers/rtc/soft_rtc.c67
-rw-r--r--components/drivers/sdio/sdio.c42
-rw-r--r--components/drivers/sensors/SConscript2
-rw-r--r--components/drivers/sensors/sensor.c15
-rwxr-xr-xcomponents/drivers/sensors/sensor.h15
-rwxr-xr-xcomponents/drivers/sensors/sensor_cmd.c31
-rw-r--r--components/drivers/serial/serial.c79
-rw-r--r--components/drivers/spi/sfud/inc/sfud_cfg.h12
-rw-r--r--components/drivers/spi/sfud/inc/sfud_flash_def.h11
-rw-r--r--components/drivers/spi/spi_flash.h3
-rw-r--r--components/drivers/spi/spi_flash_sfud.c132
-rw-r--r--components/drivers/spi/spi_flash_sfud.h13
-rw-r--r--components/drivers/spi/spi_msd.c10
-rw-r--r--components/drivers/src/dataqueue.c118
-rw-r--r--components/drivers/src/pipe.c58
-rw-r--r--components/drivers/src/ringbuffer.c34
-rw-r--r--components/drivers/src/workqueue.c2
-rw-r--r--components/drivers/touch/SConscript2
-rw-r--r--components/drivers/touch/touch.c26
-rw-r--r--components/drivers/touch/touch.h8
-rw-r--r--components/drivers/usb/usbdevice/class/audio_mic.c3
-rw-r--r--components/drivers/usb/usbdevice/class/audio_speaker.c3
-rw-r--r--components/drivers/usb/usbdevice/class/cdc_vcom.c7
-rw-r--r--components/drivers/usb/usbdevice/class/hid.c22
-rw-r--r--components/drivers/usb/usbdevice/class/mstorage.c27
-rw-r--r--components/drivers/usb/usbdevice/class/winusb.c4
-rw-r--r--components/drivers/usb/usbhost/class/udisk.c2
-rw-r--r--components/drivers/usb/usbhost/core/hub.c15
-rw-r--r--components/drivers/usb/usbhost/core/usbhost_core.c8
-rw-r--r--components/drivers/wlan/wlan_mgnt.c2
59 files changed, 1835 insertions, 370 deletions
diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig
index 5408761c6a..006497519f 100755
--- a/components/drivers/Kconfig
+++ b/components/drivers/Kconfig
@@ -95,14 +95,18 @@ if RT_USING_I2C
config RT_USING_I2C_BITOPS
bool "Use GPIO to simulate I2C"
default y
-endif
-if RT_USING_I2C_BITOPS
- config RT_I2C_BITOPS_DEBUG
- bool "Use simulate I2C debug message"
- default n
+ if RT_USING_I2C_BITOPS
+ config RT_I2C_BITOPS_DEBUG
+ bool "Use simulate I2C debug message"
+ default n
+ endif
endif
+config RT_USING_PHY
+ bool "Using ethernet phy device drivers"
+ default n
+
config RT_USING_PIN
bool "Using generic GPIO device drivers"
default y
@@ -111,6 +115,10 @@ config RT_USING_ADC
bool "Using ADC device drivers"
default n
+config RT_USING_DAC
+ bool "Using DAC device drivers"
+ default n
+
config RT_USING_PWM
bool "Using PWM device drivers"
default n
@@ -283,6 +291,11 @@ endif
config RT_USING_TOUCH
bool "Using Touch device drivers"
default n
+ if RT_USING_TOUCH
+ config RT_TOUCH_PIN_IRQ
+ bool "touch irq use pin irq"
+ default n
+ endif
menuconfig RT_USING_HWCRYPTO
bool "Using Hardware Crypto drivers"
diff --git a/components/drivers/audio/audio.c b/components/drivers/audio/audio.c
index 4cec8a4a9c..c3f8723db6 100644
--- a/components/drivers/audio/audio.c
+++ b/components/drivers/audio/audio.c
@@ -12,14 +12,15 @@
#include <stdio.h>
#include <string.h>
#include <rthw.h>
-#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "audio"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
+#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
enum
{
@@ -43,8 +44,8 @@ static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio)
position = audio->replay->pos;
dst_size = buf_info->block_size;
- /* check repaly queue is empty */
- if (rt_data_queue_peak(&audio->replay->queue, (const void **)&data, &src_size) != RT_EOK)
+ /* check replay queue is empty */
+ if (rt_data_queue_peek(&audio->replay->queue, (const void **)&data, &src_size) != RT_EOK)
{
/* ack stop event */
if (audio->replay->event & REPLAY_EVT_STOP)
@@ -63,7 +64,7 @@ static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio)
/* copy data from memory pool to hardware device fifo */
while (index < dst_size)
{
- result = rt_data_queue_peak(&audio->replay->queue, (const void **)&data, &src_size);
+ result = rt_data_queue_peek(&audio->replay->queue, (const void **)&data, &src_size);
if (result != RT_EOK)
{
LOG_D("under run %d, remain %d", audio->replay->pos, remain_bytes);
@@ -235,7 +236,7 @@ static rt_err_t _audio_dev_init(struct rt_device *dev)
if (replay->mp == RT_NULL)
{
rt_free(replay);
- LOG_E("create memory pool for repaly failed");
+ LOG_E("create memory pool for replay failed");
return -RT_ENOMEM;
}
@@ -588,7 +589,6 @@ int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
speed = 192000;
break;
default:
-
break;
}
diff --git a/components/drivers/audio/audio_pipe.c b/components/drivers/audio/audio_pipe.c
index d7c37009b6..e9de1ffb74 100644
--- a/components/drivers/audio/audio_pipe.c
+++ b/components/drivers/audio/audio_pipe.c
@@ -9,9 +9,7 @@
*/
#include <rthw.h>
-#include <rtthread.h>
#include <rtdevice.h>
-
#include "audio_pipe.h"
static void _rt_pipe_resume_writer(struct rt_audio_pipe *pipe)
diff --git a/components/drivers/audio/audio_pipe.h b/components/drivers/audio/audio_pipe.h
index 85a3eb1793..3ae3bc8498 100644
--- a/components/drivers/audio/audio_pipe.h
+++ b/components/drivers/audio/audio_pipe.h
@@ -12,7 +12,6 @@
/**
* Pipe Device
*/
-#include <rtthread.h>
#include <rtdevice.h>
#ifndef RT_PIPE_BUFSZ
@@ -71,6 +70,6 @@ rt_err_t rt_audio_pipe_detach(struct rt_audio_pipe *pipe);
#ifdef RT_USING_HEAP
rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size);
void rt_audio_pipe_destroy(struct rt_audio_pipe *pipe);
-#endif
-#endif
+#endif /* RT_USING_HEAP */
+#endif /* __AUDIO_PIPE_H__ */
diff --git a/components/drivers/hwtimer/hwtimer.c b/components/drivers/hwtimer/hwtimer.c
index 3953919fae..976d8bbf32 100644
--- a/components/drivers/hwtimer/hwtimer.c
+++ b/components/drivers/hwtimer/hwtimer.c
@@ -10,6 +10,7 @@
#include <rtthread.h>
#include <rtdevice.h>
+#include <rthw.h>
rt_inline rt_uint32_t timeout_calc(rt_hwtimer_t *timer, rt_hwtimerval_t *tv)
{
@@ -144,19 +145,25 @@ static rt_size_t rt_hwtimer_read(struct rt_device *dev, rt_off_t pos, void *buff
rt_hwtimer_t *timer;
rt_hwtimerval_t tv;
rt_uint32_t cnt;
+ rt_base_t level;
+ rt_int32_t overflow;
float t;
timer = (rt_hwtimer_t *)dev;
if (timer->ops->count_get == RT_NULL)
return 0;
+ level = rt_hw_interrupt_disable();
cnt = timer->ops->count_get(timer);
+ overflow = timer->overflow;
+ rt_hw_interrupt_enable(level);
+
if (timer->info->cntmode == HWTIMER_CNTMODE_DW)
{
cnt = (timer->freq * timer->period_sec) - cnt;
}
- t = timer->overflow * timer->period_sec + cnt/(float)timer->freq;
+ t = overflow * timer->period_sec + cnt/(float)timer->freq;
tv.sec = t;
tv.usec = (t - tv.sec) * 1000000;
size = size > sizeof(tv)? sizeof(tv) : size;
diff --git a/components/drivers/i2c/i2c-bit-ops.c b/components/drivers/i2c/i2c-bit-ops.c
index 99338eef54..96af567a1e 100644
--- a/components/drivers/i2c/i2c-bit-ops.c
+++ b/components/drivers/i2c/i2c-bit-ops.c
@@ -375,8 +375,6 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
rt_int32_t i, ret;
rt_uint16_t ignore_nack;
- LOG_D("send start condition");
- i2c_start(ops);
for (i = 0; i < num; i++)
{
msg = &msgs[i];
@@ -387,6 +385,11 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
{
i2c_restart(ops);
}
+ else
+ {
+ LOG_D("send start condition");
+ i2c_start(ops);
+ }
ret = i2c_bit_send_address(bus, msg);
if ((ret != RT_EOK) && !ignore_nack)
{
@@ -423,8 +426,11 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
ret = i;
out:
- LOG_D("send stop condition");
- i2c_stop(ops);
+ if (!(msg->flags & RT_I2C_NO_STOP))
+ {
+ LOG_D("send stop condition");
+ i2c_stop(ops);
+ }
return ret;
}
diff --git a/components/drivers/include/drivers/alarm.h b/components/drivers/include/drivers/alarm.h
index b5ebbc86d9..e59c4142c7 100644
--- a/components/drivers/include/drivers/alarm.h
+++ b/components/drivers/include/drivers/alarm.h
@@ -6,6 +6,8 @@
* Change Logs:
* Date Author Notes
* 2012-10-27 heyuanjie87 first version.
+ * 2013-05-17 aozima initial alarm event & mutex in system init.
+ * 2020-10-15 zhangsz add alarm flags hour minute second.
*/
#ifndef __ALARM_H__
@@ -22,6 +24,9 @@
#define RT_ALARM_WEEKLY 0x200 /* alarm weekly at Monday or Friday etc. */
#define RT_ALARM_MONTHLY 0x400 /* alarm monthly at someday */
#define RT_ALARM_YAERLY 0x800 /* alarm yearly at a certain date */
+#define RT_ALARM_HOUR 0x1000 /* alarm each hour at a certain min:second */
+#define RT_ALARM_MINUTE 0x2000 /* alarm each minute at a certain second */
+#define RT_ALARM_SECOND 0x4000 /* alarm each second */
/* alarm control cmd */
#define RT_ALARM_CTRL_MODIFY 1 /* modify alarm time or alarm flag */
@@ -44,6 +49,8 @@ struct rt_alarm
rt_uint32_t flag;
rt_alarm_callback_t callback;
struct tm wktime;
+
+ void *user_data;
};
struct rt_alarm_setup
@@ -67,6 +74,6 @@ void rt_alarm_update(rt_device_t dev, rt_uint32_t event);
rt_err_t rt_alarm_delete(rt_alarm_t alarm);
rt_err_t rt_alarm_start(rt_alarm_t alarm);
rt_err_t rt_alarm_stop(rt_alarm_t alarm);
-void rt_alarm_system_init(void);
+int rt_alarm_system_init(void);
#endif /* __ALARM_H__ */
diff --git a/components/drivers/include/drivers/dac.h b/components/drivers/include/drivers/dac.h
new file mode 100644
index 0000000000..b6043348dc
--- /dev/null
+++ b/components/drivers/include/drivers/dac.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-19 thread-liu the first version
+ */
+
+#ifndef __DAC_H__
+#define __DAC_H__
+#include <rtthread.h>
+
+struct rt_dac_device;
+struct rt_dac_ops
+{
+ rt_err_t (*disabled)(struct rt_dac_device *device, rt_uint32_t channel);
+ rt_err_t (*enabled)(struct rt_dac_device *device, rt_uint32_t channel);
+ rt_err_t (*convert)(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value);
+};
+
+struct rt_dac_device
+{
+ struct rt_device parent;
+ const struct rt_dac_ops *ops;
+};
+typedef struct rt_dac_device *rt_dac_device_t;
+
+typedef enum
+{
+ RT_DAC_CMD_ENABLE,
+ RT_DAC_CMD_DISABLE,
+} rt_dac_cmd_t;
+
+rt_err_t rt_hw_dac_register(rt_dac_device_t dac,const char *name, const struct rt_dac_ops *ops, const void *user_data);
+
+rt_uint32_t rt_dac_write(rt_dac_device_t dev, rt_uint32_t channel, rt_uint32_t value);
+rt_err_t rt_dac_enable(rt_dac_device_t dev, rt_uint32_t channel);
+rt_err_t rt_dac_disable(rt_dac_device_t dev, rt_uint32_t channel);
+
+#endif /* __dac_H__ */
diff --git a/components/drivers/include/drivers/hwtimer.h b/components/drivers/include/drivers/hwtimer.h
index cbfeec2bf8..d00dbd8a13 100644
--- a/components/drivers/include/drivers/hwtimer.h
+++ b/components/drivers/include/drivers/hwtimer.h
@@ -70,7 +70,7 @@ typedef struct rt_hwtimer_device
rt_int32_t freq; /* counting frequency set by the user */
rt_int32_t overflow; /* timer overflows */
- float period_sec;
+ float period_sec;
rt_int32_t cycles; /* how many times will generate a timeout event after overflow */
rt_int32_t reload; /* reload cycles(using in period mode) */
rt_hwtimer_mode_t mode; /* timing mode(oneshot/period) */
diff --git a/components/drivers/include/drivers/i2c.h b/components/drivers/include/drivers/i2c.h
index 17d57288cd..d93e82fc2b 100644
--- a/components/drivers/include/drivers/i2c.h
+++ b/components/drivers/include/drivers/i2c.h
@@ -23,6 +23,7 @@ extern "C" {
#define RT_I2C_NO_START (1u << 4)
#define RT_I2C_IGNORE_NACK (1u << 5)
#define RT_I2C_NO_READ_ACK (1u << 6) /* when I2C reading, we do not ACK */
+#define RT_I2C_NO_STOP (1u << 7)
struct rt_i2c_msg
{
@@ -83,6 +84,17 @@ rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus,
rt_uint16_t flags,
rt_uint8_t *buf,
rt_uint32_t count);
+
+rt_inline rt_err_t rt_i2c_bus_lock(struct rt_i2c_bus_device *bus, rt_tick_t timeout)
+{
+ return rt_mutex_take(&bus->lock, timeout);
+}
+
+rt_inline rt_err_t rt_i2c_bus_unlock(struct rt_i2c_bus_device *bus)
+{
+ return rt_mutex_release(&bus->lock);
+}
+
int rt_i2c_core_init(void);
#ifdef __cplusplus
diff --git a/components/drivers/include/drivers/phy.h b/components/drivers/include/drivers/phy.h
new file mode 100644
index 0000000000..2d1ad9f91f
--- /dev/null
+++ b/components/drivers/include/drivers/phy.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-10-14 wangqiang the first version
+ */
+
+#ifndef __PHY_H__
+#define __PHY_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Defines the PHY link speed. This is align with the speed for MAC. */
+enum phy_speed
+{
+ PHY_SPEED_10M = 0U, /* PHY 10M speed. */
+ PHY_SPEED_100M /* PHY 100M speed. */
+};
+
+/* Defines the PHY link duplex. */
+enum phy_duplex
+{
+ PHY_HALF_DUPLEX = 0U, /* PHY half duplex. */
+ PHY_FULL_DUPLEX /* PHY full duplex. */
+};
+
+/*! @brief Defines the PHY loopback mode. */
+enum phy_loop
+{
+ PHY_LOCAL_LOOP = 0U, /* PHY local loopback. */
+ PHY_REMOTE_LOOP /* PHY remote loopback. */
+};
+
+
+struct rt_phy_msg
+{
+ rt_uint32_t reg;
+ rt_uint32_t value;
+};
+
+typedef struct rt_phy_msg rt_phy_msg_t;
+
+
+struct rt_phy_device
+{
+ struct rt_device parent;
+ struct rt_mdio_bus *bus;
+ rt_uint32_t addr;
+ struct rt_phy_ops *ops;
+};
+
+typedef struct rt_phy_device rt_phy_t;
+
+
+enum {
+ PHY_STATUS_OK = 0,
+ PHY_STATUS_FAIL,
+ PHY_STATUS_TIMEOUT,
+};
+
+typedef rt_int32_t rt_phy_status;
+
+struct rt_phy_ops
+{
+ rt_phy_status (*init)(void *object, rt_uint32_t phy_addr, rt_uint32_t src_clock_hz);
+ rt_phy_status (*read)(rt_uint32_t reg, rt_uint32_t *data);
+ rt_phy_status (*write)(rt_uint32_t reg, rt_uint32_t data);
+ rt_phy_status (*loopback)(rt_uint32_t mode, rt_uint32_t speed, rt_bool_t enable);
+ rt_phy_status (*get_link_status)(rt_bool_t *status);
+ rt_phy_status (*get_link_speed_duplex)(rt_uint32_t *speed, rt_uint32_t *duplex);
+};
+
+rt_err_t rt_hw_phy_register(struct rt_phy_device *phy, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PHY_H__*/
diff --git a/components/drivers/include/drivers/phy_mdio.h b/components/drivers/include/drivers/phy_mdio.h
new file mode 100644
index 0000000000..d978ec2984
--- /dev/null
+++ b/components/drivers/include/drivers/phy_mdio.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-10-14 wangqiang the first version
+ */
+
+#ifndef __MDIO_H__
+#define __MDIO_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+struct rt_mdio_bus_ops
+{
+ rt_bool_t (*init)(void *bus, rt_uint32_t src_clock_hz);
+ rt_size_t (*read)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size);
+ rt_size_t (*write)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size);
+ rt_bool_t (*uninit)(void *bus);
+};
+
+struct rt_mdio_bus
+{
+ void *hw_obj;
+ char *name;
+ struct rt_mdio_bus_ops *ops;
+};
+
+typedef struct rt_mdio_bus rt_mdio_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/drivers/pin.h b/components/drivers/include/drivers/pin.h
index ca35407932..f5b2ded9f6 100644
--- a/components/drivers/include/drivers/pin.h
+++ b/components/drivers/include/drivers/pin.h
@@ -74,10 +74,13 @@ struct rt_pin_ops
rt_uint32_t mode, void (*hdr)(void *args), void *args);
rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin);
rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled);
+ rt_base_t (*pin_get)(const char *name);
};
int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data);
+/* Get pin number by name,such as PA.0,P0.12 */
+rt_base_t rt_pin_get(const char *name);
void rt_pin_mode(rt_base_t pin, rt_base_t mode);
void rt_pin_write(rt_base_t pin, rt_base_t value);
int rt_pin_read(rt_base_t pin);
diff --git a/components/drivers/include/drivers/pm.h b/components/drivers/include/drivers/pm.h
index dd5875aa1d..f28283dcf8 100644
--- a/components/drivers/include/drivers/pm.h
+++ b/components/drivers/include/drivers/pm.h
@@ -8,6 +8,8 @@
* 2012-06-02 Bernard the first version
* 2018-08-02 Tanek split run and sleep modes, support custom mode
* 2019-04-28 Zero-Free improve PM mode and device ops interface
+ * 2020-11-23 zhangsz update pm mode select
+ * 2020-11-27 zhangsz update pm 2.0
*/
#ifndef __PM_H__
@@ -45,7 +47,8 @@ enum
RT_PM_FREQUENCY_PENDING = 0x01,
};
-#define RT_PM_DEFAULT_SLEEP_MODE PM_SLEEP_MODE_IDLE
+#define RT_PM_DEFAULT_SLEEP_MODE PM_SLEEP_MODE_NONE
+#define RT_PM_DEFAULT_DEEPSLEEP_MODE PM_SLEEP_MODE_DEEP
#define RT_PM_DEFAULT_RUN_MODE PM_RUN_MODE_NORMAL_SPEED
/* The name of all modes used in the msh command "pm_dump" */
@@ -67,6 +70,33 @@ enum
"Low Mode", \
}
+/**
+ * Modules used for
+ * pm_module_request(PM_BOARD_ID, PM_SLEEP_MODE_IDLE)
+ * pm_module_release(PM_BOARD_ID, PM_SLEEP_MODE_IDLE)
+ * pm_module_release_all(PM_BOARD_ID, PM_SLEEP_MODE_IDLE)
+ */
+enum pm_module_id {
+ PM_NONE_ID = 0,
+ PM_POWER_ID,
+ PM_BOARD_ID,
+ PM_BSP_ID,
+ PM_MAIN_ID,
+ PM_PMS_ID,
+ PM_PMC_ID,
+ PM_TASK_ID,
+ PM_SPI_ID,
+ PM_I2C_ID,
+ PM_UART_ID,
+ PM_CAN_ID,
+ PM_ETH_ID,
+ PM_SENSOR_ID,
+ PM_LCD_ID,
+ PM_KEY_ID,
+ PM_TP_ID,
+ PM_MODULE_MAX_ID, /* enum must! */
+};
+
#else /* PM_HAS_CUSTOM_CONFIG */
#include <pm_cfg.h>
@@ -106,6 +136,14 @@ struct rt_device_pm
const struct rt_device_pm_ops *ops;
};
+struct rt_pm_module
+{
+ rt_uint8_t req_status;
+ rt_bool_t busy_flag;
+ rt_uint32_t timeout;
+ rt_uint32_t start_time;
+};
+
/**
* power management
*/
@@ -118,6 +156,9 @@ struct rt_pm
rt_uint8_t sleep_mode; /* current sleep mode */
rt_uint8_t run_mode; /* current running mode */
+ /* modules request status*/
+ struct rt_pm_module module_status[PM_MODULE_MAX_ID];
+
/* the list of device, which has PM feature */
rt_uint8_t device_pm_number;
struct rt_device_pm *device_pm;
@@ -143,6 +184,7 @@ struct rt_pm_notify
void rt_pm_request(rt_uint8_t sleep_mode);
void rt_pm_release(rt_uint8_t sleep_mode);
+void rt_pm_release_all(rt_uint8_t sleep_mode);
int rt_pm_run_enter(rt_uint8_t run_mode);
void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops);
@@ -154,5 +196,11 @@ void rt_pm_default_set(rt_uint8_t sleep_mode);
void rt_system_pm_init(const struct rt_pm_ops *ops,
rt_uint8_t timer_mask,
void *user_data);
+void rt_pm_module_request(uint8_t module_id, rt_uint8_t sleep_mode);
+void rt_pm_module_release(uint8_t module_id, rt_uint8_t sleep_mode);
+void rt_pm_module_release_all(uint8_t module_id, rt_uint8_t sleep_mode);
+void rt_pm_module_delay_sleep(rt_uint8_t module_id, rt_tick_t timeout);
+rt_uint32_t rt_pm_module_get_status(void);
+rt_uint8_t rt_pm_get_sleep_mode(void);
#endif /* __PM_H__ */
diff --git a/components/drivers/include/drivers/rt_drv_pwm.h b/components/drivers/include/drivers/rt_drv_pwm.h
index 16de4c6ab8..7a8e17b916 100644
--- a/components/drivers/include/drivers/rt_drv_pwm.h
+++ b/components/drivers/include/drivers/rt_drv_pwm.h
@@ -18,12 +18,20 @@
#define PWM_CMD_DISABLE (128 + 1)
#define PWM_CMD_SET (128 + 2)
#define PWM_CMD_GET (128 + 3)
+#define PWMN_CMD_ENABLE (128 + 4)
+#define PWMN_CMD_DISABLE (128 + 5)
struct rt_pwm_configuration
{
rt_uint32_t channel; /* 0-n */
rt_uint32_t period; /* unit:ns 1ns~4.29s:1Ghz~0.23hz */
rt_uint32_t pulse; /* unit:ns (pulse<=period) */
+
+ /*
+ * RT_TRUE : The channel of pwm is complememtary.
+ * RT_FALSE : The channel of pwm is nomal.
+ */
+ rt_bool_t complementary;
};
struct rt_device_pwm;
diff --git a/components/drivers/include/drivers/spi.h b/components/drivers/include/drivers/spi.h
index 301726fda8..d92518cd94 100644
--- a/components/drivers/include/drivers/spi.h
+++ b/components/drivers/include/drivers/spi.h
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-11-23 Bernard Add extern "C"
+ * 2020-06-13 armink fix the 3 wires issue
*/
#ifndef __SPI_H__
@@ -18,8 +19,6 @@
extern "C"{
#endif
-#define RT_SPI_CPHA (1<<0) /* bit[0]:CPHA, clock phase */
-#define RT_SPI_CPOL (1<<1) /* bit[1]:CPOL, clock polarity */
/**
* At CPOL=0 the base value of the clock is zero
* - For CPHA=0, data are captured on the clock's rising edge (low->high transition)
@@ -32,26 +31,29 @@ extern "C"{
* - For CPHA=1, data are captured on clock's rising edge and data are propagated
* on a falling edge.
*/
+#define RT_SPI_CPHA (1<<0) /* bit[0]:CPHA, clock phase */
+#define RT_SPI_CPOL (1<<1) /* bit[1]:CPOL, clock polarity */
+
#define RT_SPI_LSB (0<<2) /* bit[2]: 0-LSB */
#define RT_SPI_MSB (1<<2) /* bit[2]: 1-MSB */
#define RT_SPI_MASTER (0<<3) /* SPI master device */
#define RT_SPI_SLAVE (1<<3) /* SPI slave device */
+#define RT_SPI_CS_HIGH (1<<4) /* Chipselect active high */
+#define RT_SPI_NO_CS (1<<5) /* No chipselect */
+#define RT_SPI_3WIRE (1<<6) /* SI/SO pin shared */
+#define RT_SPI_READY (1<<7) /* Slave pulls low to pause */
+
+#define RT_SPI_MODE_MASK (RT_SPI_CPHA | RT_SPI_CPOL | RT_SPI_MSB | RT_SPI_SLAVE | RT_SPI_CS_HIGH | RT_SPI_NO_CS | RT_SPI_3WIRE | RT_SPI_READY)
+
#define RT_SPI_MODE_0 (0 | 0) /* CPOL = 0, CPHA = 0 */
#define RT_SPI_MODE_1 (0 | RT_SPI_CPHA) /* CPOL = 0, CPHA = 1 */
#define RT_SPI_MODE_2 (RT_SPI_CPOL | 0) /* CPOL = 1, CPHA = 0 */
#define RT_SPI_MODE_3 (RT_SPI_CPOL | RT_SPI_CPHA) /* CPOL = 1, CPHA = 1 */
-#define RT_SPI_MODE_MASK (RT_SPI_CPHA | RT_SPI_CPOL | RT_SPI_MSB | RT_SPI_SLAVE)
-
-#define RT_SPI_BUS_MODE_SPI (1<<0)
-#define RT_SPI_BUS_MODE_QSPI (1<<1)
-
-#define RT_SPI_CS_HIGH (1<<4) /* Chipselect active high */
-#define RT_SPI_NO_CS (1<<5) /* No chipselect */
-#define RT_SPI_3WIRE (1<<6) /* SI/SO pin shared */
-#define RT_SPI_READY (1<<7) /* Slave pulls low to pause */
+#define RT_SPI_BUS_MODE_SPI (1<<0)
+#define RT_SPI_BUS_MODE_QSPI (1<<1)
/**
* SPI message structure
diff --git a/components/drivers/include/drivers/usb_common.h b/components/drivers/include/drivers/usb_common.h
index c26d83391e..4d85a85e35 100644
--- a/components/drivers/include/drivers/usb_common.h
+++ b/components/drivers/include/drivers/usb_common.h
@@ -435,15 +435,15 @@ typedef struct usb_os_proerty * usb_os_proerty_t;
// 5 A big-endian 32-bit integer (REG_DWORD_BIG_ENDIAN)
// 6 A NULL-terminated Unicode string that contains a symbolic link (REG_LINK)
// 7 Multiple NULL-terminated Unicode strings (REG_MULTI_SZ)
-#define USB_OS_PROERTY_TYPE_REG_SZ 0x01UL
-#define USB_OS_PROERTY_TYPE_REG_EXPAND_SZ 0x02UL
-#define USB_OS_PROERTY_TYPE_REG_BINARY 0x03UL
-#define USB_OS_PROERTY_TYPE_REG_DWORD_LITTLE_ENDIAN 0x04UL
-#define USB_OS_PROERTY_TYPE_REG_DWORD_BIG_ENDIAN 0x05UL
-#define USB_OS_PROERTY_TYPE_REG_LINK 0x06UL
-#define USB_OS_PROERTY_TYPE_REG_MULTI_SZ 0x07UL
+#define USB_OS_PROPERTY_TYPE_REG_SZ 0x01UL
+#define USB_OS_PROPERTY_TYPE_REG_EXPAND_SZ 0x02UL
+#define USB_OS_PROPERTY_TYPE_REG_BINARY 0x03UL
+#define USB_OS_PROPERTY_TYPE_REG_DWORD_LITTLE_ENDIAN 0x04UL
+#define USB_OS_PROPERTY_TYPE_REG_DWORD_BIG_ENDIAN 0x05UL
+#define USB_OS_PROPERTY_TYPE_REG_LINK 0x06UL
+#define USB_OS_PROPERTY_TYPE_REG_MULTI_SZ 0x07UL
-#define USB_OS_PROERTY_DESC(PropertyDataType,PropertyName,PropertyData) \
+#define USB_OS_PROPERTY_DESC(PropertyDataType,PropertyName,PropertyData) \
{\
.dwSize = sizeof(struct usb_os_proerty)-sizeof(const char *)*2\
+sizeof(PropertyName)*2+sizeof(PropertyData)*2,\
diff --git a/components/drivers/include/ipc/dataqueue.h b/components/drivers/include/ipc/dataqueue.h
index d90be76ffb..76203c404d 100644
--- a/components/drivers/include/ipc/dataqueue.h
+++ b/components/drivers/include/ipc/dataqueue.h
@@ -17,8 +17,7 @@
#define RT_DATAQUEUE_EVENT_LWM 0x03
struct rt_data_item;
-#define RT_DATAQUEUE_SIZE(dq) ((dq)->put_index - (dq)->get_index)
-#define RT_DATAQUEUE_EMPTY(dq) ((dq)->size - RT_DATAQUEUE_SIZE(dq))
+
/* data queue implementation */
struct rt_data_queue
{
@@ -26,10 +25,11 @@ struct rt_data_queue
rt_uint16_t size;
rt_uint16_t lwm;
- rt_bool_t waiting_lwm;
- rt_uint16_t get_index;
- rt_uint16_t put_index;
+ rt_uint16_t get_index : 15;
+ rt_uint16_t is_empty : 1;
+ rt_uint16_t put_index : 15;
+ rt_uint16_t is_full : 1;
struct rt_data_item *queue;
@@ -55,10 +55,11 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
const void **data_ptr,
rt_size_t *size,
rt_int32_t timeout);
-rt_err_t rt_data_queue_peak(struct rt_data_queue *queue,
+rt_err_t rt_data_queue_peek(struct rt_data_queue *queue,
const void **data_ptr,
rt_size_t *size);
void rt_data_queue_reset(struct rt_data_queue *queue);
rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue);
+rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue);
#endif
diff --git a/components/drivers/include/ipc/ringbuffer.h b/components/drivers/include/ipc/ringbuffer.h
index 4487d02c47..2afd2ca213 100644
--- a/components/drivers/include/ipc/ringbuffer.h
+++ b/components/drivers/include/ipc/ringbuffer.h
@@ -71,6 +71,7 @@ rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *pt
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_putchar_force(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint16_t length);
+rt_size_t rt_ringbuffer_peak(struct rt_ringbuffer *rb, rt_uint8_t **ptr);
rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch);
rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb);
diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h
index 623c085430..f0fa2f5b4a 100644
--- a/components/drivers/include/rtdevice.h
+++ b/components/drivers/include/rtdevice.h
@@ -69,6 +69,11 @@ extern "C" {
#endif /* RT_USING_I2C_BITOPS */
#endif /* RT_USING_I2C */
+#ifdef RT_USING_PHY
+#include "drivers/phy.h"
+#include "drivers/phy_mdio.h"
+#endif /* RT_USING_PHY */
+
#ifdef RT_USING_SDIO
#include "drivers/mmcsd_core.h"
#include "drivers/sd.h"
@@ -103,6 +108,10 @@ extern "C" {
#include "drivers/adc.h"
#endif
+#ifdef RT_USING_DAC
+#include "drivers/dac.h"
+#endif
+
#ifdef RT_USING_PWM
#include "drivers/rt_drv_pwm.h"
#endif
diff --git a/components/drivers/misc/SConscript b/components/drivers/misc/SConscript
index 8a9fdb5eb9..72058eeeca 100644
--- a/components/drivers/misc/SConscript
+++ b/components/drivers/misc/SConscript
@@ -11,6 +11,9 @@ if GetDepend(['RT_USING_PIN']):
if GetDepend(['RT_USING_ADC']):
src = src + ['adc.c']
+if GetDepend(['RT_USING_DAC']):
+ src = src + ['dac.c']
+
if GetDepend(['RT_USING_PWM']):
src = src + ['rt_drv_pwm.c']
diff --git a/components/drivers/misc/dac.c b/components/drivers/misc/dac.c
new file mode 100644
index 0000000000..336c78d018
--- /dev/null
+++ b/components/drivers/misc/dac.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-19 thread-liu the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#define DBG_TAG "dac"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+static rt_size_t _dac_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ rt_err_t result = RT_EOK;
+ rt_size_t i;
+ struct rt_dac_device *dac = (struct rt_dac_device *)dev;
+ rt_uint32_t *value = (rt_uint32_t *)buffer;
+
+ for (i = 0; i < size; i += sizeof(int))
+ {
+ result = dac->ops->convert(dac, pos + i, value);
+ if (result != RT_EOK)
+ {
+ return 0;
+ }
+ value++;
+ }
+
+ return i;
+}
+
+static rt_err_t _dac_control(rt_device_t dev, int cmd, void *args)
+{
+ rt_err_t result = RT_EOK;
+ rt_dac_device_t dac = (struct rt_dac_device *)dev;
+
+ if (dac->ops->enabled == RT_NULL)
+ {
+ return -RT_ENOSYS;
+ }
+ if (cmd == RT_DAC_CMD_ENABLE)
+ {
+ result = dac->ops->enabled(dac, (rt_uint32_t)args);
+ }
+ else if (cmd == RT_DAC_CMD_DISABLE)
+ {
+ result = dac->ops->disabled(dac, (rt_uint32_t)args);
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops dac_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ _dac_write,
+ _dac_control,
+};
+#endif
+
+rt_err_t rt_hw_dac_register(rt_dac_device_t device, const char *name, const struct rt_dac_ops *ops, const void *user_data)
+{
+ rt_err_t result = RT_EOK;
+ RT_ASSERT(ops != RT_NULL && ops->convert != RT_NULL);
+
+ device->parent.type = RT_Device_Class_Miscellaneous;
+ device->parent.rx_indicate = RT_NULL;
+ device->parent.tx_complete = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->parent.ops = &dac_ops;
+#else
+ device->parent.init = RT_NULL;
+ device->parent.open = RT_NULL;
+ device->parent.close = RT_NULL;
+ device->parent.read = RT_NULL;
+ device->parent.write = _dac_write;
+ device->parent.control = _dac_control;
+#endif
+ device->ops = ops;
+ device->parent.user_data = (void *)user_data;
+
+ result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
+
+ return result;
+}
+
+rt_uint32_t rt_dac_write(rt_dac_device_t dev, rt_uint32_t channel, rt_uint32_t value)
+{
+ RT_ASSERT(dev);
+
+ dev->ops->convert(dev, channel, &value);
+
+ return RT_EOK;
+}
+
+rt_err_t rt_dac_enable(rt_dac_device_t dev, rt_uint32_t channel)
+{
+ rt_err_t result = RT_EOK;
+
+ RT_ASSERT(dev);
+ if (dev->ops->enabled != RT_NULL)
+ {
+ result = dev->ops->enabled(dev, channel);
+ }
+ else
+ {
+ result = -RT_ENOSYS;
+ }
+
+ return result;
+}
+
+rt_err_t rt_dac_disabled(rt_dac_device_t dev, rt_uint32_t channel)
+{
+ rt_err_t result = RT_EOK;
+
+ RT_ASSERT(dev);
+ if (dev->ops->disabled != RT_NULL)
+ {
+ result = dev->ops->disabled(dev, channel);
+ }
+ else
+ {
+ result = -RT_ENOSYS;
+ }
+
+ return result;
+}
+
+#ifdef FINSH_USING_MSH
+
+static int dac(int argc, char **argv)
+{
+ int result = RT_EOK;
+ static rt_dac_device_t dac_device = RT_NULL;
+ char *result_str;
+
+ if (argc > 1)
+ {
+ if (!strcmp(argv[1], "probe"))
+ {
+ if (argc == 3)
+ {
+ dac_device = (rt_dac_device_t)rt_device_find(argv[2]);
+ result_str = (dac_device == RT_NULL) ? "failure" : "success";
+ rt_kprintf("probe %s %s \n", argv[2], result_str);
+ }
+ else
+ {
+ rt_kprintf("dac probe <dac_name> - probe dac by name\n");
+ }
+ }
+ else
+ {
+ if (dac_device == RT_NULL)
+ {
+ rt_kprintf("Please using 'dac probe <dac_name>' first\n");
+ return -RT_ERROR;
+ }
+ if (!strcmp(argv[1], "enable"))
+ {
+ if (argc == 3)
+ {
+ result = rt_dac_enable(dac_device, atoi(argv[2]));
+ result_str = (result == RT_EOK) ? "success" : "failure";
+ rt_kprintf("%s channel %d enables %s \n", dac_device->parent.parent.name, atoi(argv[2]), result_str);
+ }
+ else
+ {
+ rt_kprintf("dac enable <channel> - enable dac channel\n");
+ }
+ }
+ else if (!strcmp(argv[1], "write"))
+ {
+ if (argc == 4)
+ {
+ rt_dac_write(dac_device, atoi(argv[2]), atoi(argv[3]));
+ rt_kprintf("%s channel %d write value is %d \n", dac_device->parent.parent.name, atoi(argv[2]), atoi(argv[3]));
+ }
+ else
+ {
+ rt_kprintf("dac write <channel> <value> - write dac value on the channel\n");
+ }
+ }
+ else if (!strcmp(argv[1], "disable"))
+ {
+ if (argc == 3)
+ {
+ result = rt_dac_disabled(dac_device, atoi(argv[2]));
+ result_str = (result == RT_EOK) ? "success" : "failure";
+ rt_kprintf("%s channel %d disable %s \n", dac_device->parent.parent.name, atoi(argv[2]), result_str);
+ }
+ else
+ {
+ rt_kprintf("dac disable <channel> - disable dac channel\n");
+ }
+ }
+ else
+ {
+ rt_kprintf("Unknown command. Please enter 'dac' for help\n");
+ }
+ }
+ }
+ else
+ {
+ rt_kprintf("Usage: \n");
+ rt_kprintf("dac probe <dac_name> - probe dac by name\n");
+ rt_kprintf("dac write <channel> <value> - write dac value on the channel\n");
+ rt_kprintf("dac disable <channel> - disable dac channel\n");
+ rt_kprintf("dac enable <channel> - enable dac channel\n");
+ result = -RT_ERROR;
+ }
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(dac, dac function);
+
+#endif /* FINSH_USING_MSH */
diff --git a/components/drivers/misc/pin.c b/components/drivers/misc/pin.c
index aca58ee21b..6f27fe516d 100644
--- a/components/drivers/misc/pin.c
+++ b/components/drivers/misc/pin.c
@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2015-01-20 Bernard the first version
+ * 2021-02-06 Meco Man fix RT_ENOSYS code in negative
*/
#include <drivers/pin.h>
@@ -108,7 +109,7 @@ rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,
{
return _hw_pin.ops->pin_attach_irq(&_hw_pin.parent, pin, mode, hdr, args);
}
- return RT_ENOSYS;
+ return -RT_ENOSYS;
}
rt_err_t rt_pin_detach_irq(rt_int32_t pin)
{
@@ -117,7 +118,7 @@ rt_err_t rt_pin_detach_irq(rt_int32_t pin)
{
return _hw_pin.ops->pin_detach_irq(&_hw_pin.parent, pin);
}
- return RT_ENOSYS;
+ return -RT_ENOSYS;
}
rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled)
@@ -127,7 +128,7 @@ rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled)
{
return _hw_pin.ops->pin_irq_enable(&_hw_pin.parent, pin, enabled);
}
- return RT_ENOSYS;
+ return -RT_ENOSYS;
}
/* RT-Thread Hardware PIN APIs */
@@ -151,3 +152,18 @@ int rt_pin_read(rt_base_t pin)
return _hw_pin.ops->pin_read(&_hw_pin.parent, pin);
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_read, pinRead, read status from hardware pin);
+
+rt_base_t rt_pin_get(const char *name)
+{
+ RT_ASSERT(_hw_pin.ops != RT_NULL);
+ RT_ASSERT(name[0] == 'P');
+
+ if(_hw_pin.ops->pin_get == RT_NULL)
+ {
+ return -RT_ENOSYS;
+ }
+
+ return _hw_pin.ops->pin_get(name);
+}
+FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_get, pinGet, get pin number from hardware pin);
+
diff --git a/components/drivers/misc/rt_drv_pwm.c b/components/drivers/misc/rt_drv_pwm.c
index 97d38d51b3..572580c45c 100644
--- a/components/drivers/misc/rt_drv_pwm.c
+++ b/components/drivers/misc/rt_drv_pwm.c
@@ -136,7 +136,8 @@ rt_err_t rt_pwm_enable(struct rt_device_pwm *device, int channel)
return -RT_EIO;
}
- configuration.channel = channel;
+ configuration.channel = (channel > 0) ? (channel) : (-channel); /* Make it is positive num forever */
+ configuration.complementary = (channel > 0) ? (RT_FALSE) : (RT_TRUE); /* If nagetive, it's complementary */
result = rt_device_control(&device->parent, PWM_CMD_ENABLE, &configuration);
return result;
@@ -152,7 +153,8 @@ rt_err_t rt_pwm_disable(struct rt_device_pwm *device, int channel)
return -RT_EIO;
}
- configuration.channel = channel;
+ configuration.channel = (channel > 0) ? (channel) : (-channel); /* Make it is positive num forever */
+ configuration.complementary = (channel > 0) ? (RT_FALSE) : (RT_TRUE); /* If nagetive, it's complementary */
result = rt_device_control(&device->parent, PWM_CMD_DISABLE, &configuration);
return result;
@@ -176,6 +178,20 @@ rt_err_t rt_pwm_set(struct rt_device_pwm *device, int channel, rt_uint32_t perio
return result;
}
+rt_err_t rt_pwm_get(struct rt_device_pwm *device, struct rt_pwm_configuration *cfg)
+{
+ rt_err_t result = RT_EOK;
+
+ if (!device)
+ {
+ return -RT_EIO;
+ }
+
+ result = rt_device_control(&device->parent, PWM_CMD_GET, cfg);
+
+ return result;
+}
+
#ifdef RT_USING_FINSH
#include <finsh.h>
@@ -191,6 +207,7 @@ static int pwm_enable(int argc, char **argv)
if (argc != 3)
{
rt_kprintf("Usage: pwm_enable pwm1 1\n");
+ rt_kprintf(" pwm_enable <pwm_dev> <channel/-channel>\n");
result = -RT_ERROR;
goto _exit;
}
@@ -202,12 +219,13 @@ static int pwm_enable(int argc, char **argv)
goto _exit;
}
+ /* If channel is complementary(1), make the channel number to nagetive */
result = rt_pwm_enable(device, atoi(argv[2]));
_exit:
return result;
}
-MSH_CMD_EXPORT(pwm_enable, pwm_enable pwm1 1);
+MSH_CMD_EXPORT(pwm_enable, pwm_enable <pwm_dev> <channel/-channel>);
static int pwm_disable(int argc, char **argv)
{
@@ -216,7 +234,8 @@ static int pwm_disable(int argc, char **argv)
if (argc != 3)
{
- rt_kprintf("Usage: pwm_enable pwm1 1\n");
+ rt_kprintf("Usage: pwm_disable pwm1 1\n");
+ rt_kprintf(" pwm_disable <pwm_dev> <channel/-channel> \n");
result = -RT_ERROR;
goto _exit;
}
@@ -228,12 +247,13 @@ static int pwm_disable(int argc, char **argv)
goto _exit;
}
+ /* If channel is complementary(1), make the channel number to nagetive */
result = rt_pwm_disable(device, atoi(argv[2]));
_exit:
return result;
}
-MSH_CMD_EXPORT(pwm_disable, pwm_disable pwm1 1);
+MSH_CMD_EXPORT(pwm_disable, pwm_disable <pwm_dev> <channel/-channel>);
static int pwm_set(int argc, char **argv)
{
@@ -243,6 +263,7 @@ static int pwm_set(int argc, char **argv)
if (argc != 5)
{
rt_kprintf("Usage: pwm_set pwm1 1 100 50\n");
+ rt_kprintf("Usage: pwm_set <pwm_dev> <channel> <period> <pulse>\n");
result = -RT_ERROR;
goto _exit;
}
@@ -259,7 +280,48 @@ static int pwm_set(int argc, char **argv)
_exit:
return result;
}
-MSH_CMD_EXPORT(pwm_set, pwm_set pwm1 1 100 50);
+MSH_CMD_EXPORT(pwm_set, pwm_set <pwm_dev> <channel> <period> <pulse>);
+
+
+static int pwm_get(int argc, char **argv)
+{
+ int result = 0;
+ struct rt_device_pwm *device = RT_NULL;
+ struct rt_pwm_configuration cfg = {0};
+
+ if (argc != 3)
+ {
+ rt_kprintf("Usage: pwm_get pwm1 1\n");
+ rt_kprintf(" pwm_get <pwm_dev> <channel>\n");
+ result = -RT_ERROR;
+ goto _exit;
+ }
+
+ device = (struct rt_device_pwm *)rt_device_find(argv[1]);
+ if (!device)
+ {
+ result = -RT_EIO;
+ goto _exit;
+ }
+
+ cfg.channel = atoi(argv[2]);
+ result = rt_pwm_get(device, &cfg);
+ if (result != RT_EOK)
+ {
+ rt_kprintf("Get info of device: [%s] error.\n", argv[1]);
+ }
+ else
+ {
+ rt_kprintf("Get info of device: [%s]:\n", argv[1]);
+ rt_kprintf("period : %d\n", cfg.period);
+ rt_kprintf("pulse : %d\n", cfg.pulse);
+ rt_kprintf("Duty cycle : %d%%\n", (int)(((double)(cfg.pulse)/(cfg.period)) * 100));
+ }
+
+_exit:
+ return result;
+}
+MSH_CMD_EXPORT(pwm_get, pwm_get <pwm_dev> <channel>);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */
diff --git a/components/drivers/phy/SConscript b/components/drivers/phy/SConscript
new file mode 100644
index 0000000000..ec12ed24c2
--- /dev/null
+++ b/components/drivers/phy/SConscript
@@ -0,0 +1,8 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+CPPPATH = [cwd + '/../include']
+group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_PHY'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/drivers/phy/phy.c b/components/drivers/phy/phy.c
new file mode 100644
index 0000000000..3ed4a1a265
--- /dev/null
+++ b/components/drivers/phy/phy.c
@@ -0,0 +1,78 @@
+
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-09-27 wangqiang first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "PHY"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+
+static rt_size_t phy_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t count)
+{
+ struct rt_phy_device *phy = (struct rt_phy_device *)dev->user_data;
+ struct rt_phy_msg *msg = (struct rt_phy_msg *)buffer;
+ return phy->bus->ops->read(phy->bus, phy->addr, msg->reg, &(msg->value), 4);
+}
+static rt_size_t phy_device_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t count)
+{
+ struct rt_phy_device *phy = (struct rt_phy_device *)dev->user_data;
+ struct rt_phy_msg *msg = (struct rt_phy_msg *)buffer;
+ return phy->bus->ops->write(phy->bus, phy->addr, msg->reg, &(msg->value), 4);
+}
+
+
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops phy_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ phy_device_read,
+ phy_device_write,
+ RT_NULL,
+};
+#endif
+
+/*
+* phy device register
+*/
+rt_err_t rt_hw_phy_register(struct rt_phy_device *phy, const char *name)
+{
+ rt_err_t ret;
+ struct rt_device *device;
+
+ device = &(phy->parent);
+
+ device->type = RT_Device_Class_PHY;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = phy_ops;
+#else
+ device->init = NULL;
+ device->open = NULL;
+ device->close = NULL;
+ device->read = phy_device_read;
+ device->write = phy_device_write;
+ device->control = NULL;
+#endif
+ device->user_data = phy;
+
+ /* register a character device */
+ ret = rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
+
+ return ret;
+}
diff --git a/components/drivers/pm/pm.c b/components/drivers/pm/pm.c
index dd7cc2ae63..743a184555 100644
--- a/components/drivers/pm/pm.c
+++ b/components/drivers/pm/pm.c
@@ -8,6 +8,8 @@
* 2012-06-02 Bernard the first version
* 2018-08-02 Tanek split run and sleep modes, support custom mode
* 2019-04-28 Zero-Free improve PM mode and device ops interface
+ * 2020-11-23 zhangsz update pm mode select
+ * 2020-11-27 zhangsz update pm 2.0
*/
#include <rthw.h>
@@ -17,7 +19,13 @@
#ifdef RT_USING_PM
static struct rt_pm _pm;
+
+/* default mode : system power on */
static rt_uint8_t _pm_default_sleep = RT_PM_DEFAULT_SLEEP_MODE;
+
+/* default deepsleep mode : tick-less mode */
+static rt_uint8_t _pm_default_deepsleep = RT_PM_DEFAULT_DEEPSLEEP_MODE;
+
static struct rt_pm_notify _pm_notify;
static rt_uint8_t _pm_init_flag = 0;
@@ -111,7 +119,7 @@ static rt_uint8_t _pm_select_sleep_mode(struct rt_pm *pm)
int index;
rt_uint8_t mode;
- mode = _pm_default_sleep;
+ mode = _pm_default_deepsleep;
for (index = PM_SLEEP_MODE_NONE; index < PM_SLEEP_MODE_MAX; index ++)
{
if (pm->modes[index])
@@ -126,41 +134,101 @@ static rt_uint8_t _pm_select_sleep_mode(struct rt_pm *pm)
}
/**
+ * pm module request delay sleep.
+ */
+void rt_pm_module_delay_sleep(rt_uint8_t module_id, rt_tick_t timeout)
+{
+ rt_base_t level;
+ struct rt_pm *pm;
+
+ if (_pm_init_flag == 0)
+ return;
+
+ if (module_id > (PM_MODULE_MAX_ID - 1))
+ return;
+
+ level = rt_hw_interrupt_disable();
+ pm = &_pm;
+ pm->module_status[module_id].busy_flag = RT_TRUE;
+ pm->module_status[module_id].timeout = timeout;
+ pm->module_status[module_id].start_time = rt_tick_get();
+ rt_hw_interrupt_enable(level);
+}
+
+/**
+ * This function check if all modules in idle status.
+ */
+static rt_bool_t _pm_device_check_idle(void)
+{
+ struct rt_pm *pm;
+
+ if (_pm_init_flag == 0)
+ return RT_TRUE;
+
+ pm = &_pm;
+ for (int i = 0; i < PM_MODULE_MAX_ID; i++)
+ {
+ if (pm->module_status[i].busy_flag == RT_TRUE)
+ {
+ if (rt_tick_get() - pm->module_status[i].start_time > pm->module_status[i].timeout)
+ {
+ pm->module_status[i].busy_flag = RT_FALSE;
+ pm->module_status[i].timeout = 0x00;
+ }
+ }
+ if (pm->module_status[i].busy_flag == RT_TRUE)
+ {
+ return RT_FALSE;
+ }
+ }
+
+ return RT_TRUE;
+}
+
+/**
* This function changes the power sleep mode base on the result of selection
*/
-static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode)
+static void _pm_change_sleep_mode(struct rt_pm *pm)
{
rt_tick_t timeout_tick, delta_tick;
rt_base_t level;
int ret = RT_EOK;
- if (mode == PM_SLEEP_MODE_NONE)
+ level = rt_pm_enter_critical(pm->sleep_mode);
+
+ /* module busy request */
+ if (_pm_device_check_idle() == RT_FALSE)
+ {
+ pm->ops->sleep(pm, PM_SLEEP_MODE_NONE);
+ rt_pm_exit_critical(level, pm->sleep_mode);
+ return;
+ }
+
+ if (_pm.sleep_mode == PM_SLEEP_MODE_NONE)
{
- pm->sleep_mode = mode;
pm->ops->sleep(pm, PM_SLEEP_MODE_NONE);
+ rt_pm_exit_critical(level, pm->sleep_mode);
}
else
{
- level = rt_pm_enter_critical(mode);
-
/* Notify app will enter sleep mode */
if (_pm_notify.notify)
- _pm_notify.notify(RT_PM_ENTER_SLEEP, mode, _pm_notify.data);
+ _pm_notify.notify(RT_PM_ENTER_SLEEP, pm->sleep_mode, _pm_notify.data);
/* Suspend all peripheral device */
- ret = _pm_device_suspend(mode);
+ ret = _pm_device_suspend(pm->sleep_mode);
if (ret != RT_EOK)
{
- _pm_device_resume(mode);
+ _pm_device_resume(pm->sleep_mode);
if (_pm_notify.notify)
- _pm_notify.notify(RT_PM_EXIT_SLEEP, mode, _pm_notify.data);
- rt_pm_exit_critical(level, mode);
+ _pm_notify.notify(RT_PM_EXIT_SLEEP, pm->sleep_mode, _pm_notify.data);
+ rt_pm_exit_critical(level, pm->sleep_mode);
return;
}
/* Tickless*/
- if (pm->timer_mask & (0x01 << mode))
+ if (pm->timer_mask & (0x01 << pm->sleep_mode))
{
timeout_tick = rt_timer_next_timeout_tick();
if (timeout_tick == RT_TICK_MAX)
@@ -175,7 +243,7 @@ static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode)
timeout_tick = timeout_tick - rt_tick_get();
if (timeout_tick < RT_PM_TICKLESS_THRESH)
{
- mode = PM_SLEEP_MODE_IDLE;
+ pm->sleep_mode = PM_SLEEP_MODE_IDLE;
}
else
{
@@ -185,17 +253,16 @@ static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode)
}
/* enter lower power state */
- pm->ops->sleep(pm, mode);
+ pm->ops->sleep(pm, pm->sleep_mode);
/* wake up from lower power state*/
- if (pm->timer_mask & (0x01 << mode))
+ if (pm->timer_mask & (0x01 << pm->sleep_mode))
{
delta_tick = pm->ops->timer_get_tick(pm);
pm->ops->timer_stop(pm);
if (delta_tick)
{
rt_tick_set(rt_tick_get() + delta_tick);
- rt_timer_check();
}
}
@@ -203,9 +270,17 @@ static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode)
_pm_device_resume(pm->sleep_mode);
if (_pm_notify.notify)
- _pm_notify.notify(RT_PM_EXIT_SLEEP, mode, _pm_notify.data);
+ _pm_notify.notify(RT_PM_EXIT_SLEEP, pm->sleep_mode, _pm_notify.data);
+
+ rt_pm_exit_critical(level, pm->sleep_mode);
- rt_pm_exit_critical(level, mode);
+ if (pm->timer_mask & (0x01 << pm->sleep_mode))
+ {
+ if (delta_tick)
+ {
+ rt_timer_check();
+ }
+ }
}
}
@@ -214,8 +289,6 @@ static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode)
*/
void rt_system_power_manager(void)
{
- rt_uint8_t mode;
-
if (_pm_init_flag == 0)
return;
@@ -223,8 +296,7 @@ void rt_system_power_manager(void)
_pm_frequency_scaling(&_pm);
/* Low Power Mode Processing */
- mode = _pm_select_sleep_mode(&_pm);
- _pm_change_sleep_mode(&_pm, mode);
+ _pm_change_sleep_mode(&_pm);
}
/**
@@ -248,6 +320,7 @@ void rt_pm_request(rt_uint8_t mode)
pm = &_pm;
if (pm->modes[mode] < 255)
pm->modes[mode] ++;
+ _pm_select_sleep_mode(pm);
rt_hw_interrupt_enable(level);
}
@@ -273,6 +346,121 @@ void rt_pm_release(rt_uint8_t mode)
pm = &_pm;
if (pm->modes[mode] > 0)
pm->modes[mode] --;
+ _pm_select_sleep_mode(pm);
+ rt_hw_interrupt_enable(level);
+}
+
+/**
+ * Upper application or device driver releases all the stall
+ * of corresponding power mode.
+ *
+ * @param parameter the parameter of run mode or sleep mode
+ *
+ */
+void rt_pm_release_all(rt_uint8_t mode)
+{
+ rt_ubase_t level;
+ struct rt_pm *pm;
+
+ if (_pm_init_flag == 0)
+ return;
+
+ if (mode > (PM_SLEEP_MODE_MAX - 1))
+ return;
+
+ level = rt_hw_interrupt_disable();
+ pm = &_pm;
+ pm->modes[mode] = 0;
+ _pm_select_sleep_mode(pm);
+ rt_hw_interrupt_enable(level);
+}
+
+/**
+ * Upper application or device driver requests the system
+ * stall in corresponding power mode.
+ *
+ * @param module_id the application or device module id
+ * @param mode the system power sleep mode
+ */
+void rt_pm_module_request(uint8_t module_id, rt_uint8_t mode)
+{
+ rt_base_t level;
+ struct rt_pm *pm;
+
+ if (_pm_init_flag == 0)
+ return;
+
+ if (mode > (PM_SLEEP_MODE_MAX - 1))
+ return;
+
+ if (module_id > (PM_MODULE_MAX_ID - 1))
+ return;
+
+ level = rt_hw_interrupt_disable();
+ pm = &_pm;
+ pm->module_status[module_id].req_status = 0x01;
+ if (pm->modes[mode] < 255)
+ pm->modes[mode] ++;
+ _pm_select_sleep_mode(pm);
+ rt_hw_interrupt_enable(level);
+}
+
+/**
+ * Upper application or device driver releases the stall
+ * of corresponding power mode.
+ *
+ * @param module_id the application or device module id
+ * @param mode the system power sleep mode
+ *
+ */
+void rt_pm_module_release(uint8_t module_id, rt_uint8_t mode)
+{
+ rt_ubase_t level;
+ struct rt_pm *pm;
+
+ if (_pm_init_flag == 0)
+ return;
+
+ if (mode > (PM_SLEEP_MODE_MAX - 1))
+ return;
+
+ if (module_id > (PM_MODULE_MAX_ID - 1))
+ return;
+
+ level = rt_hw_interrupt_disable();
+ pm = &_pm;
+ if (pm->modes[mode] > 0)
+ pm->modes[mode] --;
+ if (pm->modes[mode] == 0)
+ pm->module_status[module_id].req_status = 0x00;
+ _pm_select_sleep_mode(pm);
+ rt_hw_interrupt_enable(level);
+}
+
+/**
+ * Upper application or device driver releases all the stall
+ * of corresponding power mode.
+ *
+ * @param module_id the application or device module id
+ * @param mode the system power sleep mode
+ *
+ */
+void rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode)
+{
+ rt_ubase_t level;
+ struct rt_pm *pm;
+
+ if (_pm_init_flag == 0)
+ return;
+
+ if (mode > (PM_SLEEP_MODE_MAX - 1))
+ return;
+
+ level = rt_hw_interrupt_disable();
+ pm = &_pm;
+ pm->modes[mode] = 0;
+ pm->module_status[module_id].req_status = 0x00;
+ _pm_select_sleep_mode(pm);
rt_hw_interrupt_enable(level);
}
@@ -508,6 +696,10 @@ void rt_system_pm_init(const struct rt_pm_ops *ops,
rt_memset(pm->modes, 0, sizeof(pm->modes));
pm->sleep_mode = _pm_default_sleep;
+
+ /* when system power on, set default sleep modes */
+ pm->modes[pm->sleep_mode] = 1;
+ pm->module_status[PM_POWER_ID].req_status = 1;
pm->run_mode = RT_PM_DEFAULT_RUN_MODE;
pm->timer_mask = timer_mask;
@@ -516,6 +708,10 @@ void rt_system_pm_init(const struct rt_pm_ops *ops,
pm->device_pm = RT_NULL;
pm->device_pm_number = 0;
+#if IDLE_THREAD_STACK_SIZE <= 256
+ #error "[pm.c ERR] IDLE Stack Size Too Small!"
+#endif
+
_pm_init_flag = 1;
}
@@ -537,6 +733,18 @@ static void rt_pm_release_mode(int argc, char **argv)
}
MSH_CMD_EXPORT_ALIAS(rt_pm_release_mode, pm_release, release power management mode);
+static void rt_pm_release_mode_all(int argc, char **argv)
+{
+ int mode = 0;
+ if (argc >= 2)
+ {
+ mode = atoi(argv[1]);
+ }
+
+ rt_pm_release_all(mode);
+}
+MSH_CMD_EXPORT_ALIAS(rt_pm_release_mode_all, pm_release_all, release power management mode count);
+
static void rt_pm_request_mode(int argc, char **argv)
{
int mode = 0;
@@ -549,6 +757,66 @@ static void rt_pm_request_mode(int argc, char **argv)
}
MSH_CMD_EXPORT_ALIAS(rt_pm_request_mode, pm_request, request power management mode);
+static void rt_module_release_mode(int argc, char **argv)
+{
+ int module = 0;
+ int mode = 0;
+
+ if (argc >= 3)
+ {
+ module = atoi(argv[1]);
+ mode = atoi(argv[2]);
+ }
+
+ rt_pm_module_release(module, mode);
+}
+MSH_CMD_EXPORT_ALIAS(rt_module_release_mode, pm_module_release, release module power mode);
+
+static void rt_module_release_mode_all(int argc, char **argv)
+{
+ int module = 0;
+ int mode = 0;
+
+ if (argc >= 3)
+ {
+ module = atoi(argv[1]);
+ mode = atoi(argv[2]);
+ }
+
+ rt_pm_module_release_all(module, mode);
+}
+MSH_CMD_EXPORT_ALIAS(rt_module_release_mode_all, pm_module_release_all, release power management mode count);
+
+static void rt_module_request_mode(int argc, char **argv)
+{
+ int module = 0;
+ int mode = 0;
+
+ if (argc >= 3)
+ {
+ module = atoi(argv[1]);
+ mode = atoi(argv[2]);
+ }
+
+ rt_pm_module_request(module, mode);
+}
+MSH_CMD_EXPORT_ALIAS(rt_module_request_mode, pm_module_request, request power management mode);
+
+static void rt_module_delay_sleep(int argc, char **argv)
+{
+ int module = 0;
+ unsigned int timeout = 0;
+
+ if (argc >= 3)
+ {
+ module = atoi(argv[1]);
+ timeout = atoi(argv[2]);
+ }
+
+ rt_pm_module_delay_sleep(module, timeout);
+}
+MSH_CMD_EXPORT_ALIAS(rt_module_delay_sleep, pm_module_delay, module request delay sleep);
+
static void rt_pm_run_mode_switch(int argc, char **argv)
{
int mode = 0;
@@ -561,6 +829,32 @@ static void rt_pm_run_mode_switch(int argc, char **argv)
}
MSH_CMD_EXPORT_ALIAS(rt_pm_run_mode_switch, pm_run, switch power management run mode);
+rt_uint32_t rt_pm_module_get_status(void)
+{
+ rt_uint8_t index = 0;
+ struct rt_pm *pm;
+ rt_uint32_t req_status = 0x00;
+ pm = &_pm;
+
+ for (index = 0; index < 32; index ++)
+ {
+ if (pm->module_status[index].req_status == 0x01)
+ req_status |= 1<<index;
+ if (index >= PM_MODULE_MAX_ID)
+ break;
+ }
+
+ return req_status;
+}
+
+rt_uint8_t rt_pm_get_sleep_mode(void)
+{
+ struct rt_pm *pm;
+
+ pm = &_pm;
+ return pm->sleep_mode;
+}
+
static void rt_pm_dump_status(void)
{
rt_uint32_t index;
@@ -582,6 +876,22 @@ static void rt_pm_dump_status(void)
rt_kprintf("pm current sleep mode: %s\n", _pm_sleep_str[pm->sleep_mode]);
rt_kprintf("pm current run mode: %s\n", _pm_run_str[pm->run_mode]);
+
+ rt_kprintf("\n");
+ rt_kprintf("| module | busy | start time | timeout |\n");
+ rt_kprintf("+--------+------+------------+-----------+\n");
+ for (index = 0; index < PM_MODULE_MAX_ID; index ++)
+ {
+ if ((pm->module_status[index].busy_flag == RT_TRUE) ||
+ (pm->module_status[index].req_status != 0x00))
+ {
+ rt_kprintf("| %04d | %d | 0x%08x | 0x%08x |\n",
+ index, pm->module_status[index].busy_flag,
+ pm->module_status[index].start_time,
+ pm->module_status[index].timeout);
+ }
+ }
+ rt_kprintf("+--------+------+------------+-----------+\n");
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pm_dump_status, pm_dump, dump power management status);
MSH_CMD_EXPORT_ALIAS(rt_pm_dump_status, pm_dump, dump power management status);
diff --git a/components/drivers/rtc/alarm.c b/components/drivers/rtc/alarm.c
index c497ebf727..d8e4e468a7 100644
--- a/components/drivers/rtc/alarm.c
+++ b/components/drivers/rtc/alarm.c
@@ -7,13 +7,20 @@
* Date Author Notes
* 2012-10-27 heyuanjie87 first version.
* 2013-05-17 aozima initial alarm event & mutex in system init.
+ * 2020-10-15 zhangsz add alarm flags hour minute second.
+ * 2020-11-09 zhangsz fix alarm set when modify rtc time.
*/
#include <rtthread.h>
#include <rtdevice.h>
+#include <sys/time.h>
#define RT_RTC_YEARS_MAX 137
+#ifdef RT_USING_SOFT_RTC
+#define RT_ALARM_DELAY 0
+#else
#define RT_ALARM_DELAY 2
+#endif
#define RT_ALARM_STATE_INITED 0x02
#define RT_ALARM_STATE_START 0x01
#define RT_ALARM_STATE_STOP 0x00
@@ -39,10 +46,12 @@ static rt_err_t alarm_set(struct rt_alarm *alarm)
rt_err_t ret;
device = rt_device_find("rtc");
+
if (device == RT_NULL)
{
return (RT_ERROR);
}
+
if (alarm->flag & RT_ALARM_STATE_START)
wkalarm.enable = RT_TRUE;
else
@@ -86,8 +95,8 @@ static void alarm_wakeup(struct rt_alarm *alarm, struct tm *now)
{
case RT_ALARM_ONESHOT:
{
- sec_alarm = mktime(&alarm->wktime);
- sec_now = mktime(now);
+ sec_alarm = timegm(&alarm->wktime);
+ sec_now = timegm(now);
if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm))
{
/* stop alarm */
@@ -97,6 +106,61 @@ static void alarm_wakeup(struct rt_alarm *alarm, struct tm *now)
}
}
break;
+ case RT_ALARM_SECOND:
+ {
+ alarm->wktime.tm_hour = now->tm_hour;
+ alarm->wktime.tm_min = now->tm_min;
+ alarm->wktime.tm_sec = now->tm_sec + 1;
+ if (alarm->wktime.tm_sec > 59)
+ {
+ alarm->wktime.tm_sec = 0;
+ alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
+ if (alarm->wktime.tm_min > 59)
+ {
+ alarm->wktime.tm_min = 0;
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ }
+ wakeup = RT_TRUE;
+ }
+ break;
+ case RT_ALARM_MINUTE:
+ {
+ alarm->wktime.tm_hour = now->tm_hour;
+ if (alarm->wktime.tm_sec == now->tm_sec)
+ {
+ alarm->wktime.tm_min = now->tm_min + 1;
+ if (alarm->wktime.tm_min > 59)
+ {
+ alarm->wktime.tm_min = 0;
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ wakeup = RT_TRUE;
+ }
+ }
+ break;
+ case RT_ALARM_HOUR:
+ {
+ if ((alarm->wktime.tm_min == now->tm_min) &&
+ (alarm->wktime.tm_sec == now->tm_sec))
+ {
+ alarm->wktime.tm_hour = now->tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ wakeup = RT_TRUE;
+ }
+ }
+ break;
case RT_ALARM_DAILY:
{
if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm))
@@ -158,7 +222,11 @@ static void alarm_update(rt_uint32_t event)
{
/* get time of now */
timestamp = time(RT_NULL);
- localtime_r(&timestamp, &now);
+#ifdef _WIN32
+ _gmtime32_s(&now, &timestamp);
+#else
+ gmtime_r(&timestamp, &now);
+#endif
for (next = _container.head.next; next != &_container.head; next = next->next)
{
@@ -168,7 +236,11 @@ static void alarm_update(rt_uint32_t event)
}
timestamp = time(RT_NULL);
- localtime_r(&timestamp, &now);
+#ifdef _WIN32
+ _gmtime32_s(&now, &timestamp);
+#else
+ gmtime_r(&timestamp, &now);
+#endif
sec_now = alarm_mkdaysec(&now);
for (next = _container.head.next; next != &_container.head; next = next->next)
@@ -176,8 +248,7 @@ static void alarm_update(rt_uint32_t event)
alarm = rt_list_entry(next, struct rt_alarm, list);
/* calculate seconds from 00:00:00 */
sec_alarm = alarm_mkdaysec(&alarm->wktime);
-
- if ((alarm->flag & RT_ALARM_STATE_START) && (alarm != _container.current))
+ if (alarm->flag & RT_ALARM_STATE_START)
{
sec_tmp = sec_alarm - sec_now;
if (sec_tmp > 0)
@@ -200,6 +271,7 @@ static void alarm_update(rt_uint32_t event)
}
}
}
+
/* enable the alarm after now first */
if (sec_next < 24 * 3600)
{
@@ -212,6 +284,11 @@ static void alarm_update(rt_uint32_t event)
if (alarm_set(alm_prev) == RT_EOK)
_container.current = alm_prev;
}
+ else
+ {
+ if (_container.current != RT_NULL)
+ alarm_set(_container.current);
+ }
}
rt_mutex_release(&_container.mutex);
}
@@ -267,7 +344,12 @@ static rt_err_t alarm_setup(rt_alarm_t alarm, struct tm *wktime)
setup = &alarm->wktime;
*setup = *wktime;
timestamp = time(RT_NULL);
- localtime_r(&timestamp, &now);
+
+#ifdef _WIN32
+ _gmtime32_s(&now, &timestamp);
+#else
+ gmtime_r(&timestamp, &now);
+#endif
/* if these are a "don't care" value,we set them to now*/
if ((setup->tm_sec > 59) || (setup->tm_sec < 0))
@@ -279,6 +361,51 @@ static rt_err_t alarm_setup(rt_alarm_t alarm, struct tm *wktime)
switch (alarm->flag & 0xFF00)
{
+ case RT_ALARM_SECOND:
+ {
+ alarm->wktime.tm_hour = now.tm_hour;
+ alarm->wktime.tm_min = now.tm_min;
+ alarm->wktime.tm_sec = now.tm_sec + 1;
+ if (alarm->wktime.tm_sec > 59)
+ {
+ alarm->wktime.tm_sec = 0;
+ alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
+ if (alarm->wktime.tm_min > 59)
+ {
+ alarm->wktime.tm_min = 0;
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ }
+ }
+ break;
+ case RT_ALARM_MINUTE:
+ {
+ alarm->wktime.tm_hour = now.tm_hour;
+ alarm->wktime.tm_min = now.tm_min + 1;
+ if (alarm->wktime.tm_min > 59)
+ {
+ alarm->wktime.tm_min = 0;
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ }
+ break;
+ case RT_ALARM_HOUR:
+ {
+ alarm->wktime.tm_hour = now.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ break;
case RT_ALARM_DAILY:
{
/* do nothing but needed */
@@ -419,24 +546,31 @@ rt_err_t rt_alarm_control(rt_alarm_t alarm, int cmd, void *arg)
rt_err_t rt_alarm_start(rt_alarm_t alarm)
{
rt_int32_t sec_now, sec_old, sec_new;
- rt_err_t ret = RT_ERROR;
+ rt_err_t ret = RT_EOK;
time_t timestamp;
struct tm now;
if (alarm == RT_NULL)
- return (ret);
+ return (RT_ERROR);
rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
- if (!(alarm->flag & RT_ALARM_STATE_INITED))
+
+ if (!(alarm->flag & RT_ALARM_STATE_START))
{
if (alarm_setup(alarm, &alarm->wktime) != RT_EOK)
+ {
+ ret = RT_ERROR;
goto _exit;
- }
- if ((alarm->flag & 0x01) == RT_ALARM_STATE_STOP)
- {
+ }
+
timestamp = time(RT_NULL);
- localtime_r(&timestamp, &now);
+#ifdef _WIN32
+ _gmtime32_s(&now, &timestamp);
+#else
+ gmtime_r(&timestamp, &now);
+#endif
alarm->flag |= RT_ALARM_STATE_START;
+
/* set alarm */
if (_container.current == RT_NULL)
{
@@ -486,10 +620,10 @@ _exit:
*/
rt_err_t rt_alarm_stop(rt_alarm_t alarm)
{
- rt_err_t ret = RT_ERROR;
+ rt_err_t ret = RT_EOK;
if (alarm == RT_NULL)
- return (ret);
+ return (RT_ERROR);
rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
if (!(alarm->flag & RT_ALARM_STATE_START))
goto _exit;
@@ -518,10 +652,10 @@ _exit:
*/
rt_err_t rt_alarm_delete(rt_alarm_t alarm)
{
- rt_err_t ret = RT_ERROR;
+ rt_err_t ret = RT_EOK;
if (alarm == RT_NULL)
- return (ret);
+ return RT_ERROR;
rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
/* stop the alarm */
alarm->flag &= ~RT_ALARM_STATE_START;
@@ -551,9 +685,11 @@ rt_alarm_t rt_alarm_create(rt_alarm_callback_t callback, struct rt_alarm_setup *
if (setup == RT_NULL)
return (RT_NULL);
+
alarm = rt_malloc(sizeof(struct rt_alarm));
if (alarm == RT_NULL)
return (RT_NULL);
+
rt_list_init(&alarm->list);
alarm->wktime = setup->wktime;
@@ -586,13 +722,69 @@ static void rt_alarmsvc_thread_init(void *param)
}
}
+struct _alarm_flag
+{
+ const char* name;
+ rt_uint32_t flag;
+};
+
+static const struct _alarm_flag _alarm_flag_tbl[] =
+{
+ {"N", 0xffff}, /* none */
+ {"O", RT_ALARM_ONESHOT}, /* only alarm onece */
+ {"D", RT_ALARM_DAILY}, /* alarm everyday */
+ {"W", RT_ALARM_WEEKLY}, /* alarm weekly at Monday or Friday etc. */
+ {"Mo", RT_ALARM_MONTHLY}, /* alarm monthly at someday */
+ {"Y", RT_ALARM_YAERLY}, /* alarm yearly at a certain date */
+ {"H", RT_ALARM_HOUR}, /* alarm each hour at a certain min:second */
+ {"M", RT_ALARM_MINUTE}, /* alarm each minute at a certain second */
+ {"S", RT_ALARM_SECOND}, /* alarm each second */
+};
+
+static rt_uint8_t _alarm_flag_tbl_size = sizeof(_alarm_flag_tbl) / sizeof(_alarm_flag_tbl[0]);
+
+static rt_uint8_t get_alarm_flag_index(rt_uint32_t alarm_flag)
+{
+ for (rt_uint8_t index = 0; index < _alarm_flag_tbl_size; index++)
+ {
+ alarm_flag &= 0xff00;
+ if (alarm_flag == _alarm_flag_tbl[index].flag)
+ {
+ return index;
+ }
+ }
+
+ return 0;
+}
+
+void rt_alarm_dump(void)
+{
+ rt_list_t *next;
+ rt_alarm_t alarm;
+ rt_uint8_t index = 0;
+
+ rt_kprintf("| id | YYYY-MM-DD hh:mm:ss | week | flag | en |\n");
+ rt_kprintf("+----+---------------------+------+------+----+\n");
+ for (next = _container.head.next; next != &_container.head; next = next->next)
+ {
+ alarm = rt_list_entry(next, struct rt_alarm, list);
+ rt_uint8_t flag_index = get_alarm_flag_index(alarm->flag);
+ rt_kprintf("| %2d | %04d-%02d-%02d %02d:%02d:%02d | %2d | %2s | %2d |\n",
+ index++, alarm->wktime.tm_year + 1900, alarm->wktime.tm_mon + 1, alarm->wktime.tm_mday,
+ alarm->wktime.tm_hour, alarm->wktime.tm_min, alarm->wktime.tm_sec,
+ alarm->wktime.tm_wday, _alarm_flag_tbl[flag_index].name, alarm->flag & RT_ALARM_STATE_START);
+ }
+ rt_kprintf("+----+---------------------+------+------+----+\n");
+}
+
+FINSH_FUNCTION_EXPORT_ALIAS(rt_alarm_dump, __cmd_alarm_dump, dump alarm info);
/** \brief initialize alarm service system
*
* \param none
* \return none
*/
-void rt_alarm_system_init(void)
+int rt_alarm_system_init(void)
{
rt_thread_t tid;
@@ -602,8 +794,12 @@ void rt_alarm_system_init(void)
tid = rt_thread_create("alarmsvc",
rt_alarmsvc_thread_init, RT_NULL,
- 512, 8, 1);
+ 2048, 10, 5);
if (tid != RT_NULL)
rt_thread_startup(tid);
+
+ return 0;
}
+
+INIT_PREV_EXPORT(rt_alarm_system_init);
#endif
diff --git a/components/drivers/rtc/rtc.c b/components/drivers/rtc/rtc.c
index e17c0fe7dd..ef688ac3cd 100644
--- a/components/drivers/rtc/rtc.c
+++ b/components/drivers/rtc/rtc.c
@@ -11,7 +11,7 @@
* 2018-02-16 armink add auto sync time by NTP
*/
-#include <time.h>
+#include <sys/time.h>
#include <string.h>
#include <rtthread.h>
@@ -30,7 +30,7 @@
#endif /* RTC_SYNC_USING_NTP */
/**
- * Set system date(time not modify).
+ * Set system date(time not modify, local timezone).
*
* @param rt_uint32_t year e.g: 2012.
* @param rt_uint32_t month e.g: 12 (1~12).
@@ -52,10 +52,10 @@ rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day)
/* lock scheduler. */
rt_enter_critical();
- /* converts calendar time time into local time. */
+ /* converts calendar time into local time. */
p_tm = localtime(&now);
/* copy the statically located variable */
- memcpy(&tm_new, p_tm, sizeof(struct tm));
+ rt_memcpy(&tm_new, p_tm, sizeof(struct tm));
/* unlock scheduler. */
rt_exit_critical();
@@ -64,7 +64,7 @@ rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day)
tm_new.tm_mon = month - 1; /* tm_mon: 0~11 */
tm_new.tm_mday = day;
- /* converts the local time in time to calendar time. */
+ /* converts the local time into the calendar time. */
now = mktime(&tm_new);
device = rt_device_find("rtc");
@@ -80,7 +80,7 @@ rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day)
}
/**
- * Set system time(date not modify).
+ * Set system time(date not modify, local timezone).
*
* @param rt_uint32_t hour e.g: 0~23.
* @param rt_uint32_t minute e.g: 0~59.
@@ -102,10 +102,10 @@ rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second)
/* lock scheduler. */
rt_enter_critical();
- /* converts calendar time time into local time. */
+ /* converts calendar time into local time. */
p_tm = localtime(&now);
/* copy the statically located variable */
- memcpy(&tm_new, p_tm, sizeof(struct tm));
+ rt_memcpy(&tm_new, p_tm, sizeof(struct tm));
/* unlock scheduler. */
rt_exit_critical();
@@ -114,7 +114,7 @@ rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second)
tm_new.tm_min = minute;
tm_new.tm_sec = second;
- /* converts the local time in time to calendar time. */
+ /* converts the local time into the calendar time. */
now = mktime(&tm_new);
device = rt_device_find("rtc");
@@ -174,19 +174,25 @@ INIT_COMPONENT_EXPORT(rt_rtc_ntp_sync_init);
#include <finsh.h>
#include <rtdevice.h>
+/**
+ * show date and time (local timezone)
+ */
void list_date(void)
{
time_t now;
now = time(RT_NULL);
- rt_kprintf("%s\n", ctime(&now));
+ rt_kprintf("%.*s\n", 25, ctime(&now));
}
-FINSH_FUNCTION_EXPORT(list_date, show date and time.)
+FINSH_FUNCTION_EXPORT(list_date, show date and time (local timezone))
+FINSH_FUNCTION_EXPORT(set_date, set date(local timezone) e.g: set_date(2010,2,28))
+FINSH_FUNCTION_EXPORT(set_time, set time(local timezone) e.g: set_time(23,59,59))
-FINSH_FUNCTION_EXPORT(set_date, set date. e.g: set_date(2010,2,28))
-FINSH_FUNCTION_EXPORT(set_time, set time. e.g: set_time(23,59,59))
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
+/**
+ * get date and time or set (local timezone) [year month day hour min sec]
+ */
static void date(uint8_t argc, char **argv)
{
if (argc == 1)
@@ -194,7 +200,7 @@ static void date(uint8_t argc, char **argv)
time_t now;
/* output current time */
now = time(RT_NULL);
- rt_kprintf("%s", ctime(&now));
+ rt_kprintf("%.*s", 25, ctime(&now));
}
else if (argc >= 7)
{
@@ -246,9 +252,9 @@ static void date(uint8_t argc, char **argv)
rt_kprintf("e.g: date 2018 01 01 23 59 59 or date\n");
}
}
-MSH_CMD_EXPORT(date, get date and time or set [year month day hour min sec]);
-#endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */
+MSH_CMD_EXPORT(list_date, show date and time (local timezone))
+MSH_CMD_EXPORT(date, get date and time or set (local timezone) [year month day hour min sec])
+#endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */
#endif /* RT_USING_FINSH */
-
#endif /* RT_USING_RTC */
diff --git a/components/drivers/rtc/soft_rtc.c b/components/drivers/rtc/soft_rtc.c
index adcbf81fe3..240301f683 100644
--- a/components/drivers/rtc/soft_rtc.c
+++ b/components/drivers/rtc/soft_rtc.c
@@ -8,11 +8,10 @@
* 2018-01-30 armink the first version
*/
-#include <time.h>
+#include <sys/time.h>
#include <string.h>
#include <rtthread.h>
-
-#include <drivers/rtc.h>
+#include <rtdevice.h>
#ifdef RT_USING_SOFT_RTC
@@ -28,9 +27,37 @@ static struct rt_device soft_rtc_dev;
static rt_tick_t init_tick;
static time_t init_time;
+#ifdef RT_USING_ALARM
+
+static struct rt_rtc_wkalarm wkalarm;
+static struct rt_timer alarm_time;
+
+static void alarm_timeout(void *param)
+{
+ rt_alarm_update(param, 1);
+}
+
+static void soft_rtc_alarm_update(struct rt_rtc_wkalarm *palarm)
+{
+ rt_tick_t next_tick;
+
+ if (palarm->enable)
+ {
+ next_tick = RT_TICK_PER_SECOND;
+ rt_timer_control(&alarm_time, RT_TIMER_CTRL_SET_TIME, &next_tick);
+ rt_timer_start(&alarm_time);
+ }
+ else
+ {
+ rt_timer_stop(&alarm_time);
+ }
+}
+
+#endif
+
static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
{
- time_t *time;
+ time_t *t;
struct tm time_temp;
RT_ASSERT(dev != RT_NULL);
@@ -39,16 +66,27 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
switch (cmd)
{
case RT_DEVICE_CTRL_RTC_GET_TIME:
- time = (time_t *) args;
- *time = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+ t = (time_t *) args;
+ *t = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
break;
-
case RT_DEVICE_CTRL_RTC_SET_TIME:
{
- time = (time_t *) args;
- init_time = *time - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+ t = (time_t *) args;
+ init_time = *t - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+#ifdef RT_USING_ALARM
+ soft_rtc_alarm_update(&wkalarm);
+#endif
break;
}
+#ifdef RT_USING_ALARM
+ case RT_DEVICE_CTRL_RTC_GET_ALARM:
+ *((struct rt_rtc_wkalarm *)args) = wkalarm;
+ break;
+ case RT_DEVICE_CTRL_RTC_SET_ALARM:
+ wkalarm = *((struct rt_rtc_wkalarm *)args);
+ soft_rtc_alarm_update(&wkalarm);
+ break;
+#endif
}
return RT_EOK;
@@ -78,8 +116,17 @@ int rt_soft_rtc_init(void)
/* make sure only one 'rtc' device */
RT_ASSERT(!rt_device_find("rtc"));
+#ifdef RT_USING_ALARM
+ rt_timer_init(&alarm_time,
+ "alarm",
+ alarm_timeout,
+ &soft_rtc_dev,
+ 0,
+ RT_TIMER_FLAG_SOFT_TIMER|RT_TIMER_FLAG_ONE_SHOT);
+#endif
+
init_tick = rt_tick_get();
- init_time = mktime(&time_new);
+ init_time = timegm(&time_new);
soft_rtc_dev.type = RT_Device_Class_RTC;
diff --git a/components/drivers/sdio/sdio.c b/components/drivers/sdio/sdio.c
index 65bf87b895..f0d5863a06 100644
--- a/components/drivers/sdio/sdio.c
+++ b/components/drivers/sdio/sdio.c
@@ -250,7 +250,10 @@ rt_int32_t sdio_io_rw_extended_block(struct rt_sdio_function *func,
rt_int32_t ret;
rt_uint32_t left_size;
rt_uint32_t max_blks, blks;
-
+
+ RT_ASSERT(func != RT_NULL);
+ RT_ASSERT(func->card != RT_NULL);
+
left_size = len;
/* Do the bulk of the transfer using block mode (if supported). */
@@ -575,22 +578,26 @@ static rt_int32_t sdio_read_cis(struct rt_sdio_function *func)
if (tpl_link < 4)
{
LOG_D("bad CISTPL_MANFID length");
- break;
- }
- if (func->num != 0)
- {
- func->manufacturer = curr->data[0];
- func->manufacturer |= curr->data[1] << 8;
- func->product = curr->data[2];
- func->product |= curr->data[3] << 8;
}
else
{
- card->cis.manufacturer = curr->data[0];
- card->cis.manufacturer |= curr->data[1] << 8;
- card->cis.product = curr->data[2];
- card->cis.product |= curr->data[3] << 8;
+ if (func->num != 0)
+ {
+ func->manufacturer = curr->data[0];
+ func->manufacturer |= curr->data[1] << 8;
+ func->product = curr->data[2];
+ func->product |= curr->data[3] << 8;
+ }
+ else
+ {
+ card->cis.manufacturer = curr->data[0];
+ card->cis.manufacturer |= curr->data[1] << 8;
+ card->cis.product = curr->data[2];
+ card->cis.product |= curr->data[3] << 8;
+ }
}
+
+ rt_free(curr);
break;
case CISTPL_FUNCE:
if (func->num != 0)
@@ -892,9 +899,9 @@ static rt_int32_t sdio_init_card(struct rt_mmcsd_host *host, rt_uint32_t ocr)
if (card->flags & CARD_FLAG_HIGHSPEED)
{
- mmcsd_set_clock(host, 50000000);
- }
- else
+ mmcsd_set_clock(host, card->host->freq_max > 50000000 ? 50000000 : card->host->freq_max);
+ }
+ else
{
mmcsd_set_clock(host, card->cis.max_tran_speed);
}
@@ -930,9 +937,6 @@ err3:
sdio_free_cis(host->card->sdio_function[i]);
rt_free(host->card->sdio_function[i]);
host->card->sdio_function[i] = RT_NULL;
- rt_free(host->card);
- host->card = RT_NULL;
- break;
}
}
}
diff --git a/components/drivers/sensors/SConscript b/components/drivers/sensors/SConscript
index 51c4b50eef..b56ae5ce6e 100644
--- a/components/drivers/sensors/SConscript
+++ b/components/drivers/sensors/SConscript
@@ -7,7 +7,7 @@ src = ['sensor.c']
CPPPATH = [cwd, cwd + '/../include']
if GetDepend('RT_USING_SENSOR_CMD'):
- src += ['sensor_cmd.c'];
+ src += ['sensor_cmd.c']
group = DefineGroup('Sensors', src, depend = ['RT_USING_SENSOR', 'RT_USING_DEVICE'], CPPPATH = CPPPATH)
diff --git a/components/drivers/sensors/sensor.c b/components/drivers/sensors/sensor.c
index 08127bc292..660b86f85b 100644
--- a/components/drivers/sensors/sensor.c
+++ b/components/drivers/sensors/sensor.c
@@ -34,7 +34,9 @@ static char *const sensor_name_str[] =
"step_", /* Step sensor */
"forc_", /* Force sensor */
"dust_", /* Dust sensor */
- "eco2_" /* eCO2 sensor */
+ "eco2_", /* eCO2 sensor */
+ "gnss_", /* GPS/GNSS sensor */
+ "tof_" /* TOF sensor */
};
/* Sensor interrupt correlation function */
@@ -214,12 +216,6 @@ static rt_err_t rt_sensor_close(rt_device_t dev)
sensor->config.power = RT_SENSOR_POWER_DOWN;
}
- /* Sensor disable interrupt */
- if (sensor->config.irq_pin.pin != RT_PIN_NONE)
- {
- rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_FALSE);
- }
-
if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf != RT_NULL)
{
for (i = 0; i < sensor->module->sen_num; i ++)
@@ -238,6 +234,11 @@ static rt_err_t rt_sensor_close(rt_device_t dev)
}
}
}
+ /* Sensor disable interrupt */
+ if (sensor->config.irq_pin.pin != RT_PIN_NONE)
+ {
+ rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_FALSE);
+ }
__exit:
if (sensor->module)
diff --git a/components/drivers/sensors/sensor.h b/components/drivers/sensors/sensor.h
index 625fd566f2..b180e36a73 100755
--- a/components/drivers/sensors/sensor.h
+++ b/components/drivers/sensors/sensor.h
@@ -47,6 +47,8 @@ extern "C" {
#define RT_SENSOR_CLASS_FORCE (13) /* Force sensor */
#define RT_SENSOR_CLASS_DUST (14) /* Dust sensor */
#define RT_SENSOR_CLASS_ECO2 (15) /* eCO2 sensor */
+#define RT_SENSOR_CLASS_GNSS (16) /* GPS/GNSS sensor */
+#define RT_SENSOR_CLASS_TOF (17) /* TOF sensor */
/* Sensor vendor types */
@@ -63,6 +65,8 @@ extern "C" {
#define RT_SENSOR_VENDOR_SENSIRION (10) /* Sensirion */
#define RT_SENSOR_VENDOR_TI (11) /* Texas Instruments */
#define RT_SENSOR_VENDOR_PLANTOWER (12) /* Plantower */
+#define RT_SENSOR_VENDOR_AMS (13) /* ams AG */
+#define RT_SENSOR_VENDOR_MAXIM (14) /* Maxim Integrated */
/* Sensor unit types */
@@ -81,6 +85,10 @@ extern "C" {
#define RT_SENSOR_UNIT_BPM (11) /* Heart rate unit: bpm */
#define RT_SENSOR_UNIT_MM (12) /* Distance unit: mm */
#define RT_SENSOR_UNIT_MN (13) /* Force unit: mN */
+#define RT_SENSOR_UNIT_PPM (14) /* Concentration unit: ppm */
+#define RT_SENSOR_UNIT_PPB (15) /* Concentration unit: ppb */
+#define RT_SENSOR_UNIT_DMS (16) /* Coordinates unit: DMS */
+#define RT_SENSOR_UNIT_DD (17) /* Coordinates unit: DD */
/* Sensor communication interface types */
@@ -181,6 +189,12 @@ struct sensor_3_axis
rt_int32_t z;
};
+struct coordinates
+{
+ double longitude;
+ double latitude;
+};
+
struct rt_sensor_data
{
rt_uint32_t timestamp; /* The timestamp when the data was received */
@@ -190,6 +204,7 @@ struct rt_sensor_data
struct sensor_3_axis acce; /* Accelerometer. unit: mG */
struct sensor_3_axis gyro; /* Gyroscope. unit: mdps */
struct sensor_3_axis mag; /* Magnetometer. unit: mGauss */
+ struct coordinates coord; /* Coordinates unit: degrees */
rt_int32_t temp; /* Temperature. unit: dCelsius */
rt_int32_t humi; /* Relative humidity. unit: permillage */
rt_int32_t baro; /* Pressure. unit: pascal (Pa) */
diff --git a/components/drivers/sensors/sensor_cmd.c b/components/drivers/sensors/sensor_cmd.c
index 5f1f31c9e5..cbf7d233c6 100755
--- a/components/drivers/sensors/sensor_cmd.c
+++ b/components/drivers/sensors/sensor_cmd.c
@@ -34,8 +34,11 @@ static void sensor_show_data(rt_size_t num, rt_sensor_t sensor, struct rt_sensor
case RT_SENSOR_CLASS_MAG:
LOG_I("num:%3d, x:%5d, y:%5d, z:%5d mGauss, timestamp:%5d", num, sensor_data->data.mag.x, sensor_data->data.mag.y, sensor_data->data.mag.z, sensor_data->timestamp);
break;
+ case RT_SENSOR_CLASS_GNSS:
+ LOG_I("num:%3d, lon:%5d, lat:%5d, timestamp:%5d", num, sensor_data->data.coord.longitude, sensor_data->data.coord.latitude, sensor_data->timestamp);
+ break;
case RT_SENSOR_CLASS_TEMP:
- LOG_I("num:%3d, temp:%3d.%d C, timestamp:%5d", num, sensor_data->data.temp / 10, sensor_data->data.temp % 10, sensor_data->timestamp);
+ LOG_I("num:%3d, temp:%3d.%d C, timestamp:%5d", num, sensor_data->data.temp / 10, (rt_uint32_t)sensor_data->data.temp % 10, sensor_data->timestamp);
break;
case RT_SENSOR_CLASS_HUMI:
LOG_I("num:%3d, humi:%3d.%d%%, timestamp:%5d", num, sensor_data->data.humi / 10, sensor_data->data.humi % 10, sensor_data->timestamp);
@@ -47,6 +50,7 @@ static void sensor_show_data(rt_size_t num, rt_sensor_t sensor, struct rt_sensor
LOG_I("num:%3d, light:%5d lux, timestamp:%5d", num, sensor_data->data.light, sensor_data->timestamp);
break;
case RT_SENSOR_CLASS_PROXIMITY:
+ case RT_SENSOR_CLASS_TOF:
LOG_I("num:%3d, distance:%5d, timestamp:%5d", num, sensor_data->data.proximity, sensor_data->timestamp);
break;
case RT_SENSOR_CLASS_HR:
@@ -226,6 +230,7 @@ static void sensor_polling(int argc, char **argv)
rt_sensor_t sensor;
struct rt_sensor_data data;
rt_size_t res, i;
+ rt_int32_t delay;
dev = rt_device_find(argv[1]);
if (dev == RT_NULL)
@@ -237,6 +242,7 @@ static void sensor_polling(int argc, char **argv)
num = atoi(argv[2]);
sensor = (rt_sensor_t)dev;
+ delay = sensor->info.period_min > 100 ? sensor->info.period_min : 100;
if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
{
@@ -256,7 +262,7 @@ static void sensor_polling(int argc, char **argv)
{
sensor_show_data(i, sensor, &data);
}
- rt_thread_mdelay(100);
+ rt_thread_mdelay(delay);
}
rt_device_close(dev);
}
@@ -268,7 +274,9 @@ static void sensor(int argc, char **argv)
{
static rt_device_t dev = RT_NULL;
struct rt_sensor_data data;
+ rt_sensor_t sensor;
rt_size_t res, i;
+ rt_int32_t delay;
/* If the number of arguments less than 2 */
if (argc < 2)
@@ -335,6 +343,12 @@ static void sensor(int argc, char **argv)
case RT_SENSOR_VENDOR_PLANTOWER:
rt_kprintf("vendor :Plantower\n");
break;
+ case RT_SENSOR_VENDOR_AMS:
+ rt_kprintf("vendor :AMS\n");
+ break;
+ case RT_SENSOR_VENDOR_MAXIM:
+ rt_kprintf("vendor :Maxim Integrated\n");
+ break;
}
rt_kprintf("model :%s\n", info.model);
switch (info.unit)
@@ -381,6 +395,12 @@ static void sensor(int argc, char **argv)
case RT_SENSOR_UNIT_MN:
rt_kprintf("unit :mN\n");
break;
+ case RT_SENSOR_UNIT_PPM:
+ rt_kprintf("unit :ppm\n");
+ break;
+ case RT_SENSOR_UNIT_PPB:
+ rt_kprintf("unit :ppb\n");
+ break;
}
rt_kprintf("range_max :%d\n", info.range_max);
rt_kprintf("range_min :%d\n", info.range_min);
@@ -401,6 +421,9 @@ static void sensor(int argc, char **argv)
num = atoi(argv[2]);
}
+ sensor = (rt_sensor_t)dev;
+ delay = sensor->info.period_min > 100 ? sensor->info.period_min : 100;
+
for (i = 0; i < num; i++)
{
res = rt_device_read(dev, 0, &data, 1);
@@ -410,9 +433,9 @@ static void sensor(int argc, char **argv)
}
else
{
- sensor_show_data(i, (rt_sensor_t)dev, &data);
+ sensor_show_data(i, sensor, &data);
}
- rt_thread_mdelay(100);
+ rt_thread_mdelay(delay);
}
}
else if (argc == 3)
diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c
index c442b052b1..5743155e37 100644
--- a/components/drivers/serial/serial.c
+++ b/components/drivers/serial/serial.c
@@ -22,6 +22,9 @@
* 2017-11-15 JasonJia fix poll rx issue when data is full.
* add TCFLSH and FIONREAD support.
* 2018-12-08 Ernest Chen add DMA choice
+ * 2020-09-14 WillianChan add a line feed to the carriage return character
+ * when using interrupt tx
+ * 2020-12-14 Meco Man add function of setting window's size(TIOCSWINSZ)
*/
#include <rthw.h>
@@ -68,21 +71,21 @@ static int serial_fops_open(struct dfs_fd *fd)
switch (fd->flags & O_ACCMODE)
{
- case O_RDONLY:
- LOG_D("fops open: O_RDONLY!");
- flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDONLY;
- break;
- case O_WRONLY:
- LOG_D("fops open: O_WRONLY!");
- flags = RT_DEVICE_FLAG_WRONLY;
- break;
- case O_RDWR:
- LOG_D("fops open: O_RDWR!");
- flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDWR;
- break;
- default:
- LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
- break;
+ case O_RDONLY:
+ LOG_D("fops open: O_RDONLY!");
+ flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDONLY;
+ break;
+ case O_WRONLY:
+ LOG_D("fops open: O_WRONLY!");
+ flags = RT_DEVICE_FLAG_WRONLY;
+ break;
+ case O_RDWR:
+ LOG_D("fops open: O_RDWR!");
+ flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDWR;
+ break;
+ default:
+ LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
+ break;
}
if ((fd->flags & O_ACCMODE) != O_WRONLY)
@@ -130,7 +133,7 @@ static int serial_fops_read(struct dfs_fd *fd, void *buf, size_t count)
do
{
- size = rt_device_read(device, -1, buf, count);
+ size = rt_device_read(device, -1, buf, count);
if (size <= 0)
{
if (fd->flags & O_NONBLOCK)
@@ -219,7 +222,10 @@ rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data,
*data = ch;
data ++; length --;
- if (ch == '\n') break;
+ if(serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)
+ {
+ if (ch == '\n') break;
+ }
}
return size - length;
@@ -315,6 +321,19 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *
while (length)
{
+ /*
+ * to be polite with serial console add a line feed
+ * to the carriage return character
+ */
+ if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
+ {
+ if (serial->ops->putc(serial, '\r') == -1)
+ {
+ rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
+ continue;
+ }
+ }
+
if (serial->ops->putc(serial, *(char*)data) == -1)
{
rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
@@ -740,14 +759,17 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
{
- if (serial->config.bufsz == 0) {
+ if (serial->config.bufsz == 0)
+ {
struct rt_serial_rx_dma* rx_dma;
rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx;
RT_ASSERT(rx_dma != RT_NULL);
rt_free(rx_dma);
- } else {
+ }
+ else
+ {
struct rt_serial_rx_fifo* rx_fifo;
rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx;
@@ -994,7 +1016,7 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
}
break;
-
+#ifdef RT_USING_POSIX
#ifdef RT_USING_POSIX_TERMIOS
case TCGETA:
{
@@ -1086,8 +1108,17 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
break;
case TCXONC:
break;
-#endif
-#ifdef RT_USING_POSIX
+ case TIOCSWINSZ:
+ {
+ struct winsize* p_winsize;
+
+ p_winsize = (struct winsize*)args;
+ rt_enter_critical();
+ rt_kprintf("\x1b[8;%d;%dt", p_winsize->ws_col, p_winsize->ws_row);
+ rt_exit_critical();
+ }
+ break;
+#endif /*RT_USING_POSIX_TERMIOS*/
case FIONREAD:
{
rt_size_t recved = 0;
@@ -1100,7 +1131,7 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
*(rt_size_t *)args = recved;
}
break;
-#endif
+#endif /*RT_USING_POSIX*/
default :
/* control device */
ret = serial->ops->control(serial, cmd, args);
@@ -1242,7 +1273,7 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx;
rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0);
- if (rt_data_queue_peak(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK)
+ if (rt_data_queue_peek(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK)
{
/* transmit next data node */
tx_dma->activated = RT_TRUE;
diff --git a/components/drivers/spi/sfud/inc/sfud_cfg.h b/components/drivers/spi/sfud/inc/sfud_cfg.h
index 3b7860062d..01255775c8 100644
--- a/components/drivers/spi/sfud/inc/sfud_cfg.h
+++ b/components/drivers/spi/sfud/inc/sfud_cfg.h
@@ -38,6 +38,18 @@
#define SFUD_DEBUG_MODE
#endif
+#ifdef RT_DEBUG_SFUD
+#define DBG_LVL DBG_LOG
+#define SFUD_DEBUG(fmt, ...) LOG_D("(%s:%ld) "fmt"", __FILE__, __LINE__, ##__VA_ARGS__)
+#else
+#define DBG_LVL DBG_INFO
+#endif /* RT_DEBUG_SFUD */
+
+#define DBG_TAG "SFUD"
+#include <rtdbg.h>
+extern void rt_kprintf(const char *fmt, ...);
+#define SFUD_INFO(...) LOG_I(__VA_ARGS__)
+
/**
* Using probe flash JEDEC SFDP parameter.
*/
diff --git a/components/drivers/spi/sfud/inc/sfud_flash_def.h b/components/drivers/spi/sfud/inc/sfud_flash_def.h
index 34e89e7aa9..03b95cd008 100644
--- a/components/drivers/spi/sfud/inc/sfud_flash_def.h
+++ b/components/drivers/spi/sfud/inc/sfud_flash_def.h
@@ -87,7 +87,7 @@ typedef struct {
#define SFUD_MF_ID_FUDAN 0xA1
#define SFUD_MF_ID_HYUNDAI 0xAD
#define SFUD_MF_ID_SST 0xBF
-#define SFUD_MF_ID_MICRONIX 0xC2
+#define SFUD_MF_ID_MACRONIX 0xC2
#define SFUD_MF_ID_GIGADEVICE 0xC8
#define SFUD_MF_ID_ISSI 0xD5
#define SFUD_MF_ID_WINBOND 0xEF
@@ -110,7 +110,7 @@ typedef struct {
{"GigaDevice", SFUD_MF_ID_GIGADEVICE}, \
{"ISSI", SFUD_MF_ID_ISSI}, \
{"Winbond", SFUD_MF_ID_WINBOND}, \
- {"Micronix", SFUD_MF_ID_MICRONIX}, \
+ {"Macronix", SFUD_MF_ID_MACRONIX}, \
}
#ifdef SFUD_USING_FLASH_INFO_TABLE
@@ -124,6 +124,7 @@ typedef struct {
{"AT45DB161E", SFUD_MF_ID_ATMEL, 0x26, 0x00, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_DUAL_BUFFER, 512, 0x81}, \
{"W25Q40BV", SFUD_MF_ID_WINBOND, 0x40, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q16BV", SFUD_MF_ID_WINBOND, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
+ {"W25Q64CV", SFUD_MF_ID_WINBOND, 0x40, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q64DW", SFUD_MF_ID_WINBOND, 0x60, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q128BV", SFUD_MF_ID_WINBOND, 0x40, 0x18, 16L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q256FV", SFUD_MF_ID_WINBOND, 0x40, 0x19, 32L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
@@ -143,7 +144,7 @@ typedef struct {
#endif /* SFUD_USING_FLASH_INFO_TABLE */
#ifdef SFUD_USING_QSPI
-/* This table saves flash read-fast instructions in QSPI mode,
+/* This table saves flash read-fast instructions in QSPI mode,
* SFUD can use this table to select the most appropriate read instruction for flash.
* | mf_id | type_id | capacity_id | qspi_read_mode |
*/
@@ -172,7 +173,9 @@ typedef struct {
/* A25LQ64 */ \
{SFUD_MF_ID_AMIC, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_IO}, \
/* MX25L3206E and KH25L3206E */ \
- {SFUD_MF_ID_MICRONIX, 0x20, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \
+ {SFUD_MF_ID_MACRONIX, 0x20, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \
+ /* MX25L51245G */ \
+ {SFUD_MF_ID_MACRONIX, 0x20, 0x1A, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \
/* GD25Q64B */ \
{SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT}, \
}
diff --git a/components/drivers/spi/spi_flash.h b/components/drivers/spi/spi_flash.h
index 30db32474a..82b1ab2ecd 100644
--- a/components/drivers/spi/spi_flash.h
+++ b/components/drivers/spi/spi_flash.h
@@ -6,11 +6,14 @@
* Change Logs:
* Date Author Notes
* 2016/5/20 bernard the first version
+ * 2020/1/7 redoc add include
*/
#ifndef SPI_FLASH_H__
#define SPI_FLASH_H__
+#include <rtdevice.h>
+
struct spi_flash_device
{
struct rt_device flash_device;
diff --git a/components/drivers/spi/spi_flash_sfud.c b/components/drivers/spi/spi_flash_sfud.c
index eff604fe02..2333c9ccb3 100644
--- a/components/drivers/spi/spi_flash_sfud.c
+++ b/components/drivers/spi/spi_flash_sfud.c
@@ -15,12 +15,6 @@
#ifdef RT_USING_SFUD
-#ifdef RT_DEBUG_SFUD
-#define DEBUG_TRACE rt_kprintf("[SFUD] "); rt_kprintf
-#else
-#define DEBUG_TRACE(...)
-#endif /* RT_DEBUG_SFUD */
-
#ifndef RT_SFUD_DEFAULT_SPI_CFG
#ifndef RT_SFUD_SPI_MAX_HZ
@@ -34,7 +28,7 @@
.data_width = 8, \
.max_hz = RT_SFUD_SPI_MAX_HZ, \
}
-#endif
+#endif /* RT_SFUD_DEFAULT_SPI_CFG */
#ifdef SFUD_USING_QSPI
#define RT_SFUD_DEFAULT_QSPI_CFG \
@@ -44,11 +38,7 @@
.ddr_mode = 0, \
.qspi_dl_width = 4, \
}
-#endif
-
-static char log_buf[RT_CONSOLEBUF_SIZE];
-
-void sfud_log_debug(const char *file, const long line, const char *format, ...);
+#endif /* SFUD_USING_QSPI */
static rt_err_t rt_sfud_control(rt_device_t dev, int cmd, void *args) {
RT_ASSERT(dev);
@@ -259,44 +249,6 @@ static void retry_delay_100us(void) {
rt_thread_delay((RT_TICK_PER_SECOND * 1 + 9999) / 10000);
}
-/**
- * This function is print debug info.
- *
- * @param file the file which has call this function
- * @param line the line number which has call this function
- * @param format output format
- * @param ... args
- */
-void sfud_log_debug(const char *file, const long line, const char *format, ...) {
- va_list args;
-
- /* args point to the first variable parameter */
- va_start(args, format);
- rt_kprintf("[SFUD] (%s:%ld) ", file, line);
- /* must use vprintf to print */
- rt_vsnprintf(log_buf, sizeof(log_buf), format, args);
- rt_kprintf("%s\n", log_buf);
- va_end(args);
-}
-
-/**
- * This function is print routine info.
- *
- * @param format output format
- * @param ... args
- */
-void sfud_log_info(const char *format, ...) {
- va_list args;
-
- /* args point to the first variable parameter */
- va_start(args, format);
- rt_kprintf("[SFUD] ");
- /* must use vprintf to print */
- rt_vsnprintf(log_buf, sizeof(log_buf), format, args);
- rt_kprintf("%s\n", log_buf);
- va_end(args);
-}
-
sfud_err sfud_spi_port_init(sfud_flash *flash) {
sfud_err result = SFUD_SUCCESS;
@@ -311,7 +263,7 @@ sfud_err sfud_spi_port_init(sfud_flash *flash) {
flash->spi.unlock = spi_unlock;
flash->spi.user_data = flash;
if (RT_TICK_PER_SECOND < 1000) {
- rt_kprintf("[SFUD] Warning: The OS tick(%d) is less than 1000. So the flash write will take more time.\n", RT_TICK_PER_SECOND);
+ LOG_W("[SFUD] Warning: The OS tick(%d) is less than 1000. So the flash write will take more time.", RT_TICK_PER_SECOND);
}
/* 100 microsecond delay */
flash->retry.delay = retry_delay_100us;
@@ -334,23 +286,23 @@ const static struct rt_device_ops flash_device_ops =
#endif
/**
- * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device.
+ * Probe SPI flash by SFUD (Serial Flash Universal Driver) driver library and though SPI device by specified configuration.
*
* @param spi_flash_dev_name the name which will create SPI flash device
* @param spi_dev_name using SPI device name
+ * @param spi_cfg SPI device configuration
+ * @param qspi_cfg QSPI device configuration
*
* @return probed SPI flash device, probe failed will return RT_NULL
*/
-rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name) {
+rt_spi_flash_device_t rt_sfud_flash_probe_ex(const char *spi_flash_dev_name, const char *spi_dev_name,
+ struct rt_spi_configuration *spi_cfg, struct rt_qspi_configuration *qspi_cfg)
+{
rt_spi_flash_device_t rtt_dev = RT_NULL;
sfud_flash *sfud_dev = RT_NULL;
char *spi_flash_dev_name_bak = RT_NULL, *spi_dev_name_bak = RT_NULL;
- /* using default flash SPI configuration for initialize SPI Flash
- * @note you also can change the SPI to other configuration after initialized finish */
- struct rt_spi_configuration cfg = RT_SFUD_DEFAULT_SPI_CFG;
extern sfud_err sfud_device_init(sfud_flash *flash);
#ifdef SFUD_USING_QSPI
- struct rt_qspi_configuration qspi_cfg = RT_SFUD_DEFAULT_QSPI_CFG;
struct rt_qspi_device *qspi_dev = RT_NULL;
#endif
@@ -380,7 +332,7 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
/* RT-Thread SPI device initialize */
rtt_dev->rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name);
if (rtt_dev->rt_spi_device == RT_NULL || rtt_dev->rt_spi_device->parent.type != RT_Device_Class_SPIDevice) {
- rt_kprintf("ERROR: SPI device %s not found!\n", spi_dev_name);
+ LOG_E("ERROR: SPI device %s not found!", spi_dev_name);
goto error;
}
sfud_dev->spi.name = spi_dev_name_bak;
@@ -389,12 +341,12 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
/* set the qspi line number and configure the QSPI bus */
if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) {
qspi_dev = (struct rt_qspi_device *)rtt_dev->rt_spi_device;
- qspi_cfg.qspi_dl_width = qspi_dev->config.qspi_dl_width;
- rt_qspi_configure(qspi_dev, &qspi_cfg);
+ qspi_cfg->qspi_dl_width = qspi_dev->config.qspi_dl_width;
+ rt_qspi_configure(qspi_dev, qspi_cfg);
}
else
#endif
- rt_spi_configure(rtt_dev->rt_spi_device, &cfg);
+ rt_spi_configure(rtt_dev->rt_spi_device, spi_cfg);
}
/* SFUD flash device initialize */
{
@@ -406,7 +358,7 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
sfud_dev->user_data = rtt_dev;
/* initialize SFUD device */
if (sfud_device_init(sfud_dev) != SFUD_SUCCESS) {
- rt_kprintf("ERROR: SPI flash probe failed by SPI device %s.\n", spi_dev_name);
+ LOG_E("ERROR: SPI flash probe failed by SPI device %s.", spi_dev_name);
goto error;
}
/* when initialize success, then copy SFUD flash device's geometry to RT-Thread SPI flash device */
@@ -416,8 +368,8 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
#ifdef SFUD_USING_QSPI
/* reconfigure the QSPI bus for medium size */
if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) {
- qspi_cfg.medium_size = sfud_dev->chip.capacity;
- rt_qspi_configure(qspi_dev, &qspi_cfg);
+ qspi_cfg->medium_size = sfud_dev->chip.capacity;
+ rt_qspi_configure(qspi_dev, qspi_cfg);
if(qspi_dev->enter_qspi_mode != RT_NULL)
qspi_dev->enter_qspi_mode(qspi_dev);
@@ -442,10 +394,10 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
rt_device_register(&(rtt_dev->flash_device), spi_flash_dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
- DEBUG_TRACE("Probe SPI flash %s by SPI device %s success.\n",spi_flash_dev_name, spi_dev_name);
+ LOG_I("Probe SPI flash %s by SPI device %s success.",spi_flash_dev_name, spi_dev_name);
return rtt_dev;
} else {
- rt_kprintf("ERROR: Low memory.\n");
+ LOG_E("ERROR: Low memory.");
goto error;
}
@@ -464,6 +416,26 @@ error:
}
/**
+ * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device.
+ *
+ * @param spi_flash_dev_name the name which will create SPI flash device
+ * @param spi_dev_name using SPI device name
+ *
+ * @return probed SPI flash device, probe failed will return RT_NULL
+ */
+rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name)
+{
+ struct rt_spi_configuration cfg = RT_SFUD_DEFAULT_SPI_CFG;
+#ifndef SFUD_USING_QSPI
+ return rt_sfud_flash_probe_ex(spi_flash_dev_name, spi_dev_name, &cfg, RT_NULL);
+#else
+ struct rt_qspi_configuration qspi_cfg = RT_SFUD_DEFAULT_QSPI_CFG;
+
+ return rt_sfud_flash_probe_ex(spi_flash_dev_name, spi_dev_name, &cfg, &qspi_cfg);
+#endif
+}
+
+/**
* Delete SPI flash device
*
* @param spi_flash_dev SPI flash device
@@ -496,7 +468,7 @@ sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name)
rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name);
if (rt_spi_device == RT_NULL || rt_spi_device->parent.type != RT_Device_Class_SPIDevice) {
- rt_kprintf("ERROR: SPI device %s not found!\n", spi_dev_name);
+ LOG_E("ERROR: SPI device %s not found!", spi_dev_name);
goto __error;
}
@@ -505,7 +477,7 @@ sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name)
sfud_dev = (sfud_flash_t) (rtt_dev->user_data);
return sfud_dev;
} else {
- rt_kprintf("ERROR: SFUD flash device not found!\n");
+ LOG_E("ERROR: SFUD flash device not found!");
goto __error;
}
@@ -520,7 +492,7 @@ sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name)
rtt_dev = (rt_spi_flash_device_t) rt_device_find(flash_dev_name);
if (rtt_dev == RT_NULL || rtt_dev->flash_device.type != RT_Device_Class_Block) {
- rt_kprintf("ERROR: Flash device %s not found!\n", flash_dev_name);
+ LOG_E("ERROR: Flash device %s not found!", flash_dev_name);
goto __error;
}
@@ -528,7 +500,7 @@ sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name)
sfud_dev = (sfud_flash_t) (rtt_dev->user_data);
return sfud_dev;
} else {
- rt_kprintf("ERROR: SFUD flash device not found!\n");
+ LOG_E("ERROR: SFUD flash device not found!");
goto __error;
}
@@ -712,11 +684,13 @@ static void sf(uint8_t argc, char **argv) {
addr = 0;
size = sfud_dev->chip.capacity;
uint32_t start_time, time_cast;
- size_t write_size = SFUD_WRITE_MAX_PAGE_SIZE, read_size = SFUD_WRITE_MAX_PAGE_SIZE;
+ size_t write_size = SFUD_WRITE_MAX_PAGE_SIZE, read_size = SFUD_WRITE_MAX_PAGE_SIZE, cur_op_size;
uint8_t *write_data = rt_malloc(write_size), *read_data = rt_malloc(read_size);
if (write_data && read_data) {
- rt_memset(write_data, 0x55, write_size);
+ for (i = 0; i < write_size; i ++) {
+ write_data[i] = i & 0xFF;
+ }
/* benchmark testing */
rt_kprintf("Erasing the %s %ld bytes data, waiting...\n", sfud_dev->name, size);
start_time = rt_tick_get();
@@ -732,7 +706,12 @@ static void sf(uint8_t argc, char **argv) {
rt_kprintf("Writing the %s %ld bytes data, waiting...\n", sfud_dev->name, size);
start_time = rt_tick_get();
for (i = 0; i < size; i += write_size) {
- result = sfud_write(sfud_dev, addr + i, write_size, write_data);
+ if (i + write_size <= size) {
+ cur_op_size = write_size;
+ } else {
+ cur_op_size = size - i;
+ }
+ result = sfud_write(sfud_dev, addr + i, cur_op_size, write_data);
if (result != SFUD_SUCCESS) {
rt_kprintf("Writing %s failed, already wr for %lu bytes, write %d each time\n", sfud_dev->name, i, write_size);
break;
@@ -750,12 +729,13 @@ static void sf(uint8_t argc, char **argv) {
start_time = rt_tick_get();
for (i = 0; i < size; i += read_size) {
if (i + read_size <= size) {
- result = sfud_read(sfud_dev, addr + i, read_size, read_data);
+ cur_op_size = read_size;
} else {
- result = sfud_read(sfud_dev, addr + i, size - i, read_data);
+ cur_op_size = size - i;
}
+ result = sfud_read(sfud_dev, addr + i, cur_op_size, read_data);
/* data check */
- if (memcmp(write_data, read_data, read_size))
+ if (memcmp(write_data, read_data, cur_op_size))
{
rt_kprintf("Data check ERROR! Please check you flash by other command.\n");
result = SFUD_ERR_READ;
diff --git a/components/drivers/spi/spi_flash_sfud.h b/components/drivers/spi/spi_flash_sfud.h
index 490f2feadb..932b7f879c 100644
--- a/components/drivers/spi/spi_flash_sfud.h
+++ b/components/drivers/spi/spi_flash_sfud.h
@@ -27,6 +27,19 @@
rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name);
/**
+ * Probe SPI flash by SFUD (Serial Flash Universal Driver) driver library and though SPI device by specified configuration.
+ *
+ * @param spi_flash_dev_name the name which will create SPI flash device
+ * @param spi_dev_name using SPI device name
+ * @param spi_cfg SPI device configuration
+ * @param qspi_cfg QSPI device configuration
+ *
+ * @return probed SPI flash device, probe failed will return RT_NULL
+ */
+rt_spi_flash_device_t rt_sfud_flash_probe_ex(const char *spi_flash_dev_name, const char *spi_dev_name,
+ struct rt_spi_configuration *spi_cfg, struct rt_qspi_configuration *qspi_cfg);
+
+/**
* Delete SPI flash device
*
* @param spi_flash_dev SPI flash device
diff --git a/components/drivers/spi/spi_msd.c b/components/drivers/spi/spi_msd.c
index a109fd9488..191933e421 100644
--- a/components/drivers/spi/spi_msd.c
+++ b/components/drivers/spi/spi_msd.c
@@ -234,24 +234,30 @@ static rt_err_t _send_cmd(
else if (type == response_r2)
{
/* initial message */
+ /* Prevent non-aligned address access, use recv_buffer to receive data */
message.send_buf = RT_NULL;
- message.recv_buf = response + 1;
+ message.recv_buf = recv_buffer;
message.length = 1;
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
+ response[1] = recv_buffer[0];
}
else if ((type == response_r3) || (type == response_r7))
{
/* initial message */
message.send_buf = RT_NULL;
- message.recv_buf = response + 1;
+ message.recv_buf = recv_buffer;
message.length = 4;
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
+ response[1] = recv_buffer[0];
+ response[2] = recv_buffer[1];
+ response[3] = recv_buffer[2];
+ response[4] = recv_buffer[3];
}
else
{
diff --git a/components/drivers/src/dataqueue.c b/components/drivers/src/dataqueue.c
index 5a802c0711..1651417bb9 100644
--- a/components/drivers/src/dataqueue.c
+++ b/components/drivers/src/dataqueue.c
@@ -28,6 +28,7 @@ rt_data_queue_init(struct rt_data_queue *queue,
void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event))
{
RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(size > 0);
queue->evt_notify = evt_notify;
@@ -37,6 +38,8 @@ rt_data_queue_init(struct rt_data_queue *queue,
queue->get_index = 0;
queue->put_index = 0;
+ queue->is_empty = 1;
+ queue->is_full = 0;
rt_list_init(&(queue->suspended_push_list));
rt_list_init(&(queue->suspended_pop_list));
@@ -60,14 +63,14 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
rt_thread_t thread;
rt_err_t result;
- RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
result = RT_EOK;
thread = rt_thread_self();
level = rt_hw_interrupt_disable();
- while (queue->put_index - queue->get_index == queue->size)
+ while (queue->is_full)
{
/* queue is full */
if (timeout == 0)
@@ -108,9 +111,18 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
if (result != RT_EOK) goto __exit;
}
- queue->queue[queue->put_index % queue->size].data_ptr = data_ptr;
- queue->queue[queue->put_index % queue->size].data_size = data_size;
+ queue->queue[queue->put_index].data_ptr = data_ptr;
+ queue->queue[queue->put_index].data_size = data_size;
queue->put_index += 1;
+ if (queue->put_index == queue->size)
+ {
+ queue->put_index = 0;
+ }
+ queue->is_empty = 0;
+ if (queue->put_index == queue->get_index)
+ {
+ queue->is_full = 1;
+ }
/* there is at least one thread in suspended list */
if (!rt_list_isempty(&(queue->suspended_pop_list)))
@@ -150,8 +162,8 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
rt_thread_t thread;
rt_err_t result;
- RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
RT_ASSERT(data_ptr != RT_NULL);
RT_ASSERT(size != RT_NULL);
@@ -159,7 +171,7 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
thread = rt_thread_self();
level = rt_hw_interrupt_disable();
- while (queue->get_index == queue->put_index)
+ while (queue->is_empty)
{
/* queue is empty */
if (timeout == 0)
@@ -200,12 +212,20 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
goto __exit;
}
- *data_ptr = queue->queue[queue->get_index % queue->size].data_ptr;
- *size = queue->queue[queue->get_index % queue->size].data_size;
-
+ *data_ptr = queue->queue[queue->get_index].data_ptr;
+ *size = queue->queue[queue->get_index].data_size;
queue->get_index += 1;
+ if (queue->get_index == queue->size)
+ {
+ queue->get_index = 0;
+ }
+ queue->is_full = 0;
+ if (queue->put_index == queue->get_index)
+ {
+ queue->is_empty = 1;
+ }
- if ((queue->put_index - queue->get_index) <= queue->lwm)
+ if (rt_data_queue_len(queue) <= queue->lwm)
{
/* there is at least one thread in suspended list */
if (!rt_list_isempty(&(queue->suspended_push_list)))
@@ -244,39 +264,47 @@ __exit:
}
RTM_EXPORT(rt_data_queue_pop);
-rt_err_t rt_data_queue_peak(struct rt_data_queue *queue,
+rt_err_t rt_data_queue_peek(struct rt_data_queue *queue,
const void** data_ptr,
rt_size_t *size)
{
rt_ubase_t level;
- RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
- level = rt_hw_interrupt_disable();
-
- if (queue->get_index == queue->put_index)
+ if (queue->is_empty)
{
- rt_hw_interrupt_enable(level);
-
return -RT_EEMPTY;
}
- *data_ptr = queue->queue[queue->get_index % queue->size].data_ptr;
- *size = queue->queue[queue->get_index % queue->size].data_size;
+ level = rt_hw_interrupt_disable();
+
+ *data_ptr = queue->queue[queue->get_index].data_ptr;
+ *size = queue->queue[queue->get_index].data_size;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
-RTM_EXPORT(rt_data_queue_peak);
+RTM_EXPORT(rt_data_queue_peek);
void rt_data_queue_reset(struct rt_data_queue *queue)
{
+ rt_ubase_t level;
struct rt_thread *thread;
- register rt_ubase_t temp;
+ RT_ASSERT(queue != RT_NULL);
RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
+
+ level = rt_hw_interrupt_disable();
+
+ queue->get_index = 0;
+ queue->put_index = 0;
+ queue->is_empty = 1;
+ queue->is_full = 0;
+
+ rt_hw_interrupt_enable(level);
rt_enter_critical();
/* wakeup all suspend threads */
@@ -285,7 +313,7 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
while (!rt_list_isempty(&(queue->suspended_pop_list)))
{
/* disable interrupt */
- temp = rt_hw_interrupt_disable();
+ level = rt_hw_interrupt_disable();
/* get next suspend thread */
thread = rt_list_entry(queue->suspended_pop_list.next,
@@ -302,14 +330,14 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
rt_thread_resume(thread);
/* enable interrupt */
- rt_hw_interrupt_enable(temp);
+ rt_hw_interrupt_enable(level);
}
/* resume on push list */
while (!rt_list_isempty(&(queue->suspended_push_list)))
{
/* disable interrupt */
- temp = rt_hw_interrupt_disable();
+ level = rt_hw_interrupt_disable();
/* get next suspend thread */
thread = rt_list_entry(queue->suspended_push_list.next,
@@ -326,7 +354,7 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
rt_thread_resume(thread);
/* enable interrupt */
- rt_hw_interrupt_enable(temp);
+ rt_hw_interrupt_enable(level);
}
rt_exit_critical();
@@ -338,19 +366,49 @@ rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue)
{
rt_ubase_t level;
- RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
RT_ASSERT(queue != RT_NULL);
-
- level = rt_hw_interrupt_disable();
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
/* wakeup all suspend threads */
rt_data_queue_reset(queue);
+ level = rt_hw_interrupt_disable();
queue->magic = 0;
- rt_free(queue->queue);
-
rt_hw_interrupt_enable(level);
+
+ rt_free(queue->queue);
return RT_EOK;
}
RTM_EXPORT(rt_data_queue_deinit);
+
+rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue)
+{
+ rt_ubase_t level;
+ rt_int16_t len;
+
+ RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
+
+ if (queue->is_empty)
+ {
+ return 0;
+ }
+
+ level = rt_hw_interrupt_disable();
+
+ if (queue->put_index > queue->get_index)
+ {
+ len = queue->put_index - queue->get_index;
+ }
+ else
+ {
+ len = queue->size + queue->put_index - queue->get_index;
+ }
+
+ rt_hw_interrupt_enable(level);
+
+ return len;
+}
+RTM_EXPORT(rt_data_queue_len);
+
diff --git a/components/drivers/src/pipe.c b/components/drivers/src/pipe.c
index 2a7e143f6c..bd392cba2b 100644
--- a/components/drivers/src/pipe.c
+++ b/components/drivers/src/pipe.c
@@ -41,16 +41,16 @@ static int pipe_fops_open(struct dfs_fd *fd)
switch (fd->flags & O_ACCMODE)
{
- case O_RDONLY:
- pipe->readers ++;
- break;
- case O_WRONLY:
- pipe->writers ++;
- break;
- case O_RDWR:
- pipe->readers ++;
- pipe->writers ++;
- break;
+ case O_RDONLY:
+ pipe->readers ++;
+ break;
+ case O_WRONLY:
+ pipe->writers ++;
+ break;
+ case O_RDWR:
+ pipe->readers ++;
+ pipe->writers ++;
+ break;
}
device->ref_count ++;
@@ -73,16 +73,16 @@ static int pipe_fops_close(struct dfs_fd *fd)
switch (fd->flags & O_ACCMODE)
{
- case O_RDONLY:
- pipe->readers --;
- break;
- case O_WRONLY:
- pipe->writers --;
- break;
- case O_RDWR:
- pipe->readers --;
- pipe->writers --;
- break;
+ case O_RDONLY:
+ pipe->readers --;
+ break;
+ case O_WRONLY:
+ pipe->writers --;
+ break;
+ case O_RDWR:
+ pipe->readers --;
+ pipe->writers --;
+ break;
}
if (pipe->writers == 0)
@@ -123,15 +123,15 @@ static int pipe_fops_ioctl(struct dfs_fd *fd, int cmd, void *args)
switch (cmd)
{
- case FIONREAD:
- *((int*)args) = rt_ringbuffer_data_len(pipe->fifo);
- break;
- case FIONWRITE:
- *((int*)args) = rt_ringbuffer_space_len(pipe->fifo);
- break;
- default:
- ret = -EINVAL;
- break;
+ case FIONREAD:
+ *((int*)args) = rt_ringbuffer_data_len(pipe->fifo);
+ break;
+ case FIONWRITE:
+ *((int*)args) = rt_ringbuffer_space_len(pipe->fifo);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
}
return ret;
diff --git a/components/drivers/src/ringbuffer.c b/components/drivers/src/ringbuffer.c
index c6a491a7cc..88afd19506 100644
--- a/components/drivers/src/ringbuffer.c
+++ b/components/drivers/src/ringbuffer.c
@@ -194,6 +194,40 @@ rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
RTM_EXPORT(rt_ringbuffer_get);
/**
+ * peak data from ring buffer
+ */
+rt_size_t rt_ringbuffer_peak(struct rt_ringbuffer *rb, rt_uint8_t **ptr)
+{
+ RT_ASSERT(rb != RT_NULL);
+
+ *ptr = RT_NULL;
+
+ /* whether has enough data */
+ rt_size_t size = rt_ringbuffer_data_len(rb);
+
+ /* no data */
+ if (size == 0)
+ return 0;
+
+ *ptr = &rb->buffer_ptr[rb->read_index];
+
+ if(rb->buffer_size - rb->read_index > size)
+ {
+ rb->read_index += size;
+ return size;
+ }
+
+ size = rb->buffer_size - rb->read_index;
+
+ /* we are going into the other side of the mirror */
+ rb->read_mirror = ~rb->read_mirror;
+ rb->read_index = 0;
+
+ return size;
+}
+RTM_EXPORT(rt_ringbuffer_peak);
+
+/**
* put a character into ring buffer
*/
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch)
diff --git a/components/drivers/src/workqueue.c b/components/drivers/src/workqueue.c
index 2e0280df3a..2b5630d8d0 100644
--- a/components/drivers/src/workqueue.c
+++ b/components/drivers/src/workqueue.c
@@ -424,6 +424,6 @@ int rt_work_sys_workqueue_init(void)
return RT_EOK;
}
-INIT_DEVICE_EXPORT(rt_work_sys_workqueue_init);
+INIT_PREV_EXPORT(rt_work_sys_workqueue_init);
#endif
#endif
diff --git a/components/drivers/touch/SConscript b/components/drivers/touch/SConscript
index f370b2aba6..6c2a126c9c 100644
--- a/components/drivers/touch/SConscript
+++ b/components/drivers/touch/SConscript
@@ -6,6 +6,6 @@ cwd = GetCurrentDir()
src = ['touch.c']
CPPPATH = [cwd, cwd + '/../include']
-group = DefineGroup('Touch', src, depend = ['RT_USING_TOUCH', 'RT_USING_DEVICE'], CPPPATH = CPPPATH)
+group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_TOUCH', 'RT_USING_DEVICE'], CPPPATH = CPPPATH)
Return('group')
diff --git a/components/drivers/touch/touch.c b/components/drivers/touch/touch.c
index 80ba6378bb..e9595e9f8f 100644
--- a/components/drivers/touch/touch.c
+++ b/components/drivers/touch/touch.c
@@ -16,12 +16,9 @@
#include <rtdbg.h>
/* ISR for touch interrupt */
-static void irq_callback(void *args)
+void rt_hw_touch_isr(rt_touch_t touch)
{
- rt_touch_t touch;
-
- touch = (rt_touch_t)args;
-
+ RT_ASSERT(touch);
if (touch->parent.rx_indicate == RT_NULL)
{
return;
@@ -35,9 +32,17 @@ static void irq_callback(void *args)
touch->parent.rx_indicate(&touch->parent, 1);
}
+#ifdef RT_TOUCH_PIN_IRQ
+static void touch_irq_callback(void *param)
+{
+ rt_hw_touch_isr((rt_touch_t)param);
+}
+#endif
+
/* touch interrupt initialization function */
static rt_err_t rt_touch_irq_init(rt_touch_t touch)
{
+#ifdef RT_TOUCH_PIN_IRQ
if (touch->config.irq_pin.pin == RT_PIN_NONE)
{
return -RT_EINVAL;
@@ -47,18 +52,19 @@ static rt_err_t rt_touch_irq_init(rt_touch_t touch)
if (touch->config.irq_pin.mode == PIN_MODE_INPUT_PULLDOWN)
{
- rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING, irq_callback, (void *)touch);
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING, touch_irq_callback, (void *)touch);
}
else if (touch->config.irq_pin.mode == PIN_MODE_INPUT_PULLUP)
{
- rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, irq_callback, (void *)touch);
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, touch_irq_callback, (void *)touch);
}
else if (touch->config.irq_pin.mode == PIN_MODE_INPUT)
{
- rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, irq_callback, (void *)touch);
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, touch_irq_callback, (void *)touch);
}
rt_pin_irq_enable(touch->config.irq_pin.pin, PIN_IRQ_ENABLE);
+#endif
return RT_EOK;
}
@@ -66,19 +72,23 @@ static rt_err_t rt_touch_irq_init(rt_touch_t touch)
/* touch interrupt enable */
static void rt_touch_irq_enable(rt_touch_t touch)
{
+#ifdef RT_TOUCH_PIN_IRQ
if (touch->config.irq_pin.pin != RT_PIN_NONE)
{
rt_pin_irq_enable(touch->config.irq_pin.pin, RT_TRUE);
}
+#endif
}
/* touch interrupt disable */
static void rt_touch_irq_disable(rt_touch_t touch)
{
+#ifdef RT_TOUCH_PIN_IRQ
if (touch->config.irq_pin.pin != RT_PIN_NONE)
{
rt_pin_irq_enable(touch->config.irq_pin.pin, RT_FALSE);
}
+#endif
}
static rt_err_t rt_touch_open(rt_device_t dev, rt_uint16_t oflag)
diff --git a/components/drivers/touch/touch.h b/components/drivers/touch/touch.h
index 6b7288a5a0..be12c24206 100644
--- a/components/drivers/touch/touch.h
+++ b/components/drivers/touch/touch.h
@@ -45,6 +45,9 @@ extern "C" {
#define RT_TOUCH_CTRL_SET_X_TO_Y (5) /* Set X Y coordinate exchange */
#define RT_TOUCH_CTRL_DISABLE_INT (6) /* Disable interrupt */
#define RT_TOUCH_CTRL_ENABLE_INT (7) /* Enable interrupt */
+#define RT_TOUCH_CTRL_POWER_ON (8) /* Touch Power On */
+#define RT_TOUCH_CTRL_POWER_OFF (9) /* Touch Power Off */
+#define RT_TOUCH_CTRL_GET_STATUS (10) /* Get Touch Power Status */
/* Touch event */
#define RT_TOUCH_EVENT_NONE (0) /* Touch none */
@@ -63,7 +66,9 @@ struct rt_touch_info
struct rt_touch_config
{
+#ifdef RT_TOUCH_PIN_IRQ
struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */
+#endif
char *dev_name; /* The name of the communication device */
void *user_data;
};
@@ -100,6 +105,9 @@ int rt_hw_touch_register(rt_touch_t touch,
rt_uint32_t flag,
void *data);
+/* if you doesn't use pin device. you must call this function in your touch irq callback */
+void rt_hw_touch_isr(rt_touch_t touch);
+
#ifdef __cplusplus
}
#endif
diff --git a/components/drivers/usb/usbdevice/class/audio_mic.c b/components/drivers/usb/usbdevice/class/audio_mic.c
index 4ac85711ad..23ade2d9b6 100644
--- a/components/drivers/usb/usbdevice/class/audio_mic.c
+++ b/components/drivers/usb/usbdevice/class/audio_mic.c
@@ -9,10 +9,7 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
-
#include "drivers/usb_device.h"
#include "audio.h"
diff --git a/components/drivers/usb/usbdevice/class/audio_speaker.c b/components/drivers/usb/usbdevice/class/audio_speaker.c
index 84c36d2053..e9a3ffaf40 100644
--- a/components/drivers/usb/usbdevice/class/audio_speaker.c
+++ b/components/drivers/usb/usbdevice/class/audio_speaker.c
@@ -9,10 +9,7 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
-
#include "drivers/usb_device.h"
#include "audio.h"
diff --git a/components/drivers/usb/usbdevice/class/cdc_vcom.c b/components/drivers/usb/usbdevice/class/cdc_vcom.c
index c4fc3b0ad9..f9ea466bd5 100644
--- a/components/drivers/usb/usbdevice/class/cdc_vcom.c
+++ b/components/drivers/usb/usbdevice/class/cdc_vcom.c
@@ -13,8 +13,6 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
#include <drivers/serial.h>
#include "drivers/usb_device.h"
@@ -589,8 +587,9 @@ ufunction_t rt_usbd_function_cdc_create(udevice_t device)
/* create a cdc function */
func = rt_usbd_function_new(device, &dev_desc, &ops);
- //not support HS
- //rt_usbd_device_set_qualifier(device, &dev_qualifier);
+
+ /* support HS */
+ rt_usbd_device_set_qualifier(device, &dev_qualifier);
/* allocate memory for cdc vcom data */
data = (struct vcom*)rt_malloc(sizeof(struct vcom));
diff --git a/components/drivers/usb/usbdevice/class/hid.c b/components/drivers/usb/usbdevice/class/hid.c
index 5df63daddf..52e50296a4 100644
--- a/components/drivers/usb/usbdevice/class/hid.c
+++ b/components/drivers/usb/usbdevice/class/hid.c
@@ -11,13 +11,9 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
-
#include "drivers/usb_common.h"
#include "drivers/usb_device.h"
-
#include "hid.h"
#ifdef RT_USB_DEVICE_HID
@@ -29,7 +25,7 @@ struct hid_s
uep_t ep_in;
uep_t ep_out;
int status;
- rt_uint16_t protocol;
+ rt_uint8_t protocol;
rt_uint8_t report_buf[MAX_REPORT_SIZE];
struct rt_messagequeue hid_mq;
};
@@ -246,7 +242,7 @@ static struct udevice_descriptor _dev_desc =
USB_DESC_LENGTH_DEVICE, //bLength;
USB_DESC_TYPE_DEVICE, //type;
USB_BCD_VERSION, //bcdUSB;
- USB_CLASS_HID, //bDeviceClass;
+ 0x0, //bDeviceClass;
0x00, //bDeviceSubClass;
0x00, //bDeviceProtocol;
64, //bMaxPacketSize0;
@@ -266,8 +262,8 @@ static struct usb_qualifier_descriptor dev_qualifier =
sizeof(dev_qualifier), //bLength
USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType
0x0200, //bcdUSB
- USB_CLASS_MASS_STORAGE, //bDeviceClass
- 0x06, //bDeviceSubClass
+ 0x0, //bDeviceClass
+ 0x0, //bDeviceSubClass
0x50, //bDeviceProtocol
64, //bMaxPacketSize0
0x01, //bNumConfigurations
@@ -347,7 +343,7 @@ const static struct uhid_comm_descriptor _hid_comm_desc =
USB_DYNAMIC | USB_DIR_IN,
USB_EP_ATTR_INT,
0x40,
- 0x01,
+ 0x0A,
},
/* Endpoint Descriptor OUT */
@@ -458,6 +454,7 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
struct hid_s *data = (struct hid_s *) func->user_data;
+
switch (setup->bRequest)
{
case USB_REQ_GET_DESCRIPTOR:
@@ -486,7 +483,7 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
dcd_ep0_send_status(func->device->dcd);
break;
case USB_HID_REQ_GET_PROTOCOL:
- rt_usbd_ep0_write(func->device, &data->protocol,2);
+ rt_usbd_ep0_write(func->device, &data->protocol,1);
break;
case USB_HID_REQ_SET_REPORT:
@@ -692,8 +689,9 @@ ufunction_t rt_usbd_function_hid_create(udevice_t device)
/* create a cdc function */
func = rt_usbd_function_new(device, &_dev_desc, &ops);
- //not support hs
- //rt_usbd_device_set_qualifier(device, &_dev_qualifier);
+
+ /* For high speed mode supporting */
+ rt_usbd_device_set_qualifier(device, &dev_qualifier);
/* allocate memory for cdc vcom data */
data = (struct hid_s*)rt_malloc(sizeof(struct hid_s));
diff --git a/components/drivers/usb/usbdevice/class/mstorage.c b/components/drivers/usb/usbdevice/class/mstorage.c
index a681b8212f..6991d97eae 100644
--- a/components/drivers/usb/usbdevice/class/mstorage.c
+++ b/components/drivers/usb/usbdevice/class/mstorage.c
@@ -12,7 +12,6 @@
*/
#include <rtthread.h>
-#include <rtservice.h>
#include "drivers/usb_device.h"
#include "mstorage.h"
@@ -610,8 +609,11 @@ static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size)
rt_usbd_ep_set_stall(func->device, data->ep_out);
}
else
- {
- rt_usbd_ep_set_stall(func->device, data->ep_in);
+ {
+ //rt_kprintf("warning:in stall path but not stall\n");
+
+ /* FIXME: Disable the operation or the disk cannot work. */
+ //rt_usbd_ep_set_stall(func->device, data->ep_in);
}
data->csw_response.data_reside = 0;
}
@@ -719,9 +721,22 @@ static void _cb_len_calc(ufunction_t func, struct scsi_cmd* cmd,
break;
}
}
+
+ //workaround: for stability in full-speed mode
+ else if(cmd->cmd_len == 12)
+ {
+ switch(cmd->type)
+ {
+ case COUNT:
+ data->cb_data_size = cbw->cb[4];
+ break;
+ default:
+ break;
+ }
+ }
else
{
-// rt_kprintf("cmd_len error %d\n", cmd->cmd_len);
+ rt_kprintf("cmd_len error %d\n", cmd->cmd_len);
}
}
@@ -737,7 +752,7 @@ static rt_bool_t _cbw_verify(ufunction_t func, struct scsi_cmd* cmd,
data = (struct mstorage*)func->user_data;
if(cmd->cmd_len != cbw->cb_len)
{
- // rt_kprintf("cb_len error\n");
+ rt_kprintf("cb_len error\n");
cmd->cmd_len = cbw->cb_len;
}
@@ -768,7 +783,7 @@ static rt_bool_t _cbw_verify(ufunction_t func, struct scsi_cmd* cmd,
if(cbw->xfer_len < data->cb_data_size)
{
- // rt_kprintf("xfer_len < data_size\n");
+ rt_kprintf("xfer_len < data_size\n");
data->cb_data_size = cbw->xfer_len;
data->csw_response.status = 1;
}
diff --git a/components/drivers/usb/usbdevice/class/winusb.c b/components/drivers/usb/usbdevice/class/winusb.c
index bf4b353d73..4af6dba3cf 100644
--- a/components/drivers/usb/usbdevice/class/winusb.c
+++ b/components/drivers/usb/usbdevice/class/winusb.c
@@ -8,8 +8,6 @@
* 2017-11-16 ZYH first version
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
#include <drivers/usb_device.h>
#include "winusb.h"
@@ -121,7 +119,7 @@ const static char* _ustring[] =
ALIGN(4)
struct usb_os_proerty winusb_proerty[] =
{
- USB_OS_PROERTY_DESC(USB_OS_PROERTY_TYPE_REG_SZ,"DeviceInterfaceGUID",RT_WINUSB_GUID),
+ USB_OS_PROPERTY_DESC(USB_OS_PROPERTY_TYPE_REG_SZ,"DeviceInterfaceGUID",RT_WINUSB_GUID),
};
ALIGN(4)
diff --git a/components/drivers/usb/usbhost/class/udisk.c b/components/drivers/usb/usbhost/class/udisk.c
index 1509a26105..6c8030b29a 100644
--- a/components/drivers/usb/usbhost/class/udisk.c
+++ b/components/drivers/usb/usbhost/class/udisk.c
@@ -186,7 +186,7 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
{
int i = 0;
rt_err_t ret;
- char dname[4];
+ char dname[8];
char sname[8];
rt_uint8_t max_lun, *sector, sense[18], inquiry[36];
struct dfs_partition part[MAX_PARTITION_COUNT];
diff --git a/components/drivers/usb/usbhost/core/hub.c b/components/drivers/usb/usbhost/core/hub.c
index fb6cd9c406..eefa571472 100644
--- a/components/drivers/usb/usbhost/core/hub.c
+++ b/components/drivers/usb/usbhost/core/hub.c
@@ -417,8 +417,13 @@ static rt_err_t rt_usbh_hub_port_change(uhub_t hub)
if(reconnect)
{
- if(hub->child[i] != RT_NULL && hub->child[i]->status != DEV_STATUS_IDLE)
+ if(hub->child[i] != RT_NULL && hub->child[i]->status != DEV_STATUS_IDLE)
+ {
rt_usbh_detach_instance(hub->child[i]);
+
+ /* Child device have been detach. Set hub->child[i] to NULL. */
+ hub->child[i] = RT_NULL;
+ }
ret = rt_usbh_hub_port_debounce(hub, i + 1);
if(ret != RT_EOK) continue;
@@ -532,7 +537,12 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
}
/* get hub ports number */
- hub->num_ports = hub->hub_desc.num_ports;
+ /* If hub device supported ports over USB_HUB_PORT_NUM(Ex: 8 port hub). Set hub->num_ports to USB_HUB_PORT_NUM */
+ if(hub->hub_desc.num_ports > USB_HUB_PORT_NUM)
+ hub->num_ports = USB_HUB_PORT_NUM;
+ else
+ hub->num_ports = hub->hub_desc.num_ports;
+
hub->hcd = device->hcd;
hub->self = device;
@@ -607,7 +617,6 @@ static rt_err_t rt_usbh_hub_disable(void* arg)
}
if(hub != RT_NULL) rt_free(hub);
- if(intf != RT_NULL) rt_free(intf);
return RT_EOK;
}
diff --git a/components/drivers/usb/usbhost/core/usbhost_core.c b/components/drivers/usb/usbhost/core/usbhost_core.c
index 71341a33c3..d72dca82f2 100644
--- a/components/drivers/usb/usbhost/core/usbhost_core.c
+++ b/components/drivers/usb/usbhost/core/usbhost_core.c
@@ -162,6 +162,10 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
/* alloc memory for configuration descriptor */
device->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength);
+ if(device->cfg_desc == RT_NULL)
+ {
+ return RT_ENOMEM;
+ }
rt_memset(device->cfg_desc, 0, cfg_desc.wTotalLength);
/* get full configuration descriptor */
@@ -219,6 +223,10 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
{
/* allocate memory for interface device */
device->intf[i] = (struct uhintf*)rt_malloc(sizeof(struct uhintf));
+ if(device->intf[i] == RT_NULL)
+ {
+ return RT_ENOMEM;
+ }
device->intf[i]->drv = drv;
device->intf[i]->device = device;
device->intf[i]->intf_desc = intf_desc;
diff --git a/components/drivers/wlan/wlan_mgnt.c b/components/drivers/wlan/wlan_mgnt.c
index cf2204c6b3..fefe700acc 100644
--- a/components/drivers/wlan/wlan_mgnt.c
+++ b/components/drivers/wlan/wlan_mgnt.c
@@ -713,7 +713,7 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
}
COMPLETE_UNLOCK();
#ifdef RT_WLAN_WORK_THREAD_ENABLE
- rt_wlan_send_to_thread(user_event, RT_NULL, 0);
+ rt_wlan_send_to_thread(user_event, user_buff.data, user_buff.len);
#else
{
void *user_parameter;