diff options
| author | cliff-cmc <[email protected]> | 2021-02-26 11:09:27 +0800 |
|---|---|---|
| committer | Cliff Chen <[email protected]> | 2021-02-26 11:45:19 +0800 |
| commit | eea0c3d74a40f73235da45c6f77e8b411ac94cf2 (patch) | |
| tree | a6906f1aed7118ab53dbe18f2ee4727a754583af /components/drivers | |
| parent | 1a9ecf27f31277750d92c921b62503f75275e122 (diff) | |
| parent | fae0fa8eea4c0e797940bf1eddc8ee6c1711734a (diff) | |
Add memtrace command for memheap.c
Diffstat (limited to 'components/drivers')
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(×tamp, &now); +#ifdef _WIN32 + _gmtime32_s(&now, ×tamp); +#else + gmtime_r(×tamp, &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(×tamp, &now); +#ifdef _WIN32 + _gmtime32_s(&now, ×tamp); +#else + gmtime_r(×tamp, &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(×tamp, &now); + +#ifdef _WIN32 + _gmtime32_s(&now, ×tamp); +#else + gmtime_r(×tamp, &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(×tamp, &now); +#ifdef _WIN32 + _gmtime32_s(&now, ×tamp); +#else + gmtime_r(×tamp, &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; |
