diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index a25c2c34964065d5f8a44c6f9e1da5fbf935d373..6b40d8bfc29242ba8b123a46e4ee3d3c2d19a038 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -37,6 +37,7 @@ jobs: - {RTT_BSP: "at91/at91sam9g45", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "at91/at91sam9260", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "allwinner_tina", RTT_TOOL_CHAIN: "sourcery-arm"} + - {RTT_BSP: "cypress/psoc6-cy8cproto-4343w", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "ft32/ft32f072xb-starter", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "gd32/arm/gd32103c-eval", RTT_TOOL_CHAIN: "sourcery-arm"} - {RTT_BSP: "gd32/arm/gd32105c-eval", RTT_TOOL_CHAIN: "sourcery-arm"} diff --git a/bsp/cypress/libraries/HAL_Drivers/SConscript b/bsp/cypress/libraries/HAL_Drivers/SConscript index 917db4e8e420b4dc0fc03af5d5e2190df33ae2b7..4552c5babfec76f756250749e5e0d501ea53646e 100644 --- a/bsp/cypress/libraries/HAL_Drivers/SConscript +++ b/bsp/cypress/libraries/HAL_Drivers/SConscript @@ -38,6 +38,9 @@ if GetDepend(['BSP_USING_SPI']): if GetDepend(['BSP_USING_ADC']): src += ['drv_adc.c'] +if GetDepend(['BSP_USING_USBD']): + src += ['drv_usbd.c'] + if GetDepend('BSP_USING_RTC'): src += ['drv_rtc.c'] @@ -46,6 +49,9 @@ if GetDepend('BSP_USING_ON_CHIP_FLASH'): if GetDepend(['RT_USING_WDT']): src += ['drv_wdt.c'] + +if GetDepend(['RT_USING_DAC']): + src += ['drv_dac.c'] if GetDepend(['BSP_USING_TIM']): src += ['drv_hwtimer.c'] diff --git a/bsp/cypress/libraries/HAL_Drivers/drv_dac.c b/bsp/cypress/libraries/HAL_Drivers/drv_dac.c new file mode 100644 index 0000000000000000000000000000000000000000..453223e420e292342bb7e65b8b4d8d5c4be795c6 --- /dev/null +++ b/bsp/cypress/libraries/HAL_Drivers/drv_dac.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-07-28 rtthread qiu first version + */ +#include "drv_dac.h" +#include "drv_common.h" +#include + +#if defined(BSP_USING_DAC1) || defined(BSP_USING_DAC2) + +#define LOG_TAG "drv.dac" +#include + +struct cyp_dac +{ + cy_stc_csdidac_config_t cyhal_dac_device; + struct rt_dac_device cyp_dac_device; + char *name; +}; + +static struct cyp_dac dac_config[] = + { +#ifdef BSP_USING_DAC1 + DAC1_CONFIG, +#endif +#ifdef BSP_USING_DAC2 + DAC2_CONFIG, +#endif + +}; + +/*get dac channel*/ +static rt_uint32_t cyp_dac_get_channel(rt_uint32_t channel) +{ + rt_uint32_t cyp_dac_channel = 0; + + switch (channel) + { + case 1: + cyp_dac_channel = CY_CSDIDAC_A; + break; + case 2: + cyp_dac_channel = CY_CSDIDAC_B; + break; + default: + RT_ASSERT(0); + break; + } + + return cyp_dac_channel; +} + +struct cyp_dac cyp_adc_obj[sizeof(dac_config) / sizeof(dac_config[0])]; + +cy_stc_csdidac_context_t csdidac_context; + +/*dac device enable*/ +static rt_err_t cyp_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel) +{ + cy_rslt_t result; + + rt_uint32_t cyp_channel; + + RT_ASSERT(device != RT_NULL); + + cyhal_dac_t *dac_device; + + dac_device = device->parent.user_data; + + /* get current dac channel*/ + cyp_channel = cyp_dac_get_channel(channel); + + /*DAC device init*/ + result = Cy_CSDIDAC_Init(&CSDIDAC_csdidac_config, &csdidac_context); + + if (result != RT_EOK) + { + LOG_E("Cy_CSDIDAC_Init fail = %d\n", result); + return -RT_ENOSYS; + } + + return RT_EOK; +} + +/*dac device disable*/ +static rt_err_t cyp_dac_disable(struct rt_dac_device *device, rt_uint32_t channel) +{ + rt_uint32_t cyp_channel; + + cy_rslt_t result; + + RT_ASSERT(device != RT_NULL); + + cyhal_dac_t *dac_device; + + dac_device = device->parent.user_data; + + cyp_channel = cyp_dac_get_channel(channel); + + /*DAC free device*/ + result = Cy_CSDIDAC_OutputDisable(cyp_channel, &csdidac_context); + if (result != RT_EOK) + { + LOG_E("DAC Outputdisable failed. Error: %d\n", result); + return -RT_ENOSYS; + } + return RT_EOK; +} + +/*set dac output value*/ +static rt_err_t cyp_adc_convert(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value) +{ + RT_ASSERT(device != RT_NULL); + + cy_rslt_t result; + + rt_uint32_t cyp_channel; + + cyp_channel = cyp_dac_get_channel(channel); + + result = Cy_CSDIDAC_OutputEnable(cyp_channel, *value, &csdidac_context); + if (result != RT_EOK) + { + LOG_E("DAC channel initialization failed. Error: %d\n", result); + return -RT_ENOSYS; + } + + return RT_EOK; +} + +static const struct rt_dac_ops cyp_dac_ops = +{ + .disabled = cyp_dac_disable, + .enabled = cyp_dac_enabled, + .convert = cyp_adc_convert, +}; + +/*dac device init*/ +static int rt_hw_dac_init(void) +{ + int result = RT_EOK; + + /* save dac name */ + char name_buf[5] = {'d', 'a', 'c', '0', 0}; + + int i = 0; + + i = sizeof(dac_config) / sizeof(dac_config[0]); + + for (i = 0; i < sizeof(dac_config) / sizeof(dac_config[0]); i++) + { + +#ifdef BSP_USING_DAC1 + name_buf[3] = '1'; +#endif + +#ifdef BSP_USING_DAC2 + name_buf[3] = '2'; +#endif + /* register DAC device */ + if (rt_hw_dac_register(&cyp_adc_obj[i].cyp_dac_device, name_buf, &cyp_dac_ops, RT_NULL) == RT_EOK) + { + LOG_E("dac device register success\n"); + } + else + { + LOG_E("dac device register fail\n"); + result = -RT_ERROR; + } + } + return result; +} + +INIT_BOARD_EXPORT(rt_hw_dac_init); + +#endif /* BSP_USING_DAC1 /BSP_USING_DAC2 */ diff --git a/bsp/cypress/libraries/HAL_Drivers/drv_dac.h b/bsp/cypress/libraries/HAL_Drivers/drv_dac.h new file mode 100644 index 0000000000000000000000000000000000000000..cebf4811a74edff7b21b22138e2d1c986680c36a --- /dev/null +++ b/bsp/cypress/libraries/HAL_Drivers/drv_dac.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-07-28 rtthread qiu first version + */ +#ifndef __DRV__DAC_H__ +#define __DRV__DAC_H__ +#include "rtconfig.h" +#include "cycfg.h" +#include +#include "cy_csdidac.h" +#include "cycfg_peripherals.h" + +static const cy_stc_csdidac_pin_t CSDIDAC_csdidac_a_pin = +{ + .ioPcPtr = GPIO_PRT10, + .pin = 0u, +}; +static const cy_stc_csdidac_pin_t CSDIDAC_csdidac_b_pin = +{ + .ioPcPtr = GPIO_PRT10, + .pin = 0u, +}; + +const cy_stc_csdidac_config_t CSDIDAC_csdidac_config = +{ + .base = CSD0, + .csdCxtPtr = &cy_csd_0_context, + .configA = CY_CSDIDAC_GPIO, + .configB = CY_CSDIDAC_GPIO, + .ptrPinA = (const cy_stc_csdidac_pin_t *)&CSDIDAC_csdidac_a_pin, + .ptrPinB = (const cy_stc_csdidac_pin_t *)&CSDIDAC_csdidac_b_pin, + .cpuClk = 100000000u, + .csdInitTime = 25u, +}; + +#ifdef BSP_USING_DAC1 +#ifndef DAC1_CONFIG +#define DAC1_CONFIG \ + { \ + .name = "dac1", \ + } +#endif /* DAC1_CONFIG */ +#endif /*BSP_USING_DAC2*/ + +#ifdef BSP_USING_DAC2 +#ifndef DAC2_CONFIG +#define DAC2_CONFIG \ + { \ + .name = "dac2", \ + } +#endif /* DAC2_CONFIG */ +#endif /*BSP_USING_DAC2*/ + +#endif /*__DRV__DAC_H__*/ diff --git a/bsp/cypress/libraries/HAL_Drivers/drv_gpio.h b/bsp/cypress/libraries/HAL_Drivers/drv_gpio.h index c8beff6d854837205a27713131f45713cd1af8fd..899dc379ce81955975a70d522c3907f3487c2925 100644 --- a/bsp/cypress/libraries/HAL_Drivers/drv_gpio.h +++ b/bsp/cypress/libraries/HAL_Drivers/drv_gpio.h @@ -15,8 +15,6 @@ #include #include "drv_common.h" -#include "cy_retarget_io.h" -#include "cyhal_gpio.h" #include "cyhal_irq_psoc.h" #define GPIO_INTERRUPT_PRIORITY (7u) diff --git a/bsp/cypress/libraries/HAL_Drivers/drv_uart.c b/bsp/cypress/libraries/HAL_Drivers/drv_uart.c index df3d5eca44058122b70f9cb3d404f23b46ab3e79..5081c32a9741f8a6819f380e093e562301fe3fef 100644 --- a/bsp/cypress/libraries/HAL_Drivers/drv_uart.c +++ b/bsp/cypress/libraries/HAL_Drivers/drv_uart.c @@ -12,51 +12,50 @@ #include "drv_uart.h" #include "uart_config.h" -#include "cy_retarget_io.h" #include "cyhal_scb_common.h" enum { - #ifdef BSP_USING_UART0 +#ifdef BSP_USING_UART0 UART0_INDEX, - #endif - #ifdef BSP_USING_UART1 +#endif +#ifdef BSP_USING_UART1 UART1_INDEX, - #endif - #ifdef BSP_USING_UART2 +#endif +#ifdef BSP_USING_UART2 UART2_INDEX, - #endif - #ifdef BSP_USING_UART3 +#endif +#ifdef BSP_USING_UART3 UART3_INDEX, - #endif - #ifdef BSP_USING_UART4 +#endif +#ifdef BSP_USING_UART4 UART4_INDEX, - #endif - #ifdef BSP_USING_UART5 +#endif +#ifdef BSP_USING_UART5 UART5_INDEX, - #endif +#endif }; static struct ifx_uart_config uart_config[] = { - #ifdef BSP_USING_UART0 +#ifdef BSP_USING_UART0 UART0_CONFIG, - #endif - #ifdef BSP_USING_UART1 +#endif +#ifdef BSP_USING_UART1 UART1_CONFIG, - #endif - #ifdef BSP_USING_UART2 +#endif +#ifdef BSP_USING_UART2 UART2_CONFIG, - #endif - #ifdef BSP_USING_UART3 +#endif +#ifdef BSP_USING_UART3 UART3_CONFIG, - #endif - #ifdef BSP_USING_UART4 +#endif +#ifdef BSP_USING_UART4 UART4_CONFIG, - #endif - #ifdef BSP_USING_UART5 +#endif +#ifdef BSP_USING_UART5 UART5_CONFIG, - #endif +#endif }; static struct ifx_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0}; @@ -196,20 +195,20 @@ static rt_err_t ifx_control(struct rt_serial_device *serial, int cmd, void *arg) switch (cmd) { - case RT_DEVICE_CTRL_CLR_INT: + case RT_DEVICE_CTRL_CLR_INT: - break; + break; - case RT_DEVICE_CTRL_SET_INT: - /* Unmasking only the RX fifo not empty interrupt bit */ - uart->config->usart_x->INTR_RX_MASK = SCB_INTR_RX_MASK_NOT_EMPTY_Msk; + case RT_DEVICE_CTRL_SET_INT: + /* Unmasking only the RX fifo not empty interrupt bit */ + uart->config->usart_x->INTR_RX_MASK = SCB_INTR_RX_MASK_NOT_EMPTY_Msk; - /* Interrupt Settings for UART */ - Cy_SysInt_Init(uart->config->UART_SCB_IRQ_cfg, uart->config->userIsr); + /* Interrupt Settings for UART */ + Cy_SysInt_Init(uart->config->UART_SCB_IRQ_cfg, uart->config->userIsr); - /* Enable the interrupt */ - NVIC_EnableIRQ(uart->config->intrSrc); - break; + /* Enable the interrupt */ + NVIC_EnableIRQ(uart->config->intrSrc); + break; } return (RT_EOK); diff --git a/bsp/cypress/libraries/HAL_Drivers/drv_uart.h b/bsp/cypress/libraries/HAL_Drivers/drv_uart.h index b7c2c151573935a93ba6c2e5fd0040e0f7b07007..c5c68ab1b3d6c534e4892b4b5f81022b305f9aef 100644 --- a/bsp/cypress/libraries/HAL_Drivers/drv_uart.h +++ b/bsp/cypress/libraries/HAL_Drivers/drv_uart.h @@ -15,7 +15,6 @@ #include #include "board.h" -#include "cycfg_peripherals.h" #define uart_isr_callback(name) name##_isr_callback diff --git a/bsp/cypress/libraries/HAL_Drivers/uart_config.h b/bsp/cypress/libraries/HAL_Drivers/uart_config.h index ce1d1c392eea88d22be0189fd5bb4a3ed29b91b3..3fd1886fba0aff1ac1ee375e25d30b38bde1aa68 100644 --- a/bsp/cypress/libraries/HAL_Drivers/uart_config.h +++ b/bsp/cypress/libraries/HAL_Drivers/uart_config.h @@ -20,7 +20,7 @@ extern "C" { #ifdef BSP_USING_UART0 /* UART0 device driver structure */ -cy_stc_sysint_t UART2_SCB_IRQ_cfg = +cy_stc_sysint_t UART0_SCB_IRQ_cfg = { .intrSrc = (IRQn_Type) scb_0_interrupt_IRQn, .intrPriority = (7u), diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/SConscript b/bsp/cypress/libraries/IFX_PSOC6_HAL/SConscript index cec37e3ff7781410bb474ac9fee571708b72b923..a01506affbd86e93557827695f720f51cd8169d5 100644 --- a/bsp/cypress/libraries/IFX_PSOC6_HAL/SConscript +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/SConscript @@ -19,8 +19,7 @@ src = Split(''' mtb-hal-cat1/source/cyhal_utils_psoc.c mtb-hal-cat1/source/cyhal_utils.c mtb-hal-cat1/source/cyhal_lptimer.c - mtb-hal-cat1/source/cyhal_irq_psoc.c - mtb-hal-cat1/include_pvt/cyhal_hw_types.h + mtb-hal-cat1/source/cyhal_irq_psoc.c mtb-hal-cat1/COMPONENT_CAT1A/source/triggers/cyhal_triggers_psoc6_02.c mtb-hal-cat1/COMPONENT_CAT1A/source/pin_packages/cyhal_psoc6_02_124_bga.c mtb-pdl-cat1/devices/COMPONENT_CAT1A/source/cy_device.c @@ -37,8 +36,7 @@ src = Split(''' mtb-pdl-cat1/drivers/source/cy_ipc_sema.c mtb-pdl-cat1/drivers/source/cy_ipc_drv.c mtb-pdl-cat1/drivers/source/cy_trigmux.c - mtb-pdl-cat1/drivers/source/cy_prot.c - mtb-pdl-cat1/drivers/source/TOOLCHAIN_ARM/cy_syslib_mdk.s + mtb-pdl-cat1/drivers/source/cy_prot.c TARGET_CY8CKIT-062S2-43012/cybsp.c TARGET_CY8CKIT-062S2-43012/COMPONENT_CM4/system_psoc6_cm4.c TARGET_CY8CKIT-062S2-43012/COMPONENT_BSP_DESIGN_MODUS/GeneratedSource/cycfg.c @@ -95,6 +93,16 @@ if GetDepend(['RT_USING_SPI']): if GetDepend(['RT_USING_I2C']): src += ['mtb-hal-cat1/source/cyhal_i2c.c'] +if GetDepend('BSP_USING_USBD'): + src += ['mtb_shared/usbdev/cy_usb_dev.c'] + src += ['mtb_shared/usbdev/cy_usb_dev_hid.c'] + src += ['mtb-hal-cat1/source/cyhal_usb_dev.c'] + src += ['mtb-pdl-cat1/drivers/source/cy_dma.c'] + src += ['mtb-pdl-cat1/drivers/source/cy_usbfs_dev_drv.c'] + src += ['mtb-pdl-cat1/drivers/source/cy_usbfs_dev_drv_io.c'] + src += ['mtb-pdl-cat1/drivers/source/cy_usbfs_dev_drv_io_dma.c'] + src += ['TARGET_CY8CKIT-062S2-43012/COMPONENT_BSP_DESIGN_MODUS/GeneratedSource/cycfg_usbdev.c'] + if GetDepend('BSP_USING_RTC'): src += ['mtb-pdl-cat1/drivers/source/cy_rtc.c'] src += ['mtb-hal-cat1/source/cyhal_rtc.c'] @@ -121,6 +129,9 @@ if GetDepend(['RT_USING_WDT']): src += ['mtb-pdl-cat1/drivers/source/cy_wdt.c'] src += ['mtb-hal-cat1/source/cyhal_wdt.c'] +if GetDepend(['RT_USING_DAC']): + src += ['mtb_shared/csdidac/cy_csdidac.c'] + if GetDepend(['RT_USING_HWTIMER']): src += ['mtb-hal-cat1/source/cyhal_timer.c'] @@ -129,13 +140,14 @@ path = [cwd + '/capsense', cwd + '/retarget-io', cwd + '/core-lib/include', cwd + '/mtb_shared/serial-flash', - cwd + '/mtb-hal-cat1/include', - cwd + '/mtb-hal-cat1/include_pvt', + cwd + '/mtb_shared/usbdev', + cwd + '/mtb_shared/csdidac', cwd + '/mtb-pdl-cat1/cmsis/include', cwd + '/mtb-pdl-cat1/drivers/include', - cwd + '/mtb-hal-cat1/COMPONENT_CAT1A/include', cwd + '/mtb-pdl-cat1/devices/COMPONENT_CAT1A/include', - cwd + '/mtb-pdl-cat1/devices/COMPONENT_CAT1B/include', + cwd + '/mtb-hal-cat1/include_pvt', + cwd + '/mtb-hal-cat1/include', + cwd + '/mtb-hal-cat1/COMPONENT_CAT1A/include', cwd + '/TARGET_CY8CKIT-062S2-43012', cwd + '/TARGET_CY8CKIT-062S2-43012/COMPONENT_BSP_DESIGN_MODUS/GeneratedSource'] diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb-hal-cat1/source/cyhal_scb_common.c b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb-hal-cat1/source/cyhal_scb_common.c index 414f363ab8fea7b5f37e27a835d274c2df94012a..b507ba35473b47d57aec354ebb21533845d53a5f 100644 --- a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb-hal-cat1/source/cyhal_scb_common.c +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb-hal-cat1/source/cyhal_scb_common.c @@ -38,7 +38,7 @@ extern "C" { #endif -CySCB_Type* const _CYHAL_SCB_BASE_ADDRESSES[_SCB_ARRAY_SIZE] = +CySCB_Type *const _CYHAL_SCB_BASE_ADDRESSES[_SCB_ARRAY_SIZE] = { #ifdef SCB0 SCB0, @@ -149,73 +149,93 @@ const _cyhal_system_irq_t _CYHAL_SCB_IRQ_N[_SCB_ARRAY_SIZE] = /** The configuration structs for the resource in use on each SCB block */ static void *_cyhal_scb_config_structs[_SCB_ARRAY_SIZE]; /** The callback to use for each scb instance */ -static bool (*_cyhal_scb_config_pm_callback[_SCB_ARRAY_SIZE]) (void *obj_ptr, cyhal_syspm_callback_state_t state, cy_en_syspm_callback_mode_t pdl_mode); +static bool (*_cyhal_scb_config_pm_callback[_SCB_ARRAY_SIZE])(void *obj_ptr, cyhal_syspm_callback_state_t state, cy_en_syspm_callback_mode_t pdl_mode); static uint8_t _cyhal_scb_get_block_from_irqn(_cyhal_system_irq_t irqn) { switch (irqn) { #if (_SCB_ARRAY_SIZE > 0) - case scb_0_interrupt_IRQn: return 0; + case scb_0_interrupt_IRQn: + return 0; #endif #if (_SCB_ARRAY_SIZE > 1) - case scb_1_interrupt_IRQn: return 1; + case scb_1_interrupt_IRQn: + return 1; #endif #if (_SCB_ARRAY_SIZE > 2) - case scb_2_interrupt_IRQn: return 2; + case scb_2_interrupt_IRQn: + return 2; #endif #if (_SCB_ARRAY_SIZE > 3) #if !defined(CY_DEVICE_PSOC6A256K) - case scb_3_interrupt_IRQn: return 3; + case scb_3_interrupt_IRQn: + return 3; #endif #endif #if (_SCB_ARRAY_SIZE > 4) - case scb_4_interrupt_IRQn: return 4; + case scb_4_interrupt_IRQn: + return 4; #endif #if (_SCB_ARRAY_SIZE > 5) - case scb_5_interrupt_IRQn: return 5; + case scb_5_interrupt_IRQn: + return 5; #endif #if (_SCB_ARRAY_SIZE > 6) - case scb_6_interrupt_IRQn: return 6; + case scb_6_interrupt_IRQn: + return 6; #endif #if (_SCB_ARRAY_SIZE > 7) - case scb_7_interrupt_IRQn: return 7; + case scb_7_interrupt_IRQn: + return 7; #endif #if (_SCB_ARRAY_SIZE > 8) - case scb_8_interrupt_IRQn: return 8; + case scb_8_interrupt_IRQn: + return 8; #endif #if (_SCB_ARRAY_SIZE > 9) - case scb_9_interrupt_IRQn: return 9; + case scb_9_interrupt_IRQn: + return 9; #endif #if (_SCB_ARRAY_SIZE > 10) - case scb_10_interrupt_IRQn: return 10; + case scb_10_interrupt_IRQn: + return 10; #endif #if (_SCB_ARRAY_SIZE > 11) - case scb_11_interrupt_IRQn: return 11; + case scb_11_interrupt_IRQn: + return 11; #endif #if (_SCB_ARRAY_SIZE > 12) - case scb_12_interrupt_IRQn: return 12; + case scb_12_interrupt_IRQn: + return 12; #endif #if (_SCB_ARRAY_SIZE > 13) - case scb_13_interrupt_IRQn: return 13; + case scb_13_interrupt_IRQn: + return 13; #endif #if (_SCB_ARRAY_SIZE > 14) - case scb_14_interrupt_IRQn: return 14; + case scb_14_interrupt_IRQn: + return 14; #endif #if (_SCB_ARRAY_SIZE > 15) - case scb_15_interrupt_IRQn: return 15; + case scb_15_interrupt_IRQn: + return 15; #endif #if (_SCB_ARRAY_SIZE > 16) - case scb_16_interrupt_IRQn: return 16; + case scb_16_interrupt_IRQn: + return 16; #endif #if (_SCB_ARRAY_SIZE > 17) - case scb_17_interrupt_IRQn: return 17; + case scb_17_interrupt_IRQn: + return 17; #endif #if (_SCB_ARRAY_SIZE > 18) - case scb_18_interrupt_IRQn: return 18; + case scb_18_interrupt_IRQn: + return 18; #endif #if (_SCB_ARRAY_SIZE > 19) - case scb_19_interrupt_IRQn: return 19; + case scb_19_interrupt_IRQn: + return 19; #endif #if (_SCB_ARRAY_SIZE > 20) #error "Unhandled scb count" @@ -281,7 +301,7 @@ uint32_t _cyhal_i2c_set_peri_divider(void *obj, bool is_i2c, uint32_t freq, bool } if (peri_freq > 0 && _cyhal_utils_peri_pclk_assign_divider( - _cyhal_scb_get_clock_index(block_num), clock) == CY_SYSCLK_SUCCESS) + _cyhal_scb_get_clock_index(block_num), clock) == CY_SYSCLK_SUCCESS) { cy_rslt_t status = CY_RSLT_SUCCESS; @@ -294,18 +314,18 @@ uint32_t _cyhal_i2c_set_peri_divider(void *obj, bool is_i2c, uint32_t freq, bool status = cyhal_clock_set_enabled(clock, true, false); } - if(status == CY_RSLT_SUCCESS) + if (status == CY_RSLT_SUCCESS) { data_rate = (is_slave) - ? Cy_SCB_I2C_GetDataRate(base, cyhal_clock_get_frequency(clock)) - : Cy_SCB_I2C_SetDataRate(base, freq, cyhal_clock_get_frequency(clock)); + ? Cy_SCB_I2C_GetDataRate(base, cyhal_clock_get_frequency(clock)) + : Cy_SCB_I2C_SetDataRate(base, freq, cyhal_clock_get_frequency(clock)); } } } return data_rate; } -const cyhal_resource_pin_mapping_t* _cyhal_scb_find_map(cyhal_gpio_t pin, const cyhal_resource_pin_mapping_t *pin_map, +const cyhal_resource_pin_mapping_t *_cyhal_scb_find_map(cyhal_gpio_t pin, const cyhal_resource_pin_mapping_t *pin_map, size_t count, const cyhal_resource_inst_t *block_res) { for (size_t i = 0; i < count; i++) @@ -356,17 +376,17 @@ uint32_t _cyhal_scb_check_pin_affiliation(cyhal_gpio_t pin, const cyhal_resource cy_rslt_t _cyhal_scb_set_fifo_level(CySCB_Type *base, cyhal_scb_fifo_type_t type, uint16_t level) { - if(!CY_SCB_IS_TRIGGER_LEVEL_VALID(base, level)) + if (!CY_SCB_IS_TRIGGER_LEVEL_VALID(base, level)) return CYHAL_SCB_RSLT_ERR_BAD_ARGUMENT; - if(type == CYHAL_SCB_FIFO_RX) + if (type == CYHAL_SCB_FIFO_RX) { SCB_RX_FIFO_CTRL(base) &= ~SCB_RX_FIFO_CTRL_TRIGGER_LEVEL_Msk; SCB_RX_FIFO_CTRL(base) |= _VAL2FLD(SCB_RX_FIFO_CTRL_TRIGGER_LEVEL, level); return CY_RSLT_SUCCESS; } - else if(type == CYHAL_SCB_FIFO_TX) + else if (type == CYHAL_SCB_FIFO_TX) { SCB_TX_FIFO_CTRL(base) &= ~SCB_TX_FIFO_CTRL_TRIGGER_LEVEL_Msk; SCB_TX_FIFO_CTRL(base) |= _VAL2FLD(SCB_TX_FIFO_CTRL_TRIGGER_LEVEL, level); @@ -384,13 +404,13 @@ cy_rslt_t _cyhal_scb_enable_output(cyhal_resource_inst_t resource, cyhal_scb_out // This just returns a proper cyhal_source_t. Use _cyhal_scb_set_fifo_level // to actually set level. cyhal_internal_source_t src_int; - if(output == CYHAL_SCB_OUTPUT_TRIGGER_RX_FIFO_LEVEL_REACHED) + if (output == CYHAL_SCB_OUTPUT_TRIGGER_RX_FIFO_LEVEL_REACHED) { #if defined(CY_DEVICE_PSOC6A256K) // 256K devices have no SCB3 src_int = (resource.block_num < 3) - ? (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_RX_REQ + resource.block_num) - : (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_RX_REQ + resource.block_num - 1); + ? (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_RX_REQ + resource.block_num) + : (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_RX_REQ + resource.block_num - 1); #else src_int = (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_RX_REQ + resource.block_num); #endif @@ -400,13 +420,13 @@ cy_rslt_t _cyhal_scb_enable_output(cyhal_resource_inst_t resource, cyhal_scb_out } // This just returns a proper cyhal_source_t. Use _cyhal_scb_set_fifo_level // to actually set level. - else if(output == CYHAL_SCB_OUTPUT_TRIGGER_TX_FIFO_LEVEL_REACHED) + else if (output == CYHAL_SCB_OUTPUT_TRIGGER_TX_FIFO_LEVEL_REACHED) { #if defined(CY_DEVICE_PSOC6A256K) // 256K devices have no SCB3 src_int = (resource.block_num < 3) - ? (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_TX_REQ + resource.block_num) - : (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_TX_REQ + resource.block_num - 1); + ? (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_TX_REQ + resource.block_num) + : (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_TX_REQ + resource.block_num - 1); #else src_int = (cyhal_internal_source_t)(_CYHAL_TRIGGER_SCB0_TR_TX_REQ + resource.block_num); #endif @@ -430,7 +450,7 @@ cy_rslt_t _cyhal_scb_disable_output(cyhal_scb_output_t output) #if (defined(CY_IP_MXSCB) || defined(CY_DEVICE_PSOC4AMC) || defined(CY_DEVICE_PSOC4AS3) || defined(CY_DEVICE_PSOC4AS4)) // Noop: Use _cyhal_scb_set_fifo_level to actually set level if (output == CYHAL_SCB_OUTPUT_TRIGGER_RX_FIFO_LEVEL_REACHED || - output == CYHAL_SCB_OUTPUT_TRIGGER_TX_FIFO_LEVEL_REACHED) + output == CYHAL_SCB_OUTPUT_TRIGGER_TX_FIFO_LEVEL_REACHED) { return CY_RSLT_SUCCESS; } @@ -456,7 +476,7 @@ static bool _cyhal_scb_pm_callback_index(uint8_t index, cyhal_syspm_callback_sta return ((NULL != obj) && (callback != NULL)) ? callback(obj, state, pdl_mode) : true; } -static bool _cyhal_scb_pm_callback_common(cyhal_syspm_callback_state_t state, cyhal_syspm_callback_mode_t mode, void* callback_arg) +static bool _cyhal_scb_pm_callback_common(cyhal_syspm_callback_state_t state, cyhal_syspm_callback_mode_t mode, void *callback_arg) { CY_UNUSED_PARAMETER(callback_arg); bool allow = true; @@ -516,15 +536,15 @@ void _cyhal_scb_update_instance_data(uint8_t block_num, void *obj, cyhal_scb_ins if (count == 0) { CY_ASSERT(obj == NULL); - #if (CYHAL_DRIVER_AVAILABLE_SYSPM) +#if (CYHAL_DRIVER_AVAILABLE_SYSPM) _cyhal_syspm_unregister_peripheral_callback(&_cyhal_scb_pm_callback_data); - #endif +#endif } else if (count == 1 && obj != NULL) { - #if (CYHAL_DRIVER_AVAILABLE_SYSPM) +#if (CYHAL_DRIVER_AVAILABLE_SYSPM) _cyhal_syspm_register_peripheral_callback(&_cyhal_scb_pm_callback_data); - #endif +#endif } } diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/LICENSE b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..3247fccce5cd2a065504044433949fca6e9ee5a2 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/LICENSE @@ -0,0 +1,55 @@ +CYPRESS END USER LICENSE AGREEMENT + +PLEASE READ THIS END USER LICENSE AGREEMENT ("Agreement") CAREFULLY BEFORE DOWNLOADING, INSTALLING, COPYING, OR USING THIS SOFTWARE AND ACCOMPANYING DOCUMENTATION. BY DOWNLOADING, INSTALLING, COPYING OR USING THE SOFTWARE, YOU ARE AGREEING TO BE BOUND BY THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL OF THE TERMS OF THIS AGREEMENT, PROMPTLY RETURN AND DO NOT USE THE SOFTWARE. IF YOU HAVE PURCHASED THIS LICENSE TO THE SOFTWARE, YOUR RIGHT TO RETURN THE SOFTWARE EXPIRES 30 DAYS AFTER YOUR PURCHASE AND APPLIES ONLY TO THE ORIGINAL PURCHASER. + +1. Definitions. + + "Software" means this software and any accompanying documentation, including any upgrades, updates, bug fixes or modified versions provided to you by Cypress. + + "Source Code" means software in human-readable form. + + "Binary Code" means the software in binary code form such as object code or an executable. + + "Development Tools" means software that is intended to be installed on a personal computer and used to create programming code for Firmware, Drivers, or Host Applications. Examples of Development Tools are Cypress's PSoC Creator software, Cypress's WICED SDKs, and Cypress's Modus Toolbox software. + + "Firmware" means software that executes on a Cypress hardware product. + + "Driver" means software that enables the use of a Cypress hardware product on a particular host operating system such as GNU/Linux, Windows, MacOS, Android, and iOS. + + "Host Application" means software that executes on a device other than a Cypress hardware product in order to program, control, or communicate with a Cypress hardware product. + + "inf File" means a hardware setup information file (.inf file) created by the Software to allow a Microsoft Windows operating system to install the driver for a Cypress hardware product. + +2. License. Subject to the terms and conditions of this Agreement, Cypress Semiconductor Corporation ("Cypress") and its suppliers grant to you a non-exclusive, non-transferable license under their copyright rights: + + a. to use the Development Tools in object code form solely for the purpose of creating Firmware, Drivers, Host Applications, and inf Files for Cypress hardware products; and + + b. (i) if provided in Source Code form, to copy, modify, and compile the Firmware Source Code to create Firmware for execution on a Cypress hardware product, and (ii) to distribute Firmware in binary code form only, only when installed onto a Cypress hardware product; and + + c. (i) if provided in Source Code form, to copy, modify, and compile the Driver Source Code to create one or more Drivers to enable the use of a Cypress hardware product on a particular host operating system, and (ii) to distribute the Driver, in binary code form only, only when installed on a device that includes the Cypress hardware product that the Driver is intended to enable; and + + d. (i) if provided in Source Code form, to copy, modify, and compile the Host Application Source Code to create one or more Host Applications to program, control, or communicate with a Cypress hardware product, and (ii) to distribute Host Applications, in binary code form only, only when installed on a device that includes a Cypress hardware product that the Host Application is intended to program, control, or communicate with; and + + e. to freely distribute any inf File. + +Any distribution of Software permitted under this Agreement must be made pursuant to your standard end user license agreement used for your proprietary (closed source) software products, such end user license agreement to include, at a minimum, provisions limiting your licensors' liability and prohibiting reverse engineering of the Software, consistent with such provisions in this Agreement. + +3. Free and Open Source Software. Portions of the Software may be licensed under free and/or open source licenses such as the GNU General Public License or other licenses from third parties ("Third Party Software"). Third Party Software is subject to the applicable license agreement and not this Agreement. If you are entitled to receive the source code from Cypress for any Third Party Software included with the Software, either the source code will be included with the Software or you may obtain the source code at no charge from . The applicable license terms will accompany each source code package. To review the license terms applicable to any Third Party Software for which Cypress is not required to provide you with source code, please see the Software's installation directory on your computer. + +4. Proprietary Rights; Ownership. The Software, including all intellectual property rights therein, is and will remain the sole and exclusive property of Cypress or its suppliers. Cypress retains ownership of the Source Code and any compiled version thereof. Subject to Cypress' ownership of the underlying Software (including Source Code), you retain ownership of any modifications you make to the Source Code. You agree not to remove any Cypress copyright or other notices from the Source Code and any modifications thereof. You agree to keep the Source Code confidential. Any reproduction, modification, translation, compilation, or representation of the Source Code except as permitted in Section 2 ("License") is prohibited without the express written permission of Cypress. Except as otherwise expressly provided in this Agreement, you may not: (i) modify, adapt, or create derivative works based upon the Software; (ii) copy the Software; (iii) except and only to the extent explicitly permitted by applicable law despite this limitation, decompile, translate, reverse engineer, disassemble or otherwise reduce the Software to human-readable form; or (iv) use the Software or any sample code other than for the Purpose. You hereby covenant that you will not assert any claim that the Software, or derivative works thereof created by or for Cypress, infringe any intellectual property right owned or controlled by you + +5. No Support. Cypress may, but is not required to, provide technical support for the Software. + +6. Term and Termination. This Agreement is effective until terminated, and either party may terminate this Agreement at any time with or without cause. This Agreement and your license rights under this Agreement will terminate immediately without notice from Cypress if you fail to comply with any provision of this Agreement. Upon termination, you must destroy all copies of Software in your possession or control. The following paragraphs shall survive any termination of this Agreement: "Free and Open Source Software," "Proprietary Rights; Ownership," "Compliance With Law," "Disclaimer," "Limitation of Liability," and "General." + +7. Compliance With Law. Each party agrees to comply with all applicable laws, rules and regulations in connection with its activities under this Agreement. Without limiting the foregoing, the Software may be subject to export control laws and regulations of the United States and other countries. You agree to comply strictly with all such laws and regulations and acknowledge that you have the responsibility to obtain licenses to export, re-export, or import the Software. + +8. Disclaimer. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THE SOFTWARE, INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress reserves the right to make changes to the Software without notice. Cypress does not assume any liability arising out of the application or use of Software or any product or circuit described in the Software. It is the responsibility of the user of the Software to properly design, program, and test the functionality and safety of any application made of the Software and any resulting product. Cypress does not authorize its Software or products for use in any products where a malfunction or failure of the Software or Cypress product may reasonably be expected to result in significant property damage, injury or death (“High Risk Product”). If you include any Software or Cypress product in a High Risk Product, you assume all risk of such use and agree to indemnify Cypress and its suppliers against all liability. No computing device can be absolutely secure. Therefore, despite security measures implemented in Cypress hardware or software products, Cypress does not assume any liability arising out of any security breach, such as unauthorized access to or use of a Cypress product. + +9. Limitation of Liability. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS BE LIABLE FOR ANY LOST REVENUE, PROFIT, OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO EVENT SHALL CYPRESS' OR ITS SUPPLIERS’, RESELLERS’, OR DISTRIBUTORS’ TOTAL LIABILITY TO YOU, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, EXCEED THE GREATER OF US$500 OR THE PRICE PAID BY YOU FOR THE SOFTWARE. THE FOREGOING LIMITATIONS SHALL APPLY EVEN IF THE ABOVE-STATED WARRANTY FAILS OF ITS ESSENTIAL PURPOSE. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, ALL OR PORTIONS OF THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + +10. Restricted Rights. The Software is commercial computer software as that term is described in 48 C.F.R. 252.227-7014(a)(1). If the Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in Software shall be only those set forth in this Agreement. + +11. Personal Information. You agree that information you provide through your registration on Cypress IoT Community Forum or other Cypress websites, including contact information or other personal information, may be collected and used by Cypress consistent with its Data Privacy Policy (www.cypress.com/privacy-policy), as updated or revised from time to time, and may be provided to its third party sales representatives, distributors and other entities conducting sales activities for Cypress for sales-related and other business purposes. + +12. General. This Agreement will bind and inure to the benefit of each party’s successors and assigns, provided that you may not assign or transfer this Agreement, in whole or in part, without Cypress' written consent. This Agreement shall be governed by and construed in accordance with the laws of the State of California, United States of America, as if performed wholly within the state and without giving effect to the principles of conflict of law. The parties consent to personal and exclusive jurisdiction of and venue in, the state and federal courts within Santa Clara County, California; provided however, that nothing in this Agreement will limit Cypress' right to bring legal action in any venue in order to protect or enforce its intellectual property rights. No failure of either party to exercise or enforce any of its rights under this Agreement will act as a waiver of such rights. If any portion of this Agreement is found to be void or unenforceable, the remaining provisions of this Agreement shall remain in full force and effect. This Agreement is the complete and exclusive agreement between the parties with respect to the subject matter hereof, superseding and replacing any and all prior agreements, communications, and understandings (both written and oral) regarding such subject matter. Any notice to Cypress will be deemed effective when actually received and must be sent to Cypress Semiconductor Corporation, ATTN: Chief Legal Officer, 198 Champion Court, San Jose, CA 95134 USA. diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/README.md b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4c31b0a9a31d8b9aef9ef766c4659fc61b22e6f5 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/README.md @@ -0,0 +1,36 @@ +# Cypress CSDIDAC Middleware Library + +### Overview +The CSDIDAC provides an API that allows the CSD HW block IDAC functionality. +It can be useful for devices that do not include other DAC options. + +### Features +* A two-channel IDAC with the 7-bit resolution +* The IDAC A and IDAC B channels can be enabled/disabled independently +* The IDAC A and IDAC B channels can be configured with sourcing/sinking current independently +* The IDAC A and IDAC B channels can be joined to increase a maximum output current +* The IDAC A and IDAC B channels can be enabled/disabled simultaneously by using the CY_CSDIDAC_AB option +* The 0 to 609.6 uA (609600 nA) current range is available for each IDAC channel +* Each IDAC can use independently one of the six available LSB depending on a desired output current + +### Quick Start +The CSDIDAC could be configured by the ModusToolbox CSD personality. Refer to the [API Reference Guide Configuration Considerations](https://cypresssemiconductorco.github.io/csdidac/csdidac_api_reference_manual/html/index.html#group_csdidac_configuration). + + +### More information +The following resources contain more information: +* [CSDIDAC Middleware RELEASE.md](./RELEASE.md) +* [CSDIDAC Middleware API Reference Guide](https://cypresssemiconductorco.github.io/csdidac/csdidac_api_reference_manual/html/index.html) +* [ModusToolbox Software Environment, Quick Start Guide, Documentation, and Videos](https://www.cypress.com/products/modustoolbox-software-environment) +* [CSDIDAC Middleware Code Example for MBED OS](https://github.com/cypresssemiconductorco/mbed-os-example-csdidac) +* [ModusToolbox Device Configurator Tool Guide](https://www.cypress.com/ModusToolboxDeviceConfig) +* [CapSense Middleware API Reference Guide](https://cypresssemiconductorco.github.io/capsense/capsense_api_reference_manual/html/index.html) +* [CSDADC Middleware API Reference Guide](https://cypresssemiconductorco.github.io/csdadc/csdadc_api_reference_manual/html/index.html) +* [PSoC 6 Technical Reference Manual](https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-63-ble-architecture-technical-reference) +* [PSoC 63 with BLE Datasheet Programmable System-on-Chip datasheet](http://www.cypress.com/ds218787) +* [PSoC 4000S Family: PSoC 4 Architecture Technical Reference Manual (TRM)](https://www.cypress.com/documentation/technical-reference-manuals/psoc-4000s-family-psoc-4-architecture-technical-reference) +* [PSoC 4100S and PSoC 4100S Plus: PSoC 4 Architecture Technical Reference Manual (TRM)](https://www.cypress.com/documentation/technical-reference-manuals/psoc-4100s-and-psoc-4100s-plus-psoc-4-architecture) +* [Cypress Semiconductor](http://www.cypress.com) + +--- +© Cypress Semiconductor Corporation, 2019. diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/RELEASE.md b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/RELEASE.md new file mode 100644 index 0000000000000000000000000000000000000000..394a2ccb31be26893d97bbf8c21c21fcda531a84 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/RELEASE.md @@ -0,0 +1,44 @@ +# Cypress CSDIDAC Middleware Library 2.10 + +### What's Included? + +Please refer to the [README.md](./README.md) and the [API Reference Guide](https://cypresssemiconductorco.github.io/csdidac/csdidac_api_reference_manual/html/index.html) for a complete description of the CSDIDAC Middleware. +The revision history of the CSDIDAC Middleware is also available on the [API Reference Guide Changelog](https://cypresssemiconductorco.github.io/csdidac/csdidac_api_reference_manual/html/index.html#group_csdidac_changelog). +New in this release: +* Added the support for the PSoC 4100S Plus devices + + +### Supported Software and Tools +This version of the CSDIDAC Middleware was validated for compatibility with the following Software and Tools: + +| Software and Tools | Version | +| :--- | :----: | +| ModusToolbox Software Environment | 2.1 | +| - ModusToolbox Device Configurator | 2.1 | +| - ModusToolbox CSD Personality for PSoC4 devices in Device Configurator | 1.0 | +| - ModusToolbox CSD Personality for PSoC6 devices in Device Configurator | 2.0 | +| PSoC4 Peripheral Driver Library (PDL) | 1.0.0 | +| PSoC6 Peripheral Driver Library (PDL) | 1.5.0 | +| GCC Compiler | 7.2.1 | +| IAR Compiler | 8.32 | +| ARM Compiler 6 | 6.11 | +| MBED OS | 5.15.1 | +| FreeRTOS | 10.0.1 | + +### More information +The following resources contain more information: +* [CSDIDAC Middleware RELEASE.md](./RELEASE.md) +* [CSDIDAC Middleware API Reference Guide](https://cypresssemiconductorco.github.io/csdidac/csdidac_api_reference_manual/html/index.html) +* [ModusToolbox Software Environment, Quick Start Guide, Documentation, and Videos](https://www.cypress.com/products/modustoolbox-software-environment) +* [CSDIDAC Middleware Code Example for MBED OS](https://github.com/cypresssemiconductorco/mbed-os-example-csdidac) +* [ModusToolbox Device Configurator Tool Guide](https://www.cypress.com/ModusToolboxDeviceConfig) +* [CapSense Middleware API Reference Guide](https://cypresssemiconductorco.github.io/capsense/capsense_api_reference_manual/html/index.html) +* [CSDADC Middleware API Reference Guide](https://cypresssemiconductorco.github.io/csdadc/csdadc_api_reference_manual/html/index.html) +* [PSoC 6 Technical Reference Manual](https://www.cypress.com/documentation/technical-reference-manuals/psoc-6-mcu-psoc-63-ble-architecture-technical-reference) +* [PSoC 63 with BLE Datasheet Programmable System-on-Chip datasheet](http://www.cypress.com/ds218787) +* [PSoC 4000S Family: PSoC 4 Architecture Technical Reference Manual (TRM)](https://www.cypress.com/documentation/technical-reference-manuals/psoc-4000s-family-psoc-4-architecture-technical-reference) +* [PSoC 4100S and PSoC 4100S Plus: PSoC 4 Architecture Technical Reference Manual (TRM)](https://www.cypress.com/documentation/technical-reference-manuals/psoc-4100s-and-psoc-4100s-plus-psoc-4-architecture) +* [Cypress Semiconductor](http://www.cypress.com) + +--- +© Cypress Semiconductor Corporation, 2019-2020. diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/cy_csdidac.c b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/cy_csdidac.c new file mode 100644 index 0000000000000000000000000000000000000000..798350917103e9a4dcf0fb096240d444d24c68b3 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/cy_csdidac.c @@ -0,0 +1,1020 @@ +/***************************************************************************//** +* \file cy_csdidac.c +* \version 2.10 +* +* \brief +* This file provides the CSD HW block IDAC functionality implementation. +* +******************************************************************************** +* \copyright +* Copyright 2019-2020, Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + + +#include "cy_device_headers.h" +#include "cy_syslib.h" +#include "cy_syspm.h" +#include "cy_csdidac.h" +#include "cy_gpio.h" +#include "cy_csd.h" + +#if (defined(CY_IP_MXCSDV2) || defined(CY_IP_M0S8CSDV2)) + + +/******************************************************************************* +* Function Prototypes - Internal Functions +*******************************************************************************/ +/** +* \cond SECTION_CSDIDAC_INTERNAL +* \addtogroup group_csdidac_internal +* \{ +*/ +static void Cy_CSDIDAC_ConnectChannelA(cy_stc_csdidac_context_t * context); +static void Cy_CSDIDAC_ConnectChannelB(cy_stc_csdidac_context_t * context); +static void Cy_CSDIDAC_DisconnectChannelA(cy_stc_csdidac_context_t * context); +static void Cy_CSDIDAC_DisconnectChannelB(cy_stc_csdidac_context_t * context); +/** \} +* \endcond */ + + +/******************************************************************************* +* Local Definition +*******************************************************************************/ +#define CY_CSDIDAC_FSM_ABORT (0x08u) + +/* IDAC configuration register */ +/* +--------+---------------+-------------------------------------------------------------------+ + * | BITS | FIELD | DEFAULT MODE | + * |--------|---------------|-------------------------------------------------------------------| + * | 6:0 | VAL | 0x00(Sets the IDAC value to "0") | + * | 7 | POL_STATIC | 0x00(Sets the static IDAC polarity) | + * | 9:8 | POLARITY | 0x00(IDAC polarity SOURCE) | + * | 11:10 | BAL_MODE | 0x00(IDAC is enabled in PHI2 and disabled at the end of balancing)| + * | 17:16 | LEG1_MODE | 0x00(Configures LEG1 to GP_static mode) | + * | 19:18 | LEG2_MODE | 0x00(Configures LEG1 to GP_static mode) | + * | 21 | DSI_CTRL_EN | 0x00(The IDAC DSI control is disabled) | + * | 23:22 | RANGE | 0x00(Sets the range parameter value to low: 1LSB = 37.5 nA) | + * | 24 | LEG1_EN | 0x00(The output for LEG1 is disabled) | + * | 25 | LEG2_EN | 0x00(The output for LEG2 is disabled) | + * +--------+---------------+-------------------------------------------------------------------+*/ +#define CY_CSDIDAC_DEFAULT_CFG (0x01800000uL) +#define CY_CSDIDAC_POLARITY_POS (8uL) +#define CY_CSDIDAC_POLARITY_MASK (3uL << CY_CSDIDAC_POLARITY_POS) +#define CY_CSDIDAC_LSB_POS (22uL) +#define CY_CSDIDAC_LSB_MASK (3uL << CY_CSDIDAC_LSB_POS) +#define CY_CSDIDAC_LEG1_EN_POS (24uL) +#define CY_CSDIDAC_LEG1_EN_MASK (1uL << CY_CSDIDAC_LEG1_EN_POS) +#define CY_CSDIDAC_LEG2_EN_POS (25uL) +#define CY_CSDIDAC_LEG2_EN_MASK (1uL << CY_CSDIDAC_LEG2_EN_POS) +#define CY_CSDIDAC_RANGE_MASK (CY_CSDIDAC_LSB_MASK | CY_CSDIDAC_LEG1_EN_MASK | CY_CSDIDAC_LEG2_EN_MASK) + +/* +* All the defines below correspond to IDAC LSB in pA +*/ +#define CY_CSDIDAC_LSB_37 ( 37500u) +#define CY_CSDIDAC_LSB_75 ( 75000u) +#define CY_CSDIDAC_LSB_300 ( 300000u) +#define CY_CSDIDAC_LSB_600 ( 600000u) +#define CY_CSDIDAC_LSB_2400 (2400000u) +#define CY_CSDIDAC_LSB_4800 (4800000u) + +#define CY_CSDIDAC_LSB_37_MAX_CURRENT ( 4762500u) +#define CY_CSDIDAC_LSB_75_MAX_CURRENT ( 9525000u) +#define CY_CSDIDAC_LSB_300_MAX_CURRENT ( 38100000u) +#define CY_CSDIDAC_LSB_600_MAX_CURRENT ( 76200000u) +#define CY_CSDIDAC_LSB_2400_MAX_CURRENT (304800000u) +#define CY_CSDIDAC_LSB_4800_MAX_CURRENT (609600000u) + +#define CY_CSDIDAC_CODE_MASK (127u) +#define CY_CSDIDAC_CONST_2 (2u) +#define CY_CSDIDAC_CONST_10 (10u) +#define CY_CSDIDAC_CONST_1000 (1000u) +#define CY_CSDIDAC_CONST_1000000 (1000000u) + +/* CSD HW block CONFIG register definitions */ +#define CY_CSDIDAC_CSD_REG_CONFIG_INIT (0x80001000uL) +#define CY_CSDIDAC_CSD_REG_CONFIG_DEFAULT (CY_CSDIDAC_CSD_REG_CONFIG_INIT) + +/* CSD_INTR register masks */ +#define CY_CSDIDAC_CSD_INTR_SAMPLE_MSK (0x00000001uL) +#define CY_CSDIDAC_CSD_INTR_INIT_MSK (0x00000002uL) +#define CY_CSDIDAC_CSD_INTR_ADC_RES_MSK (0x00000100uL) +#define CY_CSDIDAC_CSD_INTR_ALL_MSK (CY_CSDIDAC_CSD_INTR_SAMPLE_MSK | \ + CY_CSDIDAC_CSD_INTR_INIT_MSK | \ + CY_CSDIDAC_CSD_INTR_ADC_RES_MSK) +/* CSD_INTR_MASK register masks */ +#define CY_CSDIDAC_CSD_INTR_MASK_SAMPLE_MSK (0x00000001uL) +#define CY_CSDIDAC_CSD_INTR_MASK_INIT_MSK (0x00000002uL) +#define CY_CSDIDAC_CSD_INTR_MASK_ADC_RES_MSK (0x00000100uL) +#define CY_CSDIDAC_CSD_INTR_MASK_CLEAR_MSK (0x00000000uL) + +/* Switch definitions */ +#define CY_CSDIDAC_SW_BYPA_ENABLE (0x00001000uL) +#define CY_CSDIDAC_SW_BYPB_ENABLE (0x00010000uL) +#define CY_CSDIDAC_SW_REFGEN_SEL_IBCB_ON (0x00000010uL) +#define CY_CSDIDAC_SW_REFGEN_SEL_IAIB_ON (0x00000001uL) + +#define CY_CSDIDAC_CSD_CONFIG_DEFAULT {\ + .config = 0x80001000uL,\ + .spare = 0x00000000uL,\ + .status = 0x00000000uL,\ + .statSeq = 0x00000000uL,\ + .statCnts = 0x00000000uL,\ + .statHcnt = 0x00000000uL,\ + .resultVal1 = 0x00000000uL,\ + .resultVal2 = 0x00000000uL,\ + .adcRes = 0x00000000uL,\ + .intr = 0x00000000uL,\ + .intrSet = 0x00000000uL,\ + .intrMask = 0x00000000uL,\ + .intrMasked = 0x00000000uL,\ + .hscmp = 0x00000000uL,\ + .ambuf = 0x00000000uL,\ + .refgen = 0x00000000uL,\ + .csdCmp = 0x00000000uL,\ + .swRes = 0x00000000uL,\ + .sensePeriod = 0x00000000uL,\ + .senseDuty = 0x00000000uL,\ + .swHsPosSel = 0x00000000uL,\ + .swHsNegSel = 0x00000000uL,\ + .swShieldSel = 0x00000000uL,\ + .swAmuxbufSel = 0x00000000uL,\ + .swBypSel = 0x00000000uL,\ + .swCmpPosSel = 0x00000000uL,\ + .swCmpNegSel = 0x00000000uL,\ + .swRefgenSel = CY_CSDIDAC_SW_REFGEN_SEL_IBCB_ON,\ + .swFwModSel = 0x00000000uL,\ + .swFwTankSel = 0x00000000uL,\ + .swDsiSel = 0x00000000uL,\ + .ioSel = 0x00000000uL,\ + .seqTime = 0x00000000uL,\ + .seqInitCnt = 0x00000000uL,\ + .seqNormCnt = 0x00000000uL,\ + .adcCtl = 0x00000000uL,\ + .seqStart = 0x00000000uL,\ + .idacA = 0x00000000uL,\ + .idacB = 0x00000000uL,\ + } + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_Init +****************************************************************************//** +* +* Captures the CSD HW block and configures it to the default state. +* This function is called by the application program prior to calling +* any other middleware function. +* +* Initializes the CSDIDAC middleware. Acquires, locks, and initializes +* the CSD HW block by using the low-level CSD driver. +* The function performs the following tasks: +* * Verifies the input parameters. The CY_CSDIDAC_BAD_PARAM is returned if +* verification fails. +* * Acquires and locks the CSD HW block for use of the CSDIDAC, if the CSD HW +* block is in a free state. +* * If the CSD HW block is acquired, it is initialized with +* the CSDIDAC middleware by the default configuration. +* The output pins are not connected to the CSD HW block. +* The outputs are disabled and CY_CSDIDAC_SUCCESS is returned. +* +* To connect an output pin and enable an output current, the +* Cy_CSDIDAC_OutputEnable() or Cy_CSDIDAC_OutputEnableExt() functions +* are used. +* If there is no CSD HW block, the CY_CSDIDAC_HW_BUSY status is returned, +* and the CSDIDAC middleware waits for the CSD HW block to be in the idle +* state to initialize. +* +* \param config +* The pointer to the configuration structure \ref cy_stc_csdidac_config_t that +* contains the CSDIDAC middleware initial configuration data generated +* by the CSD personality of the ModusToolbox Device Configurator tool. +* +* \param context +* The pointer to the CSDIDAC context structure \ref cy_stc_csdidac_context_t +* passed by the user. After the initialization, this structure contains +* both CSDIDAC configuration and internal data. It is used during the whole +* CSDIDAC operation. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL or an invalid +* parameter is passed. +* * CY_CSDIDAC_HW_LOCKED - The CSD HW block is already in use by other +* middleware. +* * CY_CSDIDAC_HW_FAILURE - The CSD HW block failure. +* * CY_CSDIDAC_BAD_CONFIGURATION - The CSDIDAC configuration structure +* initialization issue. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_Init( + const cy_stc_csdidac_config_t * config, + cy_stc_csdidac_context_t * context) +{ + cy_en_csdidac_status_t result = CY_CSDIDAC_BAD_PARAM; + + if ((NULL != config) && (NULL != context)) + { + if(true == Cy_CSDIDAC_IsIdacConfigValid(config)) + { + /* Copies the configuration structure to the context. */ + context->cfgCopy = *config; + /* Captures the CSD HW block for the IDAC functionality. */ + result = Cy_CSDIDAC_Restore(context); + if (CY_CSDIDAC_SUCCESS == result) + { + /* Disconnects all CSDIDAC channels. */ + Cy_CSDIDAC_DisconnectChannelA(context); + Cy_CSDIDAC_DisconnectChannelB(context); + /* Wakes up the CSD HW block. */ + (void)Cy_CSDIDAC_Wakeup(context); + } + } + else + { + result = CY_CSDIDAC_BAD_CONFIGURATION; + } + } + + return (result); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_DeInit +****************************************************************************//** +* +* Stops the middleware operation and releases the CSD HW block. +* +* If any output channel is enabled, it will be disabled and disconnected. +* +* After the CSDIDAC middleware is stopped, the CSD HW block may be +* reconfigured by the application program or other middleware for any +* other usage. +* +* When the middleware operation is stopped by the Cy_CSDIDAC_DeInit() +* function, a subsequent call of the Cy_CSDIDAC_Init() function repeats the +* initialization process. However, to implement Time-multiplexed mode +* (sharing the CSD HW Block between multiple middleware), +* the Cy_CSDIDAC_Save() and Cy_CSDIDAC_Restore() functions are used +* instead of the Cy_CSDIDAC_DeInit() and Cy_CSDIDAC_Init() functions. +* +* \param context +* The pointer to the CSDIDAC context structure \ref cy_stc_csdidac_context_t. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL or an invalid +* parameter is passed. +* * CY_CSDIDAC_HW_LOCKED - The CSD HW block is already in use by other +* middleware. +* * CY_CSDIDAC_HW_FAILURE - A CSD HW block failure. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_DeInit(cy_stc_csdidac_context_t * context) +{ + return (Cy_CSDIDAC_Save(context)); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_WriteConfig +****************************************************************************//** +* +* Updates the CSDIDAC middleware with the desired configuration. +* +* This function sets the desired CSDIDAC middleware configuration. +* The function performs the following: +* * Verifies the input parameters +* * Verifies whether the CSD HW block is captured by the CSDIDAC middleware +* and that there are no active IDAC outputs. +* * Initializes the CSD HW block registers with data passed through the +* config parameter of this function if the above verifications are +* successful. +* * Returns the status code regarding the function execution result. +* +* \param config +* The pointer to the CSDIDAC configuration structure to be updated. +* +* \param context +* The pointer to the CSDIDAC context structure \ref cy_stc_csdidac_context_t. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL or an invalid +* parameter is passed. +* * CY_CSDIDAC_HW_BUSY - Any IDAC output is enabled. The operation +* cannot be completed. +* * CY_CSDIDAC_HW_LOCKED - The CSD HW block is already in use by other +* middleware. +* * CY_CSDIDAC_BAD_CONFIGURATION - The CSDIDAC configuration structure +* initialization issue. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_WriteConfig( + const cy_stc_csdidac_config_t * config, + cy_stc_csdidac_context_t * context) +{ + cy_en_csdidac_status_t result = CY_CSDIDAC_BAD_PARAM; + uint32_t tmpRegValue = CY_CSDIDAC_SW_REFGEN_SEL_IBCB_ON; + + if ((NULL != config) && (NULL != context)) + { + if(true == Cy_CSDIDAC_IsIdacConfigValid(config)) + { + if (CY_CSD_IDAC_KEY == Cy_CSD_GetLockStatus(context->cfgCopy.base, context->cfgCopy.csdCxtPtr)) + { + if ((CY_CSDIDAC_DISABLE == context->channelStateA) && (CY_CSDIDAC_DISABLE == context->channelStateB)) + { + /* Copies the configuration structure to the context. */ + context->cfgCopy = *config; + + /* Disconnects the IDACs from AMUX buses. */ + Cy_CSD_WriteReg(context->cfgCopy.base, CY_CSD_REG_OFFSET_SW_BYP_SEL, 0u); + + /* Closes the IAIB switch if IDACs joined. */ + if ((CY_CSDIDAC_JOIN == context->cfgCopy.configA) || (CY_CSDIDAC_JOIN == context->cfgCopy.configB)) + { + tmpRegValue |= CY_CSDIDAC_SW_REFGEN_SEL_IAIB_ON; + } + Cy_CSD_WriteReg(context->cfgCopy.base, CY_CSD_REG_OFFSET_SW_REFGEN_SEL, tmpRegValue); + result = CY_CSDIDAC_SUCCESS; + } + else + { + result = CY_CSDIDAC_HW_BUSY; + } + } + else + { + result = CY_CSDIDAC_HW_LOCKED; + } + } + else + { + result = CY_CSDIDAC_BAD_CONFIGURATION; + } + } + + return (result); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_Wakeup +****************************************************************************//** +* +* Provides a delay required for the CSD HW block to settle after a wakeup +* from CPU / System Deep Sleep. +* +* This function provides a delay after exiting CPU / System Deep Sleep. +* After the CSD HW block has been powered off, an extra delay is required +* to establish the CSD HW block correct operation. +* +* \param context +* The pointer to the CSDIDAC context structure \ref cy_stc_csdidac_context_t. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_Wakeup(const cy_stc_csdidac_context_t * context) +{ + cy_en_csdidac_status_t result = CY_CSDIDAC_BAD_PARAM; + + if (NULL != context) + { + Cy_SysLib_DelayUs((uint16_t)context->cfgCopy.csdInitTime); + result = CY_CSDIDAC_SUCCESS; + } + + return (result); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_DeepSleepCallback +****************************************************************************//** +* +* The callback function to prepare the CSDIDAC before entering CPU / System Deep Sleep. +* +* This function handles CPU active to CPU / System Deep Sleep power mode transition +* for the CSDIDAC middleware. +* Calling this function directly from the application program is not +* recommended. Instead, Cy_SysPm_CpuEnterDeepSleep() is used for CPU active to +* CPU / System Deep Sleep power mode transition of the device. +* \note +* After the CPU Deep Sleep transition, the device automatically goes +* to System Deep Sleep if all conditions are fulfilled: another core is +* in CPU Deep Sleep, all the peripherals are ready to System Deep Sleep, etc. +* (see details in the device TRM). +* +* For the CSDIDAC middleware correct operation during CPU active to +* CPU / System Deep Sleep mode transition, a callback to this API is registered +* using the Cy_SysPm_RegisterCallback() function with CY_SYSPM_DEEPSLEEP +* type. After the callback is registered, this function is called by the +* Cy_SysPm_CpuEnterDeepSleep() function to prepare the middleware for the device +* power mode transition. +* +* When this function is called with CY_SYSPM_CHECK_READY as an input, this +* function returns CY_SYSPM_SUCCESS if no output is enabled. Otherwise, +* CY_SYSPM_FAIL is returned. If CY_SYSPM_FAIL status is returned, a device +* cannot change power mode. To provide such a transition, the application +* program disables all the enabled IDAC outputs. +* +* \param callbackParams +* Refer to the description of the cy_stc_syspm_callback_params_t type in the +* Peripheral Driver Library documentation. +* +* \param mode +* Refer to the description of the cy_en_syspm_callback_mode_t type in the +* Peripheral Driver Library documentation. +* +* \return +* Returns the status of the operation requested by the mode parameter: +* * CY_SYSPM_SUCCESS - CPU / System Deep Sleep power mode can be entered. +* * CY_SYSPM_FAIL - CPU / System Deep Sleep power mode cannot be entered. +* +*******************************************************************************/ +cy_en_syspm_status_t Cy_CSDIDAC_DeepSleepCallback( + cy_stc_syspm_callback_params_t * callbackParams, + cy_en_syspm_callback_mode_t mode) +{ + cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS; + cy_stc_csdidac_context_t * csdIdacCxt = (cy_stc_csdidac_context_t *) callbackParams->context; + + if (CY_SYSPM_CHECK_READY == mode) + { /* Actions before entering CPU / System Deep Sleep */ + if ((CY_CSD_IDAC_KEY == Cy_CSD_GetLockStatus(csdIdacCxt->cfgCopy.base, csdIdacCxt->cfgCopy.csdCxtPtr)) && + ((CY_CSDIDAC_ENABLE == csdIdacCxt->channelStateA) || (CY_CSDIDAC_ENABLE == csdIdacCxt->channelStateB))) + { + retVal = CY_SYSPM_FAIL; + } + } + + return (retVal); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_Save +****************************************************************************//** +* +* Saves the state of the CSDIDAC middleware so the functionality can be +* restored later. +* +* This function, along with Cy_CSDIDAC_Restore(), is specifically designed +* to support time multiplexing of the CSD HW block between multiple +* middleware. When the CSD HW block is shared by more than one middleware, +* this function can be used to save the current state of the CSDIDAC middleware +* and the CSD HW block prior to releasing the CSD HW block for use by other +* middleware. +* +* This function performs the following operations: +* * Saves the current configuration of the CSD HW block and CSDIDAC middleware. +* * Configures the output pins to the default state and disconnects them from +* the CSD HW block. Releases the CSD HW block. +* +* \param context +* The pointer to the CSDIDAC context structure \ref cy_stc_csdidac_context_t. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL or an invalid parameter +* is passed. The operation is not completed. +* * CY_CSDIDAC_HW_LOCKED - The CSD HW block is already in use by other middleware. +* The CSDIDAC middleware cannot save the state +* without the initialization or restore operation. +* * CY_CSDIDAC_HW_FAILURE - A CSD HW block failure. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_Save(cy_stc_csdidac_context_t * context) +{ + cy_en_csdidac_status_t result = CY_CSDIDAC_BAD_PARAM; + cy_en_csd_status_t initStatus = CY_CSD_LOCKED; + + if (NULL != context) + { + if (CY_CSD_IDAC_KEY == Cy_CSD_GetLockStatus(context->cfgCopy.base, context->cfgCopy.csdCxtPtr)) + { + /* Disconnects the output channels pins from analog buses. */ + Cy_CSDIDAC_DisconnectChannelA(context); + Cy_CSDIDAC_DisconnectChannelB(context); + + /* Releases the HW CSD block. */ + initStatus = Cy_CSD_DeInit(context->cfgCopy.base, CY_CSD_IDAC_KEY, context->cfgCopy.csdCxtPtr); + + if (CY_CSD_SUCCESS == initStatus) + { + result = CY_CSDIDAC_SUCCESS; + } + else + { + result = CY_CSDIDAC_HW_FAILURE; + } + } + else + { + result = CY_CSDIDAC_HW_LOCKED; + } + } + + return (result); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_Restore +****************************************************************************//** +* +* Resumes the middleware operation if the Cy_CSDIDAC_Save() function was +* called previously. +* +* This function, along with the Cy_CSDIDAC_Save() function, is specifically +* designed to support the CSD HW block time-multiplexing +* among multiple middleware. When the CSD HW block is shared by more than one +* middleware, this function can be used to restore the CSD HW block previous +* state and the CSDIDAC middleware saved using the Cy_CSDIDAC_Save() function. +* +* This function performs the Cy_CSDIDAC_Init() function, part tasks +* namely captures the CSD HW block. Use the Cy_CSDIDAC_Save() and +* Cy_CSDIDAC_Restore() functions to implement Time-multiplexed mode +* instead of using the Cy_CSDIDAC_DeInit() and Cy_CSDIDAC_Init() functions. +* +* \param context +* The pointer to the CSDIDAC middleware context +* structure \ref cy_stc_csdidac_context_t. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL or an invalid +* parameter is passed. +* * CY_CSDIDAC_HW_LOCKED - The CSD HW block is already in use by +* another middleware. +* * CY_CSDIDAC_HW_FAILURE - The CSD HW block failure. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_Restore(cy_stc_csdidac_context_t * context) +{ + uint32_t watchdogCounter; + + cy_en_csdidac_status_t result = CY_CSDIDAC_HW_FAILURE; + cy_en_csd_key_t mvKey; + cy_en_csd_status_t initStatus = CY_CSD_LOCKED; + CSD_Type * ptrCsdBaseAdd = context->cfgCopy.base; + cy_stc_csd_context_t * ptrCsdCxt = context->cfgCopy.csdCxtPtr; + cy_stc_csd_config_t csdCfg = CY_CSDIDAC_CSD_CONFIG_DEFAULT; + + /* The number of cycles of one for() loop. */ + const uint32_t cyclesPerLoop = 5u; + /* The timeout in microseconds */ + const uint32_t watchdogTimeoutUs = 10000u; + + if (NULL != context) + { + /* Closes the IAIB switch if IDACs joined */ + if ((CY_CSDIDAC_JOIN == context->cfgCopy.configA) || (CY_CSDIDAC_JOIN == context->cfgCopy.configB)) + { + csdCfg.swRefgenSel |= CY_CSDIDAC_SW_REFGEN_SEL_IAIB_ON; + } + + /* Gets the CSD HW block status. */ + mvKey = Cy_CSD_GetLockStatus(ptrCsdBaseAdd, ptrCsdCxt); + if(CY_CSD_NONE_KEY == mvKey) + { + Cy_CSD_WriteReg(ptrCsdBaseAdd, CY_CSD_REG_OFFSET_INTR_MASK, CY_CSDIDAC_CSD_INTR_MASK_CLEAR_MSK); + Cy_CSD_WriteReg(ptrCsdBaseAdd, CY_CSD_REG_OFFSET_SEQ_START, CY_CSDIDAC_FSM_ABORT); + + /* Initializes the Watchdog Counter to prevent a hang. */ + watchdogCounter = (watchdogTimeoutUs * (context->cfgCopy.cpuClk / CY_CSDIDAC_CONST_1000000)) / cyclesPerLoop; + do + { + initStatus = Cy_CSD_GetConversionStatus(ptrCsdBaseAdd, ptrCsdCxt); + watchdogCounter--; + } + while((CY_CSD_BUSY == initStatus) && (0u != watchdogCounter)); + + if (CY_CSD_SUCCESS == initStatus) + { + /* Captures the CSD HW block for the IDAC functionality. */ + initStatus = Cy_CSD_Init(ptrCsdBaseAdd, &csdCfg, CY_CSD_IDAC_KEY, ptrCsdCxt); + + if(CY_CSD_SUCCESS == initStatus) + { + result = CY_CSDIDAC_SUCCESS; + } + } + } + else + { + result = CY_CSDIDAC_HW_LOCKED; + } + } + else + { + result = CY_CSDIDAC_BAD_PARAM; + } + return (result); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_OutputEnable +****************************************************************************//** +* +* Enables an IDAC output with a specified current. +* +* This function performs the following: +* * Verifies the input parameters. +* * Identifies LSB and IDAC code required to generate the specified +* output current and configures the CSD HW block accordingly. +* * Configures and enables the CSDIDAC specified output and returns +* the status code. +* +* \param ch +* The CSDIDAC supports two outputs (A and B), this parameter +* specifies the output to be enabled. +* +* \param current +* A current value for an IDAC output in nA with a sign. If the parameter is +* positive, a sourcing current is generated. If the parameter is +* negative, the sinking current is generated. The middleware +* identifies LSB and code values required to achieve the specified output +* current. The middleware chooses the minimum possible LSB to generate the +* current to minimize a quantization error. NOTE! the quantization +* error in the output current based on the LSB size (37.5/ +* 75/300/600/2400/4800 nA). For instance, if this function +* is called to set 123456 nA, the actual output current is rounded +* to the nearest value of multiple to 2400 nA, i.e 122400 nA. The absolute +* value of this parameter is in the range from 0x00u +* to \ref CY_CSDIDAC_MAX_CURRENT_NA. +* +* \param context +* The pointer to the CSDIDAC middleware context +* structure \ref cy_stc_csdidac_context_t. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL or an invalid parameter +* is passed. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_OutputEnable( + cy_en_csdidac_choice_t ch, + int32_t current, + cy_stc_csdidac_context_t * context) +{ + cy_en_csdidac_status_t retVal = CY_CSDIDAC_BAD_PARAM; + cy_en_csdidac_polarity_t polarity= CY_CSDIDAC_SOURCE; + cy_en_csdidac_lsb_t lsbIndex; + uint32_t absCurrent = (0 > current) ? (uint32_t)(-current) : (uint32_t)current; + uint32_t code; + + if((NULL != context) && (CY_CSDIDAC_MAX_CURRENT_NA >= absCurrent)) + { + if(true == Cy_CSDIDAC_IsIdacChoiceValid(ch, context->cfgCopy.configA, context->cfgCopy.configB)) + { + /* Chooses the desired current polarity */ + if (0 > current) + { + polarity = CY_CSDIDAC_SINK; + } + /* Converts absCurrent to pA */ + absCurrent *= CY_CSDIDAC_CONST_1000; + /* Chooses IDAC LSB and calculates the IDAC code */ + if (absCurrent < CY_CSDIDAC_LSB_37_MAX_CURRENT) + { + lsbIndex = CY_CSDIDAC_LSB_37_IDX; + code = absCurrent / CY_CSDIDAC_LSB_37; + } + else if (absCurrent < CY_CSDIDAC_LSB_75_MAX_CURRENT) + { + lsbIndex = CY_CSDIDAC_LSB_75_IDX; + code = absCurrent / CY_CSDIDAC_LSB_75; + } + else if (absCurrent < CY_CSDIDAC_LSB_300_MAX_CURRENT) + { + lsbIndex = CY_CSDIDAC_LSB_300_IDX; + code = absCurrent / CY_CSDIDAC_LSB_300; + } + else if (absCurrent < CY_CSDIDAC_LSB_600_MAX_CURRENT) + { + lsbIndex = CY_CSDIDAC_LSB_600_IDX; + code = absCurrent / CY_CSDIDAC_LSB_600; + } + else if(absCurrent < CY_CSDIDAC_LSB_2400_MAX_CURRENT) + { + lsbIndex = CY_CSDIDAC_LSB_2400_IDX; + code = absCurrent / CY_CSDIDAC_LSB_2400; + } + else + { + lsbIndex = CY_CSDIDAC_LSB_4800_IDX; + code = absCurrent / CY_CSDIDAC_LSB_4800; + } + if (code > CY_CSDIDAC_MAX_CODE) + { + code = CY_CSDIDAC_MAX_CODE; + } + + /* Sets the desired IDAC(s) polarity, LSB and code in the CSD block and connects output(s). */ + retVal = Cy_CSDIDAC_OutputEnableExt(ch, polarity, lsbIndex, code, context); + } + } + + return (retVal); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_OutputEnableExt +****************************************************************************//** +* +* Enables an IDAC output with the specified polarity, LSB, and IDAC code. +* +* This function performs the following: +* * Verifies the input parameters. +* * Configures and enables the specified output of CSDIDAC and returns the +* status code. +* +* \param outputCh +* CSDIDAC supports two outputs, this parameter specifies the output to +* be enabled. +* +* \param polarity +* The polarity to be set for the specified IDAC. +* +* \param lsbIndex +* The LSB to be set for the specified IDAC. +* +* \param idacCode +* The code value for the specified IDAC in the range from 0 u +* to \ref CY_CSDIDAC_MAX_CODE. +* +* \param context +* The pointer to the CSDIDAC middleware context +* structure \ref cy_stc_csdidac_context_t. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL or an invalid parameter +* is passed. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_OutputEnableExt( + cy_en_csdidac_choice_t outputCh, + cy_en_csdidac_polarity_t polarity, + cy_en_csdidac_lsb_t lsbIndex, + uint32_t idacCode, + cy_stc_csdidac_context_t * context) +{ + CSD_Type * ptrCsdBaseAdd = context->cfgCopy.base; + uint32_t idacRegValue; + uint32_t interruptState; + cy_en_csdidac_status_t retVal = CY_CSDIDAC_BAD_PARAM; + + if((NULL != context) && (CY_CSDIDAC_MAX_CODE >= idacCode)) + { + if((true == Cy_CSDIDAC_IsIdacChoiceValid(outputCh, context->cfgCopy.configA, context->cfgCopy.configB)) && + (true == Cy_CSDIDAC_IsIdacPolarityValid(polarity)) && + (true == Cy_CSDIDAC_IsIdacLsbValid(lsbIndex))) + { + idacRegValue = idacCode | (((uint32_t)polarity) << CY_CSDIDAC_POLARITY_POS); + /* Sets IDAC LSB. The LSB value equals lsbIndex divided by 2 */ + idacRegValue |= ((((uint32_t)lsbIndex) >> 1uL) << CY_CSDIDAC_LSB_POS); + /* Sets the IDAC leg1 enabling bit */ + idacRegValue |= ((uint32_t)CY_CSDIDAC_LEG1_EN_MASK); + /* Sets the IDAC leg2 enabling bit if the lsbIndex is even. */ + if (0u != (lsbIndex % CY_CSDIDAC_CONST_2)) + { + idacRegValue |= ((uint32_t)CY_CSDIDAC_LEG2_EN_MASK); + } + + interruptState = Cy_SysLib_EnterCriticalSection(); + if (((CY_CSDIDAC_A == outputCh) || (CY_CSDIDAC_AB == outputCh)) && + (CY_CSDIDAC_DISABLED != context->cfgCopy.configA)) + { + /* Sets the IDAC A polarity, LSB and code in the context structure. */ + context->polarityA = polarity; + context->lsbA = lsbIndex; + context->codeA = (uint8_t)idacCode; + context->channelStateA = CY_CSDIDAC_ENABLE; + /* Connects the IDAC A output. */ + Cy_CSDIDAC_ConnectChannelA(context); + /* A connected IDAC B output must be available if the IDAC A output is joined to it. */ + if (CY_CSDIDAC_JOIN == context->cfgCopy.configA) + { + Cy_CSDIDAC_ConnectChannelB(context); + } + Cy_CSD_WriteReg(ptrCsdBaseAdd, CY_CSD_REG_OFFSET_IDACA, idacRegValue); + + retVal = CY_CSDIDAC_SUCCESS; + } + + if (((CY_CSDIDAC_B == outputCh) || (CY_CSDIDAC_AB == outputCh)) && + (CY_CSDIDAC_DISABLED != context->cfgCopy.configB)) + { + /* Sets the IDAC B polarity, LSB and code in the context structure. */ + context->polarityB = polarity; + context->lsbB = lsbIndex; + context->codeB = (uint8_t)idacCode; + context->channelStateB = CY_CSDIDAC_ENABLE; + /* Connects the IDAC B output. */ + Cy_CSDIDAC_ConnectChannelB(context); + /* A connected IDAC A output must be available if the IDAC B output is joined to it */ + if (CY_CSDIDAC_JOIN == context->cfgCopy.configB) + { + Cy_CSDIDAC_ConnectChannelA(context); + } + Cy_CSD_WriteReg(ptrCsdBaseAdd, CY_CSD_REG_OFFSET_IDACB, idacRegValue); + + retVal = CY_CSDIDAC_SUCCESS; + } + Cy_SysLib_ExitCriticalSection(interruptState); + } + } + + return (retVal); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_ConnectChannelA +****************************************************************************//** +* +* Connects an IDAC A output as specified by the configuration. +* +* \param context +* The pointer to the CSDIDAC middleware context +* structure \ref cy_stc_csdidac_context_t. +* +*******************************************************************************/ +static void Cy_CSDIDAC_ConnectChannelA( + cy_stc_csdidac_context_t * context) +{ + /* Closes the bypass A switch to feed output current to AMuxBusA. */ + if ((CY_CSDIDAC_GPIO == context->cfgCopy.configA) || (CY_CSDIDAC_AMUX == context->cfgCopy.configA)) + { + Cy_CSD_SetBits(context->cfgCopy.base, CY_CSD_REG_OFFSET_SW_BYP_SEL, CY_CSDIDAC_SW_BYPA_ENABLE); + } + /* Configures port pin, if it is enabled. */ + if ((CY_CSDIDAC_GPIO == context->cfgCopy.configA) && (NULL != context->cfgCopy.ptrPinA)) + { + /* Update port configuration register (drive mode) to High-Z Analog */ + Cy_GPIO_SetDrivemode(context->cfgCopy.ptrPinA->ioPcPtr, (uint32_t)context->cfgCopy.ptrPinA->pin, CY_GPIO_DM_ANALOG); + /* Connect the selected port to AMuxBusA */ + Cy_GPIO_SetHSIOM(context->cfgCopy.ptrPinA->ioPcPtr, (uint32_t)context->cfgCopy.ptrPinA->pin, HSIOM_SEL_AMUXA); + } +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_ConnectChannelB +****************************************************************************//** +* +* Connects an IDAC B output as specified by the configuration. +* +* \param context +* The pointer to the CSDIDAC middleware context +* structure \ref cy_stc_csdidac_context_t. +* +*******************************************************************************/ +static void Cy_CSDIDAC_ConnectChannelB( + cy_stc_csdidac_context_t * context) +{ + /* Closes the bypass B switch to feed an output current to AMuxBusB. */ + if ((CY_CSDIDAC_GPIO == context->cfgCopy.configB) || (CY_CSDIDAC_AMUX == context->cfgCopy.configB)) + { + Cy_CSD_SetBits(context->cfgCopy.base, CY_CSD_REG_OFFSET_SW_BYP_SEL, CY_CSDIDAC_SW_BYPB_ENABLE); + } + /* Configures port pin, if it is enabled. */ + if (CY_CSDIDAC_GPIO == context->cfgCopy.configB) + { + /* Update port configuration register (drive mode) to High-Z Analog */ + Cy_GPIO_SetDrivemode(context->cfgCopy.ptrPinB->ioPcPtr, (uint32_t)context->cfgCopy.ptrPinB->pin, CY_GPIO_DM_ANALOG); + /* Connect the selected port to AMuxBusB */ + Cy_GPIO_SetHSIOM(context->cfgCopy.ptrPinB->ioPcPtr, (uint32_t)context->cfgCopy.ptrPinB->pin, HSIOM_SEL_AMUXB); + } +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_DisconnectChannelA +****************************************************************************//** +* +* Disconnects the output channel A pin, if it is configured. +* +* \param context +* The pointer to the CSDIDAC middleware context +* structure \ref cy_stc_csdidac_context_t. +* +*******************************************************************************/ +static void Cy_CSDIDAC_DisconnectChannelA(cy_stc_csdidac_context_t * context) +{ + /* Disables the desired IDAC. */ + context->channelStateA = CY_CSDIDAC_DISABLE; + Cy_CSD_WriteReg(context->cfgCopy.base, CY_CSD_REG_OFFSET_IDACA, 0uL); + /* Opens the bypass A switch to disconnect an output current from AMuxBusA. */ + if ((CY_CSDIDAC_GPIO == context->cfgCopy.configA) || (CY_CSDIDAC_AMUX == context->cfgCopy.configA)) + { + Cy_CSD_ClrBits(context->cfgCopy.base, CY_CSD_REG_OFFSET_SW_BYP_SEL, CY_CSDIDAC_SW_BYPA_ENABLE); + } + /* Disconnects AMuxBusA from the selected pin, if it is configured. */ + if ((CY_CSDIDAC_GPIO == context->cfgCopy.configA) && (NULL != context->cfgCopy.ptrPinA)) + { + Cy_GPIO_SetHSIOM(context->cfgCopy.ptrPinA->ioPcPtr, (uint32_t)context->cfgCopy.ptrPinA->pin, HSIOM_SEL_GPIO); + } +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_DisconnectChannelB +****************************************************************************//** +* +* Disconnects the output channel B pin, if it is configured. +* +* \param context +* The pointer to the CSDIDAC middleware context +* structure \ref cy_stc_csdidac_context_t. +* +*******************************************************************************/ +static void Cy_CSDIDAC_DisconnectChannelB(cy_stc_csdidac_context_t * context) +{ + /* Disables the desired IDAC. */ + context->channelStateB = CY_CSDIDAC_DISABLE; + Cy_CSD_WriteReg(context->cfgCopy.base, CY_CSD_REG_OFFSET_IDACB, 0uL); + /* Opens the bypass B switch to disconnect an output current from AMuxBusB. */ + if ((CY_CSDIDAC_GPIO == context->cfgCopy.configB) || (CY_CSDIDAC_AMUX == context->cfgCopy.configB)) + { + Cy_CSD_ClrBits(context->cfgCopy.base, CY_CSD_REG_OFFSET_SW_BYP_SEL, CY_CSDIDAC_SW_BYPB_ENABLE); + } + /* Disconnects AMuxBusB from the selected pin, if it is configured. */ + if ((CY_CSDIDAC_GPIO == context->cfgCopy.configB) && (NULL != context->cfgCopy.ptrPinB)) + { + Cy_GPIO_SetHSIOM(context->cfgCopy.ptrPinB->ioPcPtr, (uint32_t)context->cfgCopy.ptrPinB->pin, HSIOM_SEL_GPIO); + } +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_OutputDisable +****************************************************************************//** +* +* Disables a specified IDAC output. +* +* The function performs the following: +* * Verifies the input parameters. +* * Disables the specified output of CSDIDAC and returns the status code. +* +* \param ch +* The channel to disconnect. +* +* \param context +* The pointer to the CSDIDAC middleware context +* structure \ref cy_stc_csdidac_context_t. +* +* \return +* The function returns the status of its operation. +* * CY_CSDIDAC_SUCCESS - The operation is performed successfully. +* * CY_CSDIDAC_BAD_PARAM - The input pointer is NULL or an invalid parameter +* is passed. +* +*******************************************************************************/ +cy_en_csdidac_status_t Cy_CSDIDAC_OutputDisable( + cy_en_csdidac_choice_t ch, + cy_stc_csdidac_context_t * context) +{ + cy_en_csdidac_status_t retVal = CY_CSDIDAC_BAD_PARAM; + + if(NULL != context) + { + if ((CY_CSDIDAC_A == ch) || (CY_CSDIDAC_AB == ch)) + { + Cy_CSDIDAC_DisconnectChannelA(context); + retVal = CY_CSDIDAC_SUCCESS; + } + if ((CY_CSDIDAC_B == ch) || (CY_CSDIDAC_AB == ch)) + { + Cy_CSDIDAC_DisconnectChannelB(context); + retVal = CY_CSDIDAC_SUCCESS; + } + } + + return (retVal); +} + +#endif /* (defined(CY_IP_MXCSDV2) || defined(CY_IP_M0S8CSDV2)) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/cy_csdidac.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/cy_csdidac.h new file mode 100644 index 0000000000000000000000000000000000000000..62d8db1221be73fbaa23ae089ff5b29fb3971c68 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/cy_csdidac.h @@ -0,0 +1,1158 @@ +/***************************************************************************//** +* \file cy_csdidac.h +* \version 2.10 +* +* \brief +* This file provides the function prototypes and constants specific +* to the CSDIDAC middleware. +* +******************************************************************************** +* \copyright +* Copyright 2019-2020, Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ +/** +* \mainpage CSDIDAC Middleware Library +* +* The CSDIDAC middleware is the IDAC solution that uses the +* CSD HW block. Any GPIO that can be connected to AMUX-A/B (refer to the +* particular device datasheet for information) can be an CSDIDAC output +* under software control. +* The CSD HW block is mainly used to implement the touch sense applications and +* proximity sensors (refer to the +* +* CapSense Middleware API Reference Guide), but can also +* be used to implement the IDAC, which is especially useful for the devices that +* do not include another hardware option to implement IDAC. +* +* Features: +* * A two-channel IDAC with the 7-bit resolution. +* * The IDAC A and IDAC B channels can be enabled/disabled independently. +* * The IDAC A and IDAC B channels can be configured with sourcing/sinking +* current independently. +* * The IDAC A and IDAC B channels can be joined to increase a maximum output +* current. +* * The IDAC A and IDAC B channels can be enabled/disabled simultaneously +* by using the CY_CSDIDAC_AB option. +* * The 0 to 609.6 uA (609600 nA) current range is available for each IDAC +* channel. +* * Each IDAC can use independently one of the six available LSB depending +* on a desired output current: +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
LSB IndexLSBAvailable Current Range
037.5 nA0 to 4762.5 nA
175.0 nA0 to 9525.0 nA
20.3 uA0 to 38.1 uA
30.6 uA0 to 76.2 uA
42.4 uA0 to 304.8 uA
54.8 uA0 to 609.6 uA
+* +******************************************************************************** +* \section section_csdidac_general General Description +******************************************************************************** +* +* Include cy_csdidac.h to get access to all functions and other declarations in +* this library. +* The \ref section_csdidac_quick_start is offered in this API Reference Guide. +* +* Refer to the \ref section_csdidac_toolchain for the compatibility +* information. +* +* Refer to the \ref group_csdidac_changelog for the differences between the +* middleware versions. +* \ref group_csdidac_changelog also describes the impact of changes to +* your code. +* +* The CSD HW block enables the multiple sensing capabilities on PSoC devices +* including the self-cap and mutual-cap capacitive touch sensing solution, +* 10-bit ADC, IDAC, and Comparator. The CSD driver is a low-level +* peripheral driver, a wrapper to manage access to the CSD HW block. +* Any middleware access to the CSD HW block is through the CSD Driver. +* +* The CSD HW block can support only one function at a time. However, all +* supported functionality (like CapSense, CSDADC, CSDIDAC, etc.) can be +* time-multiplexed in a design. I.e. you can save the existing state +* of the CapSense middleware, restore the state of the CSDIDAC middleware, +* perform DAC operations, and then switch back to the CapSense functionality. +* For more details and code examples, refer to the description of the +* Cy_CSDIDAC_Save() and Cy_CSDIDAC_Restore() functions. +* +* \image html capsense_solution.png "CapSense Solution" width=800px +* \image latex capsense_solution.png +* +* This section describes only the CSDIDAC middleware. Refer to the corresponding +* sections for documentation of other middleware supported by the CSD HW block. +* The CSDIDAC library is designed to be used with the CSD driver. +* The application program does not need to interact with the CSD driver +* and/or other drivers such as GPIO or SysClk directly. All of that is +* configured and managed by the middleware. +* +* The Cy_CSDIDAC API is described in the following sections: +* * \ref group_csdidac_macros +* * \ref group_csdidac_data_structures +* * \ref group_csdidac_enums +* * \ref group_csdidac_functions +* +******************************************************************************** +* \section section_csdidac_quick_start Quick Start Guide +******************************************************************************** +* +* The CSDIDAC middleware can be used in various Development Environments +* such as ModusToolbox, MBED, etc. Refer to the \ref section_csdidac_toolchain. +* The quickest way to get started is using the Code Examples. +* The continually expanding portfolio of the code examples is available +* at the Cypress Semiconductor website +* and on +* GitHub. +* +* This quick start guide assumes that the environment is configured to use the +* PSoC 6 Peripheral Driver Library(psoc6pdl) for development and the +* PSoC 6 Peripheral Driver Library(psoc6pdl) is included in the project. +* +* The steps required to set up the CSDIDAC and get the +* desired current: +* +* 1. Set up the CSDIDAC configuration manually or by using the Device Configurator +* as described in the \ref section_csdidac_configuration section. +* \note +* Put the CSDIDAC name to the Alias field of the CSD resource if the +* Device Configurator is used. +* +* 2. Include cy_csdidac.h to get access to all CSDIDAC API and cy_pdl.h to get +* access to API of peripheral drivers according to the example below: +* \snippet csdidac/snippet/main.c snippet_required_includes +* 3. If you use the MBED OS, include the cycfg.h file to get access to the +* System Configuration: +* \snippet csdidac/snippet/main.c snippet_mbed_required_includes +* 4. Declare the 'cy_csdidac_context' variable as per example below: +* \snippet csdidac/snippet/main.c snippet_csdidac_context_declaration +* 5. Update the main() routine with the following code: +* \snippet csdidac/snippet/main.c snippet_Cy_CSDIDAC_Usage +* +******************************************************************************** +* \section section_csdidac_configuration Configuration Considerations +******************************************************************************** +* +* The CSDIDAC middleware operates on the top of the CSD Driver included in the +* PSoC 6 Peripheral Driver Library (psoc6pdl). Refer to the "CSD(CapSense +* Sigma Delta)" section of the PSoC 6 Peripheral Driver Library (psoc6pdl) API +* Reference Manual. +* This section guides how to set up the CSDIDAC middleware for the operation +* with the following parameters: +* 1. Device VDDA: 3.3V. +* 2. Device Peri Clock frequency: 48MHz. +* 3. IDAC A is sourcing current of 50 uA to GPIO pin P0[4]. +* 4. IDAC B is sinking current of 0.5uA from GPIO pin P0[5]. +* +* There are two methods for the CSDIDAC Middleware configuration: +* 1. \ref subsection_csdidac_mtb_configuring +* 2. \ref subsection_csdidac_manual_configuring +* +* Generation of the initialization code using the +* +* ModusToolbox Device Configurator Tool which is part of the +* +* ModusToolbox, greatly simplifies the PSoC configuration. +* The ModusToolbox +* Device Configurator Tool provides the user interface to set up and +* automatically generate the initialization code (including analog routing) and +* configuration structures. +* +* Manual implementation of the initialization code (including analog routing) +* and configuration structures is recommended for expert Users only. This will +* include the code for the following settings which in case of the +* Device Configurator usage are generated automatically based upon the settings +* entered in its UI: +* * Assigning the Peripheral Clock Divider. +* * Configuring the HSIOM_AMUX_SPLIT_CTL switches to route signal from input +* pins configured as the CSDIDAC channels to the CSD HW block. +* * Declaration and initialization of the CSDIDAC configuration structure. +* * Declaration and initialization of the CSD HW driver context structure. +* * Definition of the of the CSD HW block base address. +* +******************************************************************************** +* \subsection subsection_csdidac_mtb_configuring Use ModusToolbox Device Configurator Tool to generate initialization code +******************************************************************************** +* +* The steps required to generate the initialization code using the +* +* ModusToolbox Device Configurator Tool : +* 1. Launch the ModusToolbox Middleware Selector and enable the CSD IDAC +* middleware. This step is required only if the ModusToolbox IDE is used. +* Otherwise, ensure the CSDIDAC Middleware is included in your project. +* 2. Launch the ModusToolbox Device Configurator Tool. +* 3. Switch to the System tab. Configure the CLK_PERI frequency to achieve 48MHz +* (you may need to change the FLL or PLL frequency) and set the VDDA voltage +* to 3.3V in Power/MCU Personality. +* 4. Switch to the Peripherals tab (#1 in the figure below). Enable the +* CSD personality under System (#2 in the figure below) and +* enter Alias (#3 in the figure below). We use CSDIDAC in +* \ref section_csdidac_quick_start. +* 5. Go to the Parameters pane and configure the CSD Personality: +* * Assign the peripheral clock divider by using the Clock +* combo box(#4 in the figure below). Any free divider can be used. +* * Set the Enable CSDIDAC check box (#5 in the figure below). +* * Configure the CSDIDAC with the desired parameters per +* \ref section_csdidac_configuration (#5 in the figure below). +* * Assign the CSDIDAC Channels to pins per \ref section_csdidac_configuration +* (#6 in the figure below). +* 6. Switch to the Peripheral Clocks tab and configure the assigned peripheral +* clock divider. The Max supported clock frequency for the CSD HW block +* is 50 MHz. The divider value "1" can be used, because in the current case the +* Peri Clock frequency is 48 MHz. +* 7. Perform File->Save to generate the initialization code. +* +* \image html csdidac_config.png "CSDIDAC configuration" width=1172px +* \image latex csdidac_config.png +* +* Now, all required CSDIDAC initialization code and configuration prerequisites +* will be generated: +* * The Peripheral Clock Divider assignment and analog routing are parts of +* the init_cycfg_all() routine. Place the call of the init_cycfg_all() function +* before using any CSDIDAC API functions to ensure initialization of all +* external resources required for the CSDIDAC operation. +* Refer to the main() routine code snippet in +* \ref section_csdidac_quick_start +* * The CSDIDAC configuration structure declaration in the +* cycfg_peripherals.h file and its initialization in the +* cycfg_peripherals.c file. The variable name is +* \_csdidac_config. +* * The CSD HW driver context structure declaration in the +* cycfg_peripherals.h file and its initialization in the +* cycfg_peripherals.c file. The variable name is +* cy_csd_\_context. +* * The CSD HW block base address definition is in the +* cycfg_peripherals.h file. The definition name is \_HW. +* +* The generated code will be available under the GeneratedSource folder. +* +* Refer to \ref section_csdidac_quick_start section for the application layer +* code required to set up the CSDIDAC and to get the desired current on the +* assigned pin. +* +******************************************************************************** +* \subsection subsection_csdidac_manual_configuring Implement the initialization code manually +******************************************************************************** +* +* The steps required to implement the initialization code manually: +* 1. Launch the ModusToolbox Middleware Selector and enable the +* CSD IDAC middleware. This step is required only if the ModusToolbox IDE +* is used. +* Otherwise, ensure the CSDIDAC Middleware is included in your project. +* 2. Define the CSD HW block base address. See the code example below: +* \snippet csdidac/snippet/main.c snippet_csd_hw_definition +* 3. Declare the CSD HW driver context structure and initialize the +* lockKey field with the CY_CSD_NONE_KEY value. See the code example below: +* \snippet csdidac/snippet/main.c snippet_csd_context_declaration +* 4. Declare the CSDIDAC configuration structure and initialize it according +* to the desired parameters. See the code example below: +* \snippet csdidac/snippet/main.c snippet_csdidac_config_declaration +* 5. Assign the Peripheral Clock Divider to the CSD HW block and configure +* the divider value. +* See the code example below and refer to the main() routine code snippet in +* \ref section_csdidac_quick_start +* \snippet csdidac/snippet/main.c snippet_Cy_CSDIDAC_Clock_Assignment +* 6. Set the configuration of the HSIOM_AMUX_SPLIT_CTL switches to route signal +* from CSD HW block to the pins configured as the CSDIDAC output channels. +* +* The AMUX bus has segments that are separated with the HSIOM_AMUX_SPLIT_CTL switches. +* The code below closes the AMUX_SPLIT_CTL switches, which route the IDAC output +* signal from the CSD block to the pin. In this example, IDAC output channels +* are assigned to the P0[4] and P[5] pins. The AMUX_SPLIT_CTL[5] and AMUX_SPLIT_CTL[6] +* switches must be closed in the PSoC6 device. The P0[4] and P[5] pins in the +* PSoC4 device belong to the AMUX bus segment, which is connected to the CSD block +* directly. In this case, the AMUX_SPLIT_CTL switches are not closed. +* Refer to the +* Technical Reference Manual +* (TRM) for more information regarding the analog interconnection. +* See the code example below and refer to the main() routine code snippet in +* \ref section_csdidac_quick_start +* \snippet csdidac/snippet/main.c snippet_Cy_CSDIDAC_Amux_Configuration +* \note +* If you use a KIT, check on the schematics, if pins P0[4] and P0[5] are +* free. If not, use some other pins and update the AMUX_SPLIT_CTL registers. +* \note +* Some CSDIDAC configurations are restricted. The CSD personality has a +* mechanism to prevent writing an invalid configuration. If CSDIDAC is manually +* created, avoid the following combinations: +* * both IDAC channels are disabled +* * one IDAC channel is disabled and another channel is joined to it +* * the IDAC A channel and IDAC B channel are joined to each other +* +* Refer to \ref section_csdidac_quick_start section for the application layer +* code required to set up the CSDIDAC and to get the desired current on the +* assigned pin. +* +******************************************************************************** +* \section group_csdadc_use_cases Use Cases +******************************************************************************** +* +* This section provides descriptions and links to additional documentation for +* some specific CSDIDAC use cases. +* +******************************************************************************** +* \subsection group_csdidac_low_power_design Low power design +******************************************************************************** +* The CSD HW block and CSDIDAC middleware can operate in CPU active and +* CPU sleep power modes. It is also +* possible to switch between low power and ultra low power system modes. +* In System Deep Sleep and Hibernate power modes, the CSD HW block is powered off and +* CSDIDAC operations are not performed. Before entering CPU / System Deep Sleep, +* disable CSDIDAC output current generation. If output +* currents are not disabled, a CPU Deep Sleep transition will fail. +* When the device wakes up from CPU / System Deep Sleep, the CSD HW block resumes operation +* without the need for re-initialization and the CSDIDAC operations can be +* continued with configuration that was set before a CPU / System Deep Sleep transition. +* When the device wakes up from Hibernate power mode, the CSD HW block +* does not retain the configuration and CSDIDAC requires re-initialization. +* +* \note +* 1. Analog start up time for the CSD HW block is 25 us for PSoC6 devices and +* 10 us for PSoC4 devices. Initiate any kind of operation only after 25 us +* for PSoC6 devices and 10 us for PSoC4 devices from System Deep Sleep / Hibernate exit. +* +* 2. Entering CPU Deep Sleep mode does not mean the device enters +* System Deep Sleep. For more detail about switching to System Deep Sleep, +* refer to the device TRM. +* +* Refer to the Cy_CSDIDAC_DeepSleepCallback() function description and to the +* SysPm (System Power Management) driver documentation for the low power design +* considerations. +* +* Sleep mode
+* The CSD HW block can operate in CPU sleep mode. The user can start CSDIDAC +* and move CPU into sleep mode to reduce power consumption. After wake-up CPU +* from sleep, the user can perform other operations, e.g. disable IDACs. +* Then, the user configures the CSDIDAC middleware as described in +* \ref section_csdidac_configuration, and updates the main() routine with +* the following code: +* \snippet csdidac/snippet/main.c snippet_Cy_CSDIDAC_Sleep +* +* Deep Sleep mode
+* To use the CSDIDAC middleware in CPU / System Deep Sleep mode, the user configures +* a wake-up source (e.g. a pin, WDT, LPC or another entities, that are active +* in CPU / System Deep Sleep mode), configures the CSDIDAC middleware as described in +* \ref section_csdidac_configuration, configures CSDIDAC and other drivers' and +* middleware's (if present) Deep Sleep Callback structures, registers +* callbacks, and updates the main() routine with the following code: +* \snippet csdidac/snippet/main.c snippet_CSDIDAC_DeepSleep_structures +* \snippet csdidac/snippet/main.c snippet_Cy_CSDIDAC_DeepSleep +* +******************************************************************************** +* \subsection group_csdidac_time_multiplexing Time-multiplexing operation +******************************************************************************** +* Refer to the +* CapSense Middleware API Reference Guide for implementation of the +* time-multiplexing operation by using common CSD HW block. +* +******************************************************************************** +* \section section_csdidac_toolchain Supported Software and Tools +******************************************************************************** +* +* This version of the CSDIDAC Middleware was validated for compatibility +* with the following Software and Tools: +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
Software and ToolsVersion
ModusToolbox Software Environment2.1
- ModusToolbox Device Configurator2.1
- ModusToolbox CSD Personality for PSoC4 devices in Device Configurator1.0
- ModusToolbox CSD Personality for PSoC6 devices in Device Configurator2.0
PSoC4 Peripheral Driver Library (PDL)1.0.0
PSoC6 Peripheral Driver Library (PDL)1.5.0
GCC Compiler7.2.1
IAR Compiler8.32
Arm Compiler 66.11
MBED OS (only for PSoC6)5.15.1
FreeRTOS10.0.1
+* +******************************************************************************** +* \section section_csdidac_update Update to Newer Versions +******************************************************************************** +* Consult \ref group_csdidac_changelog to learn about the design impact of the +* newer version. Set up your environment in accordance with +* \ref section_csdidac_toolchain. You might need to re-generate the configuration +* structures for either the device initialization code or the middleware +* initialization code. +* +* Ensure: +* * The specified version of the ModusToolbox Device Configurator and +* the CSD personality are used to re-generate the device configuration. +* * The toolchains are set up properly for your environment per the settings +* outlined in the Supported Software and Tools. +* * The project is re-built once the the toolchains are configured and the +* configuration is completed. +* +******************************************************************************** +* \section group_csdidac_MISRA MISRA-C Compliance +******************************************************************************** +* +* The Cy_CSDIDAC library has the following specific deviations: +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
MISRA RuleRule Class (Required/Advisory)Rule DescriptionDescription of Deviation(s)
11.4ADo not perform a conversion between the pointer to an object +* and an integer type.Such a conversion is performed with CSDIDAC context +* in the DeepSleepCallback() function. +* This case is verified on correct operation.
1.2 R Constant: De-reference of the NULL pointer. These violations are reported as a result of using +* offset macros of the CSD Driver with corresponding documented +* violation 20.6. Refer to the CSD Driver API Reference Guide.
20.3
+* +******************************************************************************** +* \section group_csdidac_changelog Changelog +******************************************************************************** +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
VersionChangesReason for Change
2.10Added the support of PSoC 4 CapSense Forth Generation devicesDevices support
Minor documentation updateDocumentation cleanup
2.0The joining two IDAC channels option is added to increase +* the maximum CSDIDAC output current Feature enchancement
The cy_stc_csdidac_config_t structure is changed: the periClk field +* replaced with cpuClk, busOnlyA and busOnlyB fields replaced with +* configA and configB fields respectively, the field order is changed. +* The \ref cy_en_csdidac_channel_config_t enumeration type is added.User experience improvement
The \ref CY_CSDIDAC_HW_FAILURE and +* the \ref CY_CSDIDAC_BAD_CONFIGURATION return status cases are added +* to the \ref cy_en_csdidac_status_t enumeration typeUser experience improvement
The \ref CY_CSDIDAC_AB choosing case for both IDACs is added +* to the \ref cy_en_csdidac_choice_t enumeration typeFeature enchancement
The CSDIDAC MW sources are enclosed with the conditional compilation to +* ensure a successful compilation for non-CapSense-capable devicesCompilation for non-CapSense-capable devices
1.0The initial version
+* +******************************************************************************** +* \section group_csdidac_more_information More Information +******************************************************************************** +* +* Important information about the CapSense-technology overview, appropriate +* device for the design, CapSense system and sensor design guidelines, +* different interfaces and tuning guidelines necessary for a successful design +* of a CapSense system is available in the Getting Started with CapSense +* document and the product-specific CapSense design guide. It is highly +* recommended to start with these documents. They can be found at www.cypress.com. +* +* For more information, refer to the following documents: +* +* * CapSense and CSDIDAC Overview: +* +* * CSDIDAC Middleware +* Code Example for MBED OS +* +* * +* CapSense Middleware API Reference Guide +* +* * ModusToolbox Overview: +* +* * +* ModusToolbox Software Environment, Quick Start Guide, Documentation, +* and Videos +* +* * ModusToolbox +* Device Configurator Tool Guide +* +* * Kits: +* +* * +* CY8CKIT-145-40XX PSoC 4000S CapSense Prototyping Kit +* +* * +* CY8CKIT-149 PSoC 4100S Plus Prototyping Kit +* +* * +* CY8CKIT-041-40XX PSoC 4 S-Series Pioneer Kit +* +* * +* CY8CKIT-041-41XX PSoC 4100S CapSense Pioneer Kit +* +* * +* CY8CKIT-062-BLE PSoC 6 BLE Pioneer Kit +* +* * +* CY8CKIT-062-WiFi-BT PSoC 6 WiFi-BT Pioneer Kit +* +* * +* CY8CPROTO-062-4343W PSoC 6 Wi-Fi BT Prototyping Kit +* +* * General Information: +* +* * +* PSoC 4 PDL API Reference +* +* * +* PSoC 6 PDL API Reference +* +* * +* PSoC 6 Technical Reference Manual +* +* * +* PSoC 63 with BLE Datasheet Programmable System-on-Chip datasheet +* +* * +* PSoC 4000S Family: PSoC 4 Architecture Technical Reference Manual (TRM) +* +* * +* PSoC 4100S and PSoC 4100S Plus: PSoC 4 Architecture Technical Reference Manual (TRM) +* +* * +* Cypress Semiconductor GitHub +* +* * Cypress Semiconductor +* +* \note +* The links to another software component's documentation (middleware and PDL) +* point to GitHub to the latest available version of the software. +* To get documentation of the specified version, download from GitHub and unzip +* the component archive. The documentation is available in the docs folder. +* +* \defgroup group_csdidac_macros Macros +* \brief +* This section describes the CSDIDAC macros. These macros can be used for +* checking a maximum IDAC code and a maximum IDAC output current. +* For detailed information about macros, see each macro description. +* +* \defgroup group_csdidac_enums Enumerated types +* \brief +* Describes the enumeration types defined by the CSDIDAC. These enumerations +* can be used for checking CSDIDAC functions' return status, +* for defining a CSDIDAC LSB and polarity, and for choosing IDAC for an +* operation and defining its states. For detailed information about +* enumerations, see each enumeration description. +* +* \defgroup group_csdidac_data_structures Data Structures +* \brief +* Describes the data structures defined by the CSDIDAC. The CSDIDAC +* middleware use structures for output channel pins, +* middleware configuration, and context. The pin structure is included +* in the configuration structure and both of them can be defined by the +* user with the CSD personality in the Device Configurator or manually +* if the user doesn't use ModusToolbox. +* The context structure contains a copy of the configuration structure +* and current CSDIDAC middleware state data. The context +* structure should be allocated by the user and be passed to all +* CSDIDAC middleware functions. CSDIDAC middleware structure sizes +* are shown in the table below: +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
StructureSize in bytes (w/o padding)
cy_stc_csdidac_pin_t5
cy_stc_csdidac_config_t23
cy_stc_csdidac_context_t31
+* +* \defgroup group_csdidac_functions Functions +* \brief +* This section describes the CSDIDAC Function Prototypes. +*/ + +/******************************************************************************/ + + +#if !defined(CY_CSDIDAC_H) +#define CY_CSDIDAC_H + +#include "cy_device_headers.h" +#include "cy_csd.h" + +#if (defined(CY_IP_MXCSDV2) || defined(CY_IP_M0S8CSDV2)) + +/* The C binding of definitions to build with the C++ compiler. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** +* \addtogroup group_csdidac_macros +* \{ +*/ +/** Middleware major version */ +#define CY_CSDIDAC_MW_VERSION_MAJOR (2) + +/** Middleware minor version */ +#define CY_CSDIDAC_MW_VERSION_MINOR (10) + +/** Middleware version */ +#define CY_CSDIDAC_MW_VERSION (210) + +/** CSDIDAC ID. The user can identify the CSDIDAC middleware error codes by this macro. */ +#define CY_CSDIDAC_ID (CY_PDL_DRV_ID(0x44u)) + +/** +* The CSDIDAC max code value. The user provides the code +* parameter for the Cy_CSDIDAC_OutputEnableExt() function +* in the range from 0u to CY_CSDIDAC_MAX_CODE. +*/ +#define CY_CSDIDAC_MAX_CODE (127u) + +/** +* The CSDIDAC max output current value. The user provides +* the value of the current parameter for the Cy_CSDIDAC_OutputEnable() +* function in range from 0 to +/-(CY_CSDIDAC_MAX_CURRENT_NA). +*/ +#define CY_CSDIDAC_MAX_CURRENT_NA (609600uL) + +/** \} group_csdidac_macros */ + +/*************************************** +* Enumerated Types and Parameters +***************************************/ +/** +* \addtogroup group_csdidac_enums +* \{ +*/ + +/** CSDIDAC return enumeration type */ +typedef enum +{ + CY_CSDIDAC_SUCCESS = (0u), + /**< The operation executed successfully. */ + CY_CSDIDAC_BAD_PARAM = (CY_CSDIDAC_ID + (uint32_t)CY_PDL_STATUS_ERROR + 1u), + /**< + * An input parameter is invalid. + * The user checks whether all + * the input parameters are valid. + */ + CY_CSDIDAC_HW_BUSY = (CY_CSDIDAC_ID + (uint32_t)CY_PDL_STATUS_ERROR + 2u), + /**< + * The CSD HW block is busy, + * i.e. any of current channel (A or B) + * is enabled. + */ + CY_CSDIDAC_HW_LOCKED = (CY_CSDIDAC_ID + (uint32_t)CY_PDL_STATUS_ERROR + 3u), + /**< + * The CSD HW block is acquired and + * locked by other middleware + * or application. The CSDIDAC + * middleware waits for + * the CSD HW block release + * to acquire it for use. + */ + CY_CSDIDAC_HW_FAILURE = (CY_CSDIDAC_ID + (uint32_t)CY_PDL_STATUS_ERROR + 4u), + /**< + * A CSD HW block failure. The possible reasons: + * - No peripheral clock assigned to the CSD HW block. + * - Peripheral clock assigned to the CSD HW block is disabled. + * - The CSD HW clock frequency is less than 100 kHz. + * - The configuration CSD HW block registers are corrupted. + * - The CSD HW block is damaged. + */ + CY_CSDIDAC_BAD_CONFIGURATION = (CY_CSDIDAC_ID + (uint32_t)CY_PDL_STATUS_ERROR + 5u), + /**< + * The CSDIDAC configuration structure initialization issue. + * The possible reasons: + * - The base pointer is initialized with NULL. + * - The csdCxtPtr pointer is initialized with NULL. + * - The configA or configB fields are not enumerators of the + * \ref cy_en_csdidac_channel_config_t type. + * - The ptrPinA (ptrPinB) field is initialized with NULL + * when configA (configB) is initialized with \ref CY_CSDIDAC_GPIO. + * - The configA and configB fields are initialized with \ref CY_CSDIDAC_DISABLED + * simultaneously. + * - The configA and configB fields are initialized with \ref CY_CSDIDAC_JOIN + * simultaneously. + * - The configA (configB) field is initialized with \ref CY_CSDIDAC_JOIN + * when configB (configA) is initialized with \ref CY_CSDIDAC_DISABLED. + */ +} cy_en_csdidac_status_t; + +/** +* The CSDIDAC output current LSB enumeration type. The user can choose +* LSB when the Cy_CSDIDAC_OutputEnableExt() function is called and +* can check which LSB was chosen by the Cy_CSDIDAC_OutputEnable() +* function in the cy_stc_csdidac_context_t structure. +*/ + +typedef enum +{ + CY_CSDIDAC_LSB_37_IDX = 0u, /**< Index for 37.5 nA LSB */ + CY_CSDIDAC_LSB_75_IDX = 1u, /**< Index for 75.0 nA LSB */ + CY_CSDIDAC_LSB_300_IDX = 2u, /**< Index for 0.3 uA LSB */ + CY_CSDIDAC_LSB_600_IDX = 3u, /**< Index for 0.6 uA LSB */ + CY_CSDIDAC_LSB_2400_IDX = 4u, /**< Index for 2.4 uA LSB */ + CY_CSDIDAC_LSB_4800_IDX = 5u, /**< Index for 4.8 uA LSB */ +}cy_en_csdidac_lsb_t; + +/** +* The CSDIDAC polarity enumeration type. The user can choose the polarity +* when the Cy_CSDIDAC_OutputEnableExt() function is called and can +* check which polarity was chosen by the Cy_CSDIDAC_OutputEnable() +* function in the cy_stc_csdidac_context_t structure. +*/ +typedef enum +{ + CY_CSDIDAC_SOURCE = 0u, /**< Source polarity */ + CY_CSDIDAC_SINK = 1u, /**< Sink polarity */ +}cy_en_csdidac_polarity_t; + +/** +* The CSDIDAC channel enabling enumeration type. The user can check which +* channel (A or B or both) is currently enabled +* in the cy_stc_csdidac_context_t structure. +*/ +typedef enum +{ + CY_CSDIDAC_DISABLE = 0u, /**< The channel is disabled. */ + CY_CSDIDAC_ENABLE = 1u, /**< The channel is enabled. */ +}cy_en_csdidac_state_t; + +/** +* The CSDIDAC choosing enumeration type. The user can choose channel A or B +* to operate with the Cy_CSDIDAC_OutputEnableExt(), Cy_CSDIDAC_OutputDisable(), +* or Cy_CSDIDAC_OutputEnable() functions. +*/ +typedef enum +{ + CY_CSDIDAC_A = 0uL, /**< The IDAC A is chosen for an operation */ + CY_CSDIDAC_B = 1uL, /**< The IDAC B is chosen for an operation */ + CY_CSDIDAC_AB = 2uL, /**< Both IDACs are chosen for an operation */ +} cy_en_csdidac_choice_t; + +/** +* The CSDIDAC channel configuration defines either disabled or enabled with +* specific routing. +*/ +typedef enum +{ + CY_CSDIDAC_DISABLED = 0u, /**< The IDAC channel is disabled. */ + CY_CSDIDAC_GPIO = 1u, /**< The IDAC channel is enabled and routed to a pin. */ + CY_CSDIDAC_AMUX = 2u, /**< The IDAC channel is enabled and routed to a corresponding analog bus. */ + CY_CSDIDAC_JOIN = 3u, /**< The IDAC channel is enabled and routed to the other IDAC channel. */ +}cy_en_csdidac_channel_config_t; + +/** \} group_csdidac_enums */ + + +/*************************************** +* Data Structure Definitions +***************************************/ +/** +* \addtogroup group_csdidac_data_structures +* \{ +*/ + +/** The CSDIDAC pin structure. */ +typedef struct { + GPIO_PRT_Type * ioPcPtr; /**< The pointer to the channel IO PC register. */ + uint8_t pin; /**< The channel IO pin. */ +} cy_stc_csdidac_pin_t; + +/** The CSDIDAC configuration structure */ +typedef struct +{ + CSD_Type * base; /**< The pointer to the CSD HW Block. */ + cy_stc_csd_context_t * csdCxtPtr; /**< The pointer to the context of the CSD driver. */ + cy_en_csdidac_channel_config_t configA; /**< The IDAC A channel configuration. */ + cy_en_csdidac_channel_config_t configB; /**< The IDAC B channel configuration. */ + const cy_stc_csdidac_pin_t * ptrPinA; /**< The pointer to the IDAC A pin structure. */ + const cy_stc_csdidac_pin_t * ptrPinB; /**< The pointer to the IDAC B pin structure. */ + uint32_t cpuClk; /**< CPU Clock in Hz. */ + uint8_t csdInitTime; /**< The CSD HW Block initialization time. */ +} cy_stc_csdidac_config_t; + +/** The CSDIDAC context structure, that contains the internal middleware data. */ +typedef struct{ + cy_stc_csdidac_config_t cfgCopy; /**< A configuration structure copy. */ + cy_en_csdidac_polarity_t polarityA; /**< The current IdacA polarity. */ + cy_en_csdidac_lsb_t lsbA; /**< The current IdacA LSB. */ + uint8_t codeA; /**< The current IdacA code. */ + cy_en_csdidac_state_t channelStateA; /**< The IDAC channel A is enabled. */ + cy_en_csdidac_polarity_t polarityB; /**< The current IdacB polarity. */ + cy_en_csdidac_lsb_t lsbB; /**< The current IdacB LSB. */ + uint8_t codeB; /**< The current IdacB code. */ + cy_en_csdidac_state_t channelStateB; /**< The IDAC channel B is enabled. */ +}cy_stc_csdidac_context_t; + +/** \} group_csdidac_data_structures */ + + +/******************************************************************************* +* Function Prototypes +*******************************************************************************/ + +/** +* \addtogroup group_csdidac_functions +* \{ +*/ +cy_en_csdidac_status_t Cy_CSDIDAC_Init( + const cy_stc_csdidac_config_t * config, + cy_stc_csdidac_context_t * context); +cy_en_csdidac_status_t Cy_CSDIDAC_DeInit( + cy_stc_csdidac_context_t * context); +cy_en_csdidac_status_t Cy_CSDIDAC_WriteConfig( + const cy_stc_csdidac_config_t * config, + cy_stc_csdidac_context_t * context); +cy_en_csdidac_status_t Cy_CSDIDAC_Wakeup( + const cy_stc_csdidac_context_t * context); +cy_en_syspm_status_t Cy_CSDIDAC_DeepSleepCallback( + cy_stc_syspm_callback_params_t * callbackParams, + cy_en_syspm_callback_mode_t mode); +cy_en_csdidac_status_t Cy_CSDIDAC_Save( + cy_stc_csdidac_context_t * context); +cy_en_csdidac_status_t Cy_CSDIDAC_Restore( + cy_stc_csdidac_context_t * context); +cy_en_csdidac_status_t Cy_CSDIDAC_OutputEnable( + cy_en_csdidac_choice_t ch, + int32_t current, + cy_stc_csdidac_context_t * context); +cy_en_csdidac_status_t Cy_CSDIDAC_OutputEnableExt( + cy_en_csdidac_choice_t outputCh, + cy_en_csdidac_polarity_t polarity, + cy_en_csdidac_lsb_t lsbIndex, + uint32_t idacCode, + cy_stc_csdidac_context_t * context); +cy_en_csdidac_status_t Cy_CSDIDAC_OutputDisable( + cy_en_csdidac_choice_t ch, + cy_stc_csdidac_context_t * context); + +/** \} group_csdidac_functions */ + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_IsIdacLsbValid +****************************************************************************//** +* +* Performs verification if the value passed through the idacLsbVal +* parameter is the enumerator of the \ref cy_en_csdidac_lsb_t type. +* +* \param idacLsbVal +* The input value for verification. +* +* \return status +* Returns the verification status: +* - true - Indicates that the verification succeeded. +* - false - Indicates that the verification failed. +* +*******************************************************************************/ +__STATIC_INLINE bool Cy_CSDIDAC_IsIdacLsbValid(cy_en_csdidac_lsb_t idacLsbVal) +{ + bool retVal; + + switch(idacLsbVal) + { + case CY_CSDIDAC_LSB_37_IDX: + case CY_CSDIDAC_LSB_75_IDX: + case CY_CSDIDAC_LSB_300_IDX: + case CY_CSDIDAC_LSB_600_IDX: + case CY_CSDIDAC_LSB_2400_IDX: + case CY_CSDIDAC_LSB_4800_IDX: + retVal = true; + break; + + default: + retVal = false; + break; + } + + return(retVal); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_IsIdacPolarityValid +****************************************************************************//** +* +* Performs verification if the value passed through the idacPolarityVal +* parameter is the enumerator of the \ref cy_en_csdidac_polarity_t type. +* +* \param idacPolarityVal +* The input value for verification. +* +* \return status +* Returns the verification status: +* - true - Indicates that the verification succeeded. +* - false - Indicates that the verification failed. +* +*******************************************************************************/ +__STATIC_INLINE bool Cy_CSDIDAC_IsIdacPolarityValid(cy_en_csdidac_polarity_t idacPolarityVal) +{ + bool retVal; + + switch(idacPolarityVal) + { + case CY_CSDIDAC_SOURCE: + case CY_CSDIDAC_SINK: + retVal = true; + break; + + default: + retVal = false; + break; + } + + return(retVal); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_IsIdacChoiceValid +****************************************************************************//** +* +* Performs verification if the value passed through the idacChoiceVal +* parameter is the enumerator of the \ref cy_en_csdidac_choice_t type. +* +* Performs verification that both IDACs are not disabled if CY_CSDIDAC_AB is +* passed through the idacChoiceVal parameter. +* +* \param idacChoiceVal +* The input value for verification. +* +* \param idacAConfigVal +* The IDACA channel configuration. +* +* \param idacBConfigVal +* The IDACB channel configuration. +* +* \return status +* Returns the verification status: +* - true - Indicates that the verification succeeded. +* - false - Indicates that the verification failed. +* +*******************************************************************************/ +__STATIC_INLINE bool Cy_CSDIDAC_IsIdacChoiceValid(cy_en_csdidac_choice_t idacChoiceVal, + cy_en_csdidac_channel_config_t idacAConfigVal, + cy_en_csdidac_channel_config_t idacBConfigVal) +{ + bool retVal; + + switch(idacChoiceVal) + { + case CY_CSDIDAC_A: + case CY_CSDIDAC_B: + retVal = true; + break; + case CY_CSDIDAC_AB: + if((CY_CSDIDAC_DISABLED != idacAConfigVal) && + (CY_CSDIDAC_DISABLED != idacBConfigVal)) + { + retVal = true; + } + else + { + retVal = false; + } + break; + + default: + retVal = false; + break; + } + + return(retVal); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_IsIdacChConfigValid +****************************************************************************//** +* +* Performs verification if the value passed through the idacChConfigVal +* parameter is the enumerator of the \ref cy_en_csdidac_channel_config_t type. +* +* \param idacChConfigVal +* The input value for verification. +* +* \return status +* Returns the verification status: +* - true - Indicates that the verification succeeded. +* - false - Indicates that the verification failed. +* +*******************************************************************************/ +__STATIC_INLINE bool Cy_CSDIDAC_IsIdacChConfigValid(cy_en_csdidac_channel_config_t idacChConfigVal) +{ + bool retVal; + + switch(idacChConfigVal) + { + case CY_CSDIDAC_DISABLED: + case CY_CSDIDAC_GPIO: + case CY_CSDIDAC_AMUX: + case CY_CSDIDAC_JOIN: + retVal = true; + break; + + default: + retVal = false; + break; + } + + return(retVal); +} + + +/******************************************************************************* +* Function Name: Cy_CSDIDAC_IsIdacConfigValid +****************************************************************************//** +* +* Performs verification of the CSDIDAC data structure initialization. +* +* \param config +* The pointer to the CSDIDSC configuration structure \ref cy_stc_csdidac_config_t. +* +* \return status +* Returns the verification status: +* - true - Indicates that the verification succeeded. +* - false - Indicates that the verification failed. +* +*******************************************************************************/ +__STATIC_INLINE bool Cy_CSDIDAC_IsIdacConfigValid(const cy_stc_csdidac_config_t * config) +{ + bool retVal = true; + + if((NULL != config->base) && (NULL != config->csdCxtPtr)) + { + if(((CY_CSDIDAC_GPIO == config->configA) && (NULL == config->ptrPinA)) || + ((CY_CSDIDAC_GPIO == config->configB) && (NULL == config->ptrPinB)) || + ((CY_CSDIDAC_DISABLED == config->configA) && (CY_CSDIDAC_DISABLED == config->configB)) || + ((CY_CSDIDAC_JOIN == config->configA) && (CY_CSDIDAC_DISABLED == config->configB)) || + ((CY_CSDIDAC_JOIN == config->configB) && (CY_CSDIDAC_DISABLED == config->configA)) || + (false == Cy_CSDIDAC_IsIdacChConfigValid(config->configA)) || + (false == Cy_CSDIDAC_IsIdacChConfigValid(config->configB)) || + ((CY_CSDIDAC_JOIN == config->configA) && (CY_CSDIDAC_JOIN == config->configB))) + { + retVal = false; + } + } + else + { + retVal = false; + } + + return(retVal); +} + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* (defined(CY_IP_MXCSDV2) || defined(CY_IP_M0S8CSDV2)) */ + +#endif /* CY_CSDIDAC_H */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/version.xml b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/version.xml new file mode 100644 index 0000000000000000000000000000000000000000..7e1c8664aeac67b3a38b541b091eb8bddc4911be --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/csdidac/version.xml @@ -0,0 +1 @@ +2.10.0.248 diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/.gitignore b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2f88269126ddda7f912628d1b74a7000a358468e --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/.gitignore @@ -0,0 +1 @@ +/docs diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/.mbedignore b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/.mbedignore new file mode 100644 index 0000000000000000000000000000000000000000..ab1cfb4ef2c685fde1e195236d4678c9682ee3d9 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/.mbedignore @@ -0,0 +1 @@ +test/* diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/LICENSE.txt b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..bbd030eeebe3e03f198777935688760287e03dc5 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/LICENSE.txt @@ -0,0 +1,210 @@ +CYPRESS (AN INFINEON COMPANY) END USER LICENSE AGREEMENT + +PLEASE READ THIS END USER LICENSE AGREEMENT ("Agreement") CAREFULLY BEFORE +DOWNLOADING, INSTALLING, COPYING, OR USING THIS SOFTWARE AND ACCOMPANYING +DOCUMENTATION. BY DOWNLOADING, INSTALLING, COPYING OR USING THE SOFTWARE, +YOU ARE AGREEING TO BE BOUND BY THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL +OF THE TERMS OF THIS AGREEMENT, PROMPTLY RETURN AND DO NOT USE THE SOFTWARE. +IF YOU HAVE PURCHASED THIS LICENSE TO THE SOFTWARE, YOUR RIGHT TO RETURN THE +SOFTWARE EXPIRES 30 DAYS AFTER YOUR PURCHASE AND APPLIES ONLY TO THE ORIGINAL +PURCHASER. + +1. Definitions. + + "Software" means this software and any accompanying documentation, + including any upgrades, updates, bug fixes or modified versions provided + to you by Cypress. + + "Source Code" means software in human-readable form. + + "Binary Code" means the software in binary code form such as object code or + an executable. + + "Development Tools" means software that is intended to be installed on a + personal computer and used to create programming code for Firmware, + Drivers, or Host Applications. Examples of Development Tools are + Cypress's PSoC Creator software, Cypress's WICED SDKs, and Cypress's + ModusToolbox software. + + "Firmware" means software that executes on a Cypress hardware product. + + "Driver" means software that enables the use of a Cypress hardware product + on a particular host operating system such as GNU/Linux, Windows, MacOS, + Android, and iOS. + + "Host Application" means software that executes on a device other than a + Cypress hardware product in order to program, control, or communicate + with a Cypress hardware product. + + "inf File" means a hardware setup information file (.inf file) created by + the Software to allow a Microsoft Windows operating system to install + the driver for a Cypress hardware product. + +2. License. Subject to the terms and conditions of this Agreement, Cypress +Semiconductor Corporation ("Cypress") and its suppliers grant to you a +non-exclusive, non-transferable license under their copyright rights: + + a. to use the Development Tools in object code form solely for the purpose + of creating Firmware, Drivers, Host Applications, and inf Files for + Cypress hardware products; and + + b. (i) if provided in Source Code form, to copy, modify, and compile the + Firmware Source Code to create Firmware for execution on a Cypress + hardware product, and + (ii) to distribute Firmware in binary code form only, only when + installed onto a Cypress hardware product; and + + c. (i) if provided in Source Code form, to copy, modify, and compile the + Driver Source Code to create one or more Drivers to enable the use + of a Cypress hardware product on a particular host operating + system, and + (ii) to distribute the Driver, in binary code form only, only when + installed on a device that includes the Cypress hardware product + that the Driver is intended to enable; and + + d. (i) if provided in Source Code form, to copy, modify, and compile the + Host Application Source Code to create one or more Host + Applications to program, control, or communicate with a Cypress + hardware product, and + (ii) to distribute Host Applications, in binary code form only, only + when installed on a device that includes a Cypress hardware product + that the Host Application is intended to program, control, or + communicate with; and + + e. to freely distribute any inf File. + +Any distribution of Software permitted under this Agreement must be made +pursuant to your standard end user license agreement used for your proprietary +(closed source) software products, such end user license agreement to include, +at a minimum, provisions limiting your licensors' liability and prohibiting +reverse engineering of the Software, consistent with such provisions in this +Agreement. + +3. Free and Open Source Software. Portions of the Software may be licensed +under free and/or open source licenses such as the GNU General Public License +or other licenses from third parties ("Third Party Software"). Third Party +Software is subject to the applicable license agreement and not this +Agreement. If you are entitled to receive the source code from Cypress for +any Third Party Software included with the Software, either the source code +will be included with the Software or you may obtain the source code at no +charge from . The applicable license +terms will accompany each source code package. To review the license terms +applicable to any Third Party Software for which Cypress is not required to +provide you with source code, please see the Software's installation directory +on your computer. + +4. Proprietary Rights; Ownership. The Software, including all intellectual +property rights therein, is and will remain the sole and exclusive property of +Cypress or its suppliers. Cypress retains ownership of the Source Code and +any compiled version thereof. Subject to Cypress' ownership of the underlying +Software (including Source Code), you retain ownership of any modifications +you make to the Source Code. You agree not to remove any Cypress copyright or +other notices from the Source Code and any modifications thereof. You agree +to keep the Source Code confidential. Any reproduction, modification, +translation, compilation, or representation of the Source Code except as +permitted in Section 2 ("License") is prohibited without the express written +permission of Cypress. Except as otherwise expressly provided in this +Agreement, you may not: + (i) modify, adapt, or create derivative works based upon the Software; + (ii) copy the Software; + (iii) except and only to the extent explicitly permitted by applicable + law despite this limitation, decompile, translate, reverse engineer, + disassemble or otherwise reduce the Software to human-readable form; + or + (iv) use the Software or any sample code other than for the Purpose. +You hereby covenant that you will not assert any claim that the Software, or +derivative works thereof created by or for Cypress, infringe any intellectual +property right owned or controlled by you + +5. No Support. Cypress may, but is not required to, provide technical support +for the Software. + +6. Term and Termination. This Agreement is effective until terminated, and +either party may terminate this Agreement at any time with or without cause. +This Agreement and your license rights under this Agreement will terminate +immediately without notice from Cypress if you fail to comply with any +provision of this Agreement. Upon termination, you must destroy all copies of +Software in your possession or control. The following paragraphs shall +survive any termination of this Agreement: "Free and Open Source Software," +"Proprietary Rights; Ownership," "Compliance With Law," "Disclaimer," +"Limitation of Liability," and "General." + +7. Compliance With Law. Each party agrees to comply with all applicable laws, +rules and regulations in connection with its activities under this Agreement. +Without limiting the foregoing, the Software may be subject to export control +laws and regulations of the United States and other countries. You agree to +comply strictly with all such laws and regulations and acknowledge that you +have the responsibility to obtain licenses to export, re-export, or import the +Software. + +8. Disclaimer. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, CYPRESS +MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THE +SOFTWARE, INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress +reserves the right to make changes to the Software without notice. Cypress +does not assume any liability arising out of the application or use of +Software or any product or circuit described in the Software. It is the +responsibility of the user of the Software to properly design, program, and +test the functionality and safety of any application made of the Software and +any resulting product. Cypress does not authorize its Software or products +for use in any products where a malfunction or failure of the Software or +Cypress product may reasonably be expected to result in significant property +damage, injury or death ("High Risk Product"). If you include any Software or +Cypress product in a High Risk Product, you assume all risk of such use and +agree to indemnify Cypress and its suppliers against all liability. No +computing device can be absolutely secure. Therefore, despite security +measures implemented in Cypress hardware or software products, Cypress does +not assume any liability arising out of any security breach, such as +unauthorized access to or use of a Cypress product. + +9. Limitation of Liability. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE +LAW, IN NO EVENT WILL CYPRESS OR ITS SUPPLIERS, RESELLERS, OR DISTRIBUTORS BE +LIABLE FOR ANY LOST REVENUE, PROFIT, OR DATA, OR FOR SPECIAL, INDIRECT, +CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS +OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR +INABILITY TO USE THE SOFTWARE EVEN IF CYPRESS OR ITS SUPPLIERS, RESELLERS, OR +DISTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO +EVENT SHALL CYPRESS' OR ITS SUPPLIERS', RESELLERS', OR DISTRIBUTORS' TOTAL +LIABILITY TO YOU, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), OR +OTHERWISE, EXCEED THE GREATER OF US$500 OR THE PRICE PAID BY YOU FOR THE +SOFTWARE. THE FOREGOING LIMITATIONS SHALL APPLY EVEN IF THE ABOVE-STATED +WARRANTY FAILS OF ITS ESSENTIAL PURPOSE. BECAUSE SOME STATES OR JURISDICTIONS +DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, +ALL OR PORTIONS OF THE ABOVE LIMITATION MAY NOT APPLY TO YOU. + +10. Restricted Rights. The Software is commercial computer software as that +term is described in 48 C.F.R. 252.227-7014(a)(1). If the Software is being +acquired by or on behalf of the U.S. Government or by a U.S. Government prime +contractor or subcontractor (at any tier), then the Government's rights in +Software shall be only those set forth in this Agreement. + +11. Personal Information. You agree that information you provide through your +registration on Cypress IoT Community Forum or other Cypress websites, +including contact information or other personal information, may be collected +and used by Cypress consistent with its Data Privacy Policy +(www.cypress.com/privacy-policy), as updated or revised from time to time, and +may be provided to its third party sales representatives, distributors and +other entities conducting sales activities for Cypress for sales-related and +other business purposes. + +12. General. This Agreement will bind and inure to the benefit of each +party's successors and assigns, provided that you may not assign or transfer +this Agreement, in whole or in part, without Cypress' written consent. This +Agreement shall be governed by and construed in accordance with the laws of +the State of California, United States of America, as if performed wholly +within the state and without giving effect to the principles of conflict of +law. The parties consent to personal and exclusive jurisdiction of and venue +in, the state and federal courts within Santa Clara County, California; +provided however, that nothing in this Agreement will limit Cypress' right to +bring legal action in any venue in order to protect or enforce its +intellectual property rights. No failure of either party to exercise or +enforce any of its rights under this Agreement will act as a waiver of such +rights. If any portion of this Agreement is found to be void or +unenforceable, the remaining provisions of this Agreement shall remain in full +force and effect. This Agreement is the complete and exclusive agreement +between the parties with respect to the subject matter hereof, superseding and +replacing any and all prior agreements, communications, and understandings +(both written and oral) regarding such subject matter. Any notice to Cypress +will be deemed effective when actually received and must be sent to Cypress +Semiconductor Corporation, ATTN: Chief Legal Officer, 198 Champion Court, San +Jose, CA 95134 USA. \ No newline at end of file diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/README.md b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/README.md new file mode 100644 index 0000000000000000000000000000000000000000..86cc1c6ab55e4fdd7e6cb7dd7d4304c6b0a68228 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/README.md @@ -0,0 +1,69 @@ +# USB Device Middleware Library + +## Overview + +The USB Device middleware provides a full-speed +[USB 2.0 Chapter 9 specification](https://usb.org/document-library/usb-20-specification) +compliant device framework. It uses the USBFS driver from +CAT1A/CAT2 Peripheral Driver Library to interface with the hardware. +The middleware provides support for Audio, CDC, HID and Vendor classes. +It also enables implementing support for other classes. The USB Configurator +tool makes it easy to construct a USB Device descriptor. + +## Features + +* USB Full-Speed Device Framework +* USB Device Configurator +* The following USB Classes are supported: + * Audio Class + * CDC: Communication Device Class + * HID: Human Interface Device +* Adding Custom Class Support +* Vendor-Specific Requests Support +* Power Status Reporting for Self-Powered Devices +* Blocking API Timeout Function Redefinition +* Compliance with [MISRA-C:2012 coding standard](https://www.misra.org.uk/) + +## USB Device Specific Instructions + +The user must ensure that the parameters selected in the USB Device personality +are aligned with the descriptor configuration in the USB Configurator, because +there is no connection between the USB Device personality in the Device +Configurator and USB Configurator. + +Specifically, parameter "Endpoints Mask" in the USB personality must be aligned +with the endpoints selected in the USB Configurator. If DMA Automatic mode is +selected, parameter "Endpoint Buffer Size" must be aligned with the total size +of the endpoint buffers allocated in the USB Configurator. + +## Quick Start + +Configure the USB Device using the ModusToolbox™ USB Device personality and +USB Device Configurator. Refer to the +[API Reference Quick Start Guide](https://infineon.github.io/usbdev/usbfs_dev_api_reference_manual/html/index.html) + +## More information + +The following links provide more information: + +* [USB Device Middleware Library Release Notes](./RELEASE.md) +* [USB Device Middleware Library API Reference](https://infineon.github.io/usbdev/usbfs_dev_api_reference_manual/html/index.html) +* [CAT1 Peripheral Driver Library API Reference](https://infineon.github.io/mtb-pdl-cat1/pdl_api_reference_manual/html/index.html) +* [CAT2 Peripheral Driver Library API Reference](https://infineon.github.io/mtb-pdl-cat2/pdl_api_reference_manual/html/index.html) +* [ModusToolbox™ Software Environment, Quick Start Guide, Documentation, and Videos](https://www.cypress.com/products/modustoolbox-software-environment) +* [PSoC™ 6 SDK Examples](https://github.com/Infineon?q=mtb-example-psoc6%20NOT%20Deprecated) +* [ModusToolbox™ USB Configurator Tool Guide](https://www.cypress.com/ModusToolboxUSBConfig) +* [ModusToolbox™ Device Configurator Tool Guide](https://www.cypress.com/ModusToolboxDeviceConfig) +* [PSoC™ 6 WiFi-BT Pioneer Kit](http://www.cypress.com/CY8CKIT-062-WiFi-BT) +* [PSoC™ 6 Wi-Fi BT Prototyping Kit](http://www.cypress.com/cy8cproto-062-4343w) +* [PSoC™ 6 MCU Datasheets](http://www.cypress.com/psoc6ds) +* [PSoC™ 6 MCU Application Notes](http://www.cypress.com/psoc6an) +* [PSoC™ 6 MCU Technical Reference Manuals](http://www.cypress.com/psoc6trm) +* [PMG1-S2 Prototyping Kit](http://www.cypress.com/CY7112) +* [PMG1-S3 Prototyping Kit](http://www.cypress.com/CY7113) +* [PMG1 Datasheets](https://www.cypress.com/PMG1DS) +* [CYPRESS™ Semiconductor](http://www.cypress.com) + +--- +© 2019-2021, CYPRESS™ Semiconductor Corporation (an Infineon company) +or an affiliate of CYPRESS™ Semiconductor Corporation. diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/RELEASE.md b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/RELEASE.md new file mode 100644 index 0000000000000000000000000000000000000000..773cbad0a0cae494d3759730e3fa395076dc88e3 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/RELEASE.md @@ -0,0 +1,62 @@ +# USB Device Middleware Library 2.10 + +## What's Included? + +For a complete description of the USB Device Middleware, refer to +[README.md](./README.md) and the +[USB Device API Reference](https://infineon.github.io/usbdev/usbfs_dev_api_reference_manual/html/index.html). +The revision history of the USB Device Middleware is also available in the +[API Reference Changelog](https://infineon.github.io/usbdev/usbfs_dev_api_reference_manual/html/index.html#group_usb_dev_changelog). + +New in this release: + +* Updated the middleware to support configurations without any data endpoints. +* Added support for the PMG1 Family of MCUs. +* Updated the middleware to comply with MISRA-C:2012 standard. + +## Defect Fixes + +* Fixed an issue in vendor class request handling. + +## USB Device Specific Instructions + +The user must ensure that the parameters selected in the USB Device personality +are aligned with the descriptor configuration in the USB Configurator, because +there is no connection between the USB Device personality in the Device +Configurator and USB Configurator. + +Specifically, parameter "Endpoints Mask" in the USB personality must be aligned +with the endpoints selected in the USB Configurator. If DMA Automatic mode is +selected, parameter "Endpoint Buffer Size" must be aligned with the total size +of the endpoint buffers allocated in the USB Configurator. + +## Known Issues + +| Problem | Workaround | +| ------- | ---------- | +| The USB Device ignores LPM requests after wake up from Deep Sleep. | Call USBFS driver Cy_USBFS_Dev_Drv_Lpm_SetResponse() after calling Cy_USBFS_Dev_Drv_Resume() to restore response to the LPM packets. | +| The USB Device modes with DMA do not work after wake up from Deep Sleep, due to incorrect restore of the ARB_CFG register. | Save ARB_CFG values before entering Deep Sleep and restore it after calling of Cy_USBFS_Dev_Drv_Resume. | + +## Supported Software and Tools + +This version of the USB Device Middleware was validated for compatibility with the following Software and Tools: + +| Software and Tools | Version | +| :--- | :----: | +| ModusToolbox™ Software Environment | 2.3 | +| - ModusToolbox™ Device Configurator | 3.0 | +| - ModusToolbox™ USB Device Personality in Device Configurator | 1.1 | +| - ModusToolbox™ USB Device Configurator | 2.30 | +| MTB CAT1A Peripheral Driver Library (PDL) | 2.2.1 | +| MTB CAT2 Peripheral Driver Library (PDL) | 1.2.0 | +| GCC Compiler | 9.3.1 | +| IAR Compiler | 8.42.2 | +| ARM Compiler 6 | 6.16 | + +## More information + +For a more information, refer to [README.md](./README.md) + +--- +© 2019-2021, CYPRESS™ Semiconductor Corporation (an Infineon company) +or an affiliate of CYPRESS™ Semiconductor Corporation. diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev.c b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev.c new file mode 100644 index 0000000000000000000000000000000000000000..e12cca90af94eb03536d9294e0fe7eabe19736d9 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev.c @@ -0,0 +1,2853 @@ +/***************************************************************************//** +* \file cy_usb_dev.c +* \version 2.10 +* +* Provides API implementation of the USBFS device middleware. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + +#include "cy_usb_dev.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + + +/******************************************************************************* +* Internal Macro +*******************************************************************************/ + +#define GET_CFG_WORD(addr) CY_USB_DEV_GET_CFG_WORD(addr) +#define VAL2IDX(val) ( (uint32_t) (val) - 1U) +#define GET_UINT16(lsb, msb) ((lsb) | (uint16_t) (((uint16_t) (msb)) << 8UL)) + +/* Decode setup request bmRequestType */ +#define SETUP_RQST_RCPT_Pos (0) +#define SETUP_RQST_RCPT_Msk (0x1FU) +#define SETUP_RQST_TYPE_Pos (5) +#define SETUP_RQST_TYPE_Msk (0x60u) +#define SETUP_RQST_DIR_Pos (7) +#define SETUP_RQST_DIR_Msk (0x80U) + +/* Setup request layout in the buffer */ +#define SETUP_RQST_POS (0) +#define SETUP_RQST_TYPE_POS (1) +#define SETUP_VALUE_LSB_POS (2) +#define SETUP_VALUE_MSB_POS (3) +#define SETUP_INDEX_LSB_POS (4) +#define SETUP_INDEX_MSB_POS (5) +#define SETUP_LENGTH_LSB_POS (6) +#define SETUP_LENGTH_MSB_POS (7) + +/* Field position in the descriptors */ +#define CONFIG_DESCR_LENGTH_LSB_POS (2) /* Configuration descriptor length (LSB) byte position */ +#define CONFIG_DESCR_LENGTH_MSB_POS (3) /* Configuration descriptor length (MSB) byte position */ +#define BOS_DESCR_LENGTH_LSB_POS (2) /* BOS descriptor length (LSB) byte position */ +#define BOS_DESCR_LENGTH_MSB_POS (3) /* BOS descriptor length (MSB) byte position */ +#define CONFIG_DESCR_ATTRIB_POS (7) /* Configuration descriptor attribute byte position */ +#define DEVICE_DESCR_ISN_STRING_POS (16) /* Position of Serial Number in Device Descriptor */ +#define STRING_DESCR_LENGTH_POS (0) /* Position inside string descriptor where length is stored */ +#define STRING_DESCR_TYPE_POS (1) /* Position inside string descriptor where type is stored */ + +/* bmAttributes in configuration descriptor */ +#define CONFIG_ATTR_SELF_POWERED_MASK (0x40U) /* Configuration attribute Self-Powered mask */ +#define CONFIG_ATTR_REMOTE_WAKEUP_MASK (0x20U) /* Configuration attribute Remote Wakeup mask */ + +/* Fixed string descriptor indexes */ +#define STRING_LANGID_INDEX (0U) +#define STRING_IMSOS_INDEX (0xEEU) +#define EXT_OS_DESC_LENGTH_BYTE0_POS (0x0U) +#define EXT_OS_DESC_LENGTH_BYTE1_POS (0x1U) +#define EXT_OS_DESC_LENGTH_BYTE2_POS (0x2U) +#define EXT_OS_DESC_LENGTH_BYTE3_POS (0x3U) + + +/******************************************************************************* +* Static Functions Prototypes +*******************************************************************************/ + +static int32_t HandleTimeout(int32_t milliseconds); + +#if defined(CY_IP_MXUSBFS) +static void InitSerialNumberString(cy_stc_usb_dev_context_t *context); +#endif /* defined(CY_IP_MXUSBFS) */ + +static cy_en_usb_dev_status_t ConvertEndpointStateToStatus(cy_en_usb_dev_ep_state_t epState); + +static void BusResetCallback(USBFS_Type *base, struct cy_stc_usbfs_dev_drv_context *drvContext); +static void Ep0SetupCallback(USBFS_Type *base, struct cy_stc_usbfs_dev_drv_context *drvContext); +static void Ep0InCallback (USBFS_Type *base, struct cy_stc_usbfs_dev_drv_context *drvContext); +static void Ep0OutCallback (USBFS_Type *base, struct cy_stc_usbfs_dev_drv_context *drvContext); + +static cy_en_usb_dev_status_t HandleSetup(cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t HandleIn (cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t HandleOut (cy_stc_usb_dev_context_t *context); + +static void DecodeSetupPacket (uint8_t const *data, cy_stc_usb_dev_setup_packet_t *packet); + +static cy_en_usb_dev_status_t HandleStandardRequests (cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t GetDescriptorRequest (cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t GetConfigurationRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t GetInterfaceRequest (cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t GetStatusRequest (cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t const *context); +static cy_en_usb_dev_status_t ClearFeatureRequest (cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t SetAddressRequest (cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t SetConfigurationRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t SetInterfaceRequest (cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t SetFeatureRequest (cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context); + +static cy_en_usb_dev_status_t HandleClassRequests(cy_stc_usb_dev_class_ll_item_t *curItem, + cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t HandleClassRequestsCompleted(cy_stc_usb_dev_class_ll_item_t *curItem, + cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context); + +static cy_en_usb_dev_status_t GetExtOsStringDescriptors(cy_stc_usb_dev_ms_os_string_t const *msOsString, + cy_stc_usb_dev_control_transfer_t *transfer); +static cy_en_usb_dev_status_t HandleVendorRequests(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context); +static cy_en_usb_dev_status_t HandleVendorRequestsCompleted(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context); + +static cy_en_usb_dev_status_t CallSetInterfaceCallbacks(uint32_t interface, + uint32_t alternate, + cy_stc_usb_dev_class_ll_item_t *curItem, + cy_stc_usb_dev_context_t *context); + +static cy_en_usb_dev_status_t ConfigureDataEndpoints(uint32_t config, cy_stc_usb_dev_context_t *context); + +static cy_en_usb_dev_status_t InterfaceRemoveDataEndpoints(uint32_t numEndpoints, + cy_stc_usb_dev_endpoint_t const * const *epsPool, + cy_stc_usb_dev_context_t *context); + +static cy_en_usb_dev_status_t InterfaceAddDataEndpoints(uint32_t numEndpoints, + cy_stc_usb_dev_endpoint_t const * const *epsPool, + cy_stc_usb_dev_context_t *context); + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_Init +****************************************************************************//** +* +* Initialize the USB Device stack and underneath USBFS hardware driver. +* +* \param base +* The pointer to the USBFS instance. +* +* \param drvConfig +* The pointer to the USBFS driver configuration structure. +* +* \param drvContext +* The pointer to the USBFS driver context structure allocated by the user. +* The structure is used during the USBFS driver operation for internal +* configuration and data retention. The user must not modify anything in +* this structure. +* +* \param device +* The pointer to the device structure \ref cy_stc_usb_dev_device_t. +* +* \param config +* The pointer to the driver configuration structure \ref cy_stc_usb_dev_config_t. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for +* internal configuration and data retention. The user must not modify anything +* in this structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +* \note +* The configuration of USB clocks, pins, and interrupts is not handled by this +* function and must be done on the application level. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_Init(USBFS_Type *base, + struct cy_stc_usbfs_dev_drv_config const *drvConfig, + struct cy_stc_usbfs_dev_drv_context *drvContext, + cy_stc_usb_dev_device_t const *device, + cy_stc_usb_dev_config_t const *config, + cy_stc_usb_dev_context_t *context) +{ + /* Input parameters verification */ + if ((NULL == device) || (NULL == config) || (NULL == context) || + (NULL == base) || (NULL == drvConfig) || (NULL == drvContext)) + { + return CY_USB_DEV_BAD_PARAM; + } + + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_DRV_HW_ERROR; + + /* Store driver information in device */ + context->drvBase = base; + context->drvContext = drvContext; + + /* Set default state */ + context->state = CY_USB_DEV_DISABLED; + context->configuration = 0U; + context->classRoot = NULL; + + /* Configure endpoint 0 buffer */ + context->ControlTransfer.buffer = config->ep0Buffer; + context->ControlTransfer.bufferSize = config->ep0BufferSize; + + /* Store link to descriptors */ + context->devDescriptors = device; + + /* Initialize delay function */ + context->handleTimeout = &HandleTimeout; + + /* Initialize event callback */ + context->eventsCallback = NULL; + +#if defined(CY_IP_MXUSBFS) + + /* Initialize serial string descriptor and set pointer */ + InitSerialNumberString(context); + +#endif /* defined(CY_IP_MXUSBFS) */ + + context->getSerialNumString = NULL; + + /* Initialize vendor-specific callbacks */ + context->vndRequestReceived = NULL; + context->vndRequestCompleted = NULL; + + /* Link driver and device context */ + Cy_USBFS_Dev_Drv_SetDevContext(base, context, drvContext); + + /* Configure driver */ + retStatus = (cy_en_usb_dev_status_t) Cy_USBFS_Dev_Drv_Init(base, drvConfig, drvContext); + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Hook device handlers to be called by driver */ + Cy_USBFS_Dev_Drv_RegisterServiceCallback(base, CY_USB_DEV_BUS_RESET, &BusResetCallback, drvContext); + Cy_USBFS_Dev_Drv_RegisterServiceCallback(base, CY_USB_DEV_EP0_SETUP, &Ep0SetupCallback, drvContext); + Cy_USBFS_Dev_Drv_RegisterServiceCallback(base, CY_USB_DEV_EP0_IN, &Ep0InCallback, drvContext); + Cy_USBFS_Dev_Drv_RegisterServiceCallback(base, CY_USB_DEV_EP0_OUT, &Ep0OutCallback, drvContext); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_DeInit +****************************************************************************//** +* +* De-initialize the USB Device stack and underneath hardware driver. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +void Cy_USB_Dev_DeInit(cy_stc_usb_dev_context_t *context) +{ + Cy_USBFS_Dev_Drv_DeInit(context->drvBase, context->drvContext); + + /* IDe-initialize all callbacks */ + context->classRoot = NULL; + context->eventsCallback = NULL; + context->getSerialNumString = NULL; + context->vndRequestReceived = NULL; + context->vndRequestCompleted = NULL; +} + + +/******************************************************************************* +* Function Name: HandleTimeout +****************************************************************************//** +* +* Waits for 1 millisecond and returns updated number of milliseconds that remain +* to wait before timeout expires. +* +* \param milliseconds +* Number of milliseconds that remain to wait before timeout expires. +* +* \return +* Updated number of milliseconds remain to wait. +* +*******************************************************************************/ +static int32_t HandleTimeout(int32_t milliseconds) +{ + Cy_SysLib_Delay(1U); /* Wait for 1 millisecond */ + + return (milliseconds - 1); +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_Connect +****************************************************************************//** +* +* Enables pull-up on D+ (hardware supports only full-speed device) line to +* signal USB Device connection on USB Bus. +* +* \param blocking +* Wait until device is configured. +* +* \param timeout +* Defines in milliseconds the time for which this function can block. +* If that time expires, the USB Device is disconnected and the function returns. +* To wait forever, pass \ref CY_USB_DEV_WAIT_FOREVER. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_Connect(bool blocking, int32_t timeout, cy_stc_usb_dev_context_t *context) +{ + /* Returns SUCCESS except timeout when timeout is used */ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_SUCCESS; + + context->state = CY_USB_DEV_POWERED; + Cy_USBFS_Dev_Drv_Enable(context->drvBase, context->drvContext); + + if (blocking) + { + if (CY_USB_DEV_WAIT_FOREVER == timeout) + { + /* Wait until device is configured */ + while (CY_USB_DEV_CONFIGURED != context->state) + { + (void) context->handleTimeout(timeout); + } + } + else + { + /* Wait until device is configured or timeout */ + while ((CY_USB_DEV_CONFIGURED != context->state) && (timeout > 0)) + { + timeout = context->handleTimeout(timeout); + } + + /* Timeout expired disconnect USB Device */ + if (0 == timeout) + { + Cy_USB_Dev_Disconnect(context); + retStatus = CY_USB_DEV_TIMEOUT; + } + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_Disconnect +****************************************************************************//** +* +* Disables pull-up on D+ (hardware supports only full-speed device) line to +* signal USB Device disconnection on USB Bus. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +void Cy_USB_Dev_Disconnect(cy_stc_usb_dev_context_t *context) +{ + Cy_USBFS_Dev_Drv_Disable(context->drvBase, context->drvContext); + + /* Set device in the default state */ + context->state = CY_USB_DEV_DISABLED; + context->configuration = 0U; +} + + +/******************************************************************************* +* Function Name: ConvertEndpointStateToStatus +****************************************************************************//** +* +* Converts endpoint state to the USB Device status code. +* +* \param epState +* Endpoint state cy_en_usb_dev_ep_state_t. +* The state CY_USB_DEV_EP_IDLE converted to \ref CY_USB_DEV_DRV_HW_DISABLED +* to indicate that current endpoint configuration was changed. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t ConvertEndpointStateToStatus(cy_en_usb_dev_ep_state_t epState) +{ + cy_en_usb_dev_status_t retStatus; + + switch(epState) + { + case CY_USB_DEV_EP_COMPLETED: + retStatus = CY_USB_DEV_SUCCESS; + break; + + case CY_USB_DEV_EP_PENDING: + retStatus = CY_USB_DEV_DRV_HW_BUSY; + break; + + case CY_USB_DEV_EP_IDLE: /* Endpoint configuration is changed */ + case CY_USB_DEV_EP_STALLED: + retStatus = CY_USB_DEV_DRV_HW_DISABLED; + break; + + case CY_USB_DEV_EP_INVALID: + case CY_USB_DEV_EP_DISABLED: + retStatus = CY_USB_DEV_BAD_PARAM; + break; + + default: + retStatus = CY_USB_DEV_BAD_PARAM; + break; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_AbortEpTransfer +****************************************************************************//** +* +* Aborts pending read or write endpoint operation. +* If there is any bus activity after abort operation requested the function +* waits for its completion or timeout. The timeout is time to transfer +* bulk or interrupt packet of maximum playload size. If this bus activity is +* a transfer to the aborting endpoint the received data is lost and endpoint +* transfer completion callbacks is not invoked. +* After function returns new read or write endpoint operation can be submitted. +* +* \param endpoint +* The data endpoint number. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +* \note +* The abort operation is not supported for ISOC endpoints because +* these endpoints do not have handshake and are always accessible by the +* USB Host. Therefore, abort can cause unexpected behavior. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_AbortEpTransfer(uint32_t endpoint, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus; + + /* Request abort operation, on exit abort complete */ + retStatus = (cy_en_usb_dev_status_t) Cy_USBFS_Dev_Drv_Abort(context->drvBase, endpoint, context->drvContext); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + retStatus = CY_USB_DEV_DRV_HW_ERROR; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_StartReadEp +****************************************************************************//** +* +* Start a reading on a certain endpoint. +* +* \param endpoint +* The OUT data endpoint number. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +* \note +* The read is not allowed for OUT endpoints after SET_CONFIGURATION or +* SET_INTERFACE request therefore this function must be called before reading data +* from OUT endpoints. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_StartReadEp(uint32_t endpoint, cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus; + cy_en_usb_dev_ep_state_t epState; + + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + + /* Check that endpoint is ready for read operation */ + if ((CY_USB_DEV_EP_IDLE == epState) || (CY_USB_DEV_EP_COMPLETED == epState)) + { + /* Enable endpoint to be written by host */ + Cy_USBFS_Dev_Drv_EnableOutEndpoint(context->drvBase, endpoint, context->drvContext); + + retStatus = CY_USB_DEV_SUCCESS; + } + else + { + /* Use endpoint state to get status */ + retStatus = ConvertEndpointStateToStatus(epState); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_ReadEpBlocking +****************************************************************************//** +* +* Read data received from USB Host from a certain endpoint. Before calling +* this function, \ref Cy_USB_Dev_StartReadEp must be called. +* This function is blocking and returns after successful USB Host transfer, +* or an error or timeout occurred. +* +* \param endpoint +* The OUT data endpoint number. +* +* \param buffer +* The pointer to buffer that stores data that was read. \n +* Allocate buffer using \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro to make +* it USBFS driver configuration independent (See \ref group_usb_dev_ep_buf_alloc +* for more information). +* +* \param size +* The number of bytes to read. +* This value must be less or equal to endpoint maximum packet size. +* +* \param actSize +* The number of bytes that were actually read. +* +* \param timeout +* Defines in milliseconds the time for which this function can block. +* If that time expires the function returns. +* To wait forever pass \ref CY_USB_DEV_WAIT_FOREVER. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_ReadEpBlocking(uint32_t endpoint, uint8_t *buffer, + uint32_t size, uint32_t *actSize, int32_t timeout, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_SUCCESS; + cy_en_usb_dev_ep_state_t epState; + + /* Get endpoint state before check it */ + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + + if (CY_USB_DEV_WAIT_FOREVER == timeout) + { + /* Wait until transfer is completed */ + while (CY_USB_DEV_EP_PENDING == epState) + { + (void) context->handleTimeout(timeout); + + /* Update endpoint state */ + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + } + } + else + { + /* Wait until transfer is completed or for timeout */ + while ((CY_USB_DEV_EP_PENDING == epState) && (timeout > 0)) + { + timeout = context->handleTimeout(timeout); + + /* Update endpoint state */ + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + } + + /* Timeout expired */ + if (0 == timeout) + { + /* Abort write operation */ + (void) Cy_USB_Dev_AbortEpTransfer(endpoint, context); + retStatus = CY_USB_DEV_TIMEOUT; + } + } + + /* Clear actual number of read bytes */ + *actSize = 0U; + + /* Read data from endpoint buffer after completion */ + if (CY_USB_DEV_EP_COMPLETED == epState) + { + retStatus = (cy_en_usb_dev_status_t) + Cy_USBFS_Dev_Drv_ReadOutEndpoint(context->drvBase, + endpoint, buffer, size, actSize, context->drvContext); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + retStatus = CY_USB_DEV_DRV_HW_ERROR; + } + } + + if ((CY_USB_DEV_TIMEOUT != retStatus) && (CY_USB_DEV_DRV_HW_ERROR != retStatus)) + { + /* Use endpoint state to get status */ + retStatus = ConvertEndpointStateToStatus(epState); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_ReadEpNonBlocking +****************************************************************************//** +* +* Read data received from USB Host from a certain endpoint. Before calling +* this function, \ref Cy_USB_Dev_StartReadEp must be called. +* +* \param endpoint +* The OUT data endpoint number. +* +* \param buffer +* The pointer to buffer that stores data that was read. \n +* Allocate buffer using \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro to make +* it USBFS driver configuration independent (See \ref group_usb_dev_ep_buf_alloc +* for more information). +* +* \param size +* The number of bytes to read. +* This value must be less than or equal to endpoint maximum packet size. +* +* \param actSize +* The number of bytes that were actually read. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_ReadEpNonBlocking(uint32_t endpoint, uint8_t *buffer, + uint32_t size, uint32_t *actSize, cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus; + cy_en_usb_dev_ep_state_t epState; + + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + + /* Read data from endpoint buffer after completion */ + if (CY_USB_DEV_EP_COMPLETED == epState) + { + retStatus = (cy_en_usb_dev_status_t) + Cy_USBFS_Dev_Drv_ReadOutEndpoint(context->drvBase, + endpoint, buffer, size, actSize, context->drvContext); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + retStatus = CY_USB_DEV_DRV_HW_ERROR; + } + } + else + { + /* Clear actual number of read bytes */ + *actSize = 0U; + + /* Use endpoint state to get status */ + retStatus = ConvertEndpointStateToStatus(epState); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_WriteEpBlocking +****************************************************************************//** +* +* Write data to be transferred to USB Host from a certain endpoint. +* This function is blocking and returns after successful USB Host transfer, +* or an error or timeout occurred. +* +* \param endpoint +* The IN data endpoint number. +* +* \param buffer +* The pointer to the buffer containing data bytes to write. \n +* Allocate buffer using \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro to make +* it USBFS driver configuration independent (See \ref group_usb_dev_ep_buf_alloc +* for more information). +* +* \param size +* The number of bytes to write. +* This value must be less than or equal to endpoint maximum packet size. +* +* \param timeout +* Defines in milliseconds the time for which this function can block. +* If that time expires, the function returns. +* To wait forever, pass \ref CY_USB_DEV_WAIT_FOREVER. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_WriteEpBlocking(uint32_t endpoint, uint8_t const *buffer, + uint32_t size, int32_t timeout, cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_BAD_PARAM; + cy_en_usb_dev_ep_state_t epState; + + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + + /* Check that endpoint is ready for write operation */ + if ((CY_USB_DEV_EP_IDLE == epState) || (CY_USB_DEV_EP_COMPLETED == epState)) + { + retStatus = (cy_en_usb_dev_status_t) Cy_USBFS_Dev_Drv_LoadInEndpoint(context->drvBase, + endpoint, buffer, size, context->drvContext); + + /* Check endpoint load status */ + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Update endpoint state after load operation */ + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + + if (CY_USB_DEV_WAIT_FOREVER == timeout) + { + /* Wait until transfer is completed */ + while (CY_USB_DEV_EP_PENDING == epState) + { + (void) context->handleTimeout(timeout); + + /* Update endpoint state */ + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + } + } + else + { + /* Wait until transfer is completed or for timeout */ + while ((CY_USB_DEV_EP_PENDING == epState) && (timeout > 0)) + { + timeout = context->handleTimeout(timeout); + + /* Update endpoint state */ + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + } + + /* Timeout expired */ + if (0 == timeout) + { + /* Abort write operation */ + (void) Cy_USB_Dev_AbortEpTransfer(endpoint, context); + retStatus = CY_USB_DEV_TIMEOUT; + } + } + } + else + { + retStatus = CY_USB_DEV_DRV_HW_ERROR; + } + } + + if ((CY_USB_DEV_TIMEOUT != retStatus) && (CY_USB_DEV_DRV_HW_ERROR != retStatus)) + { + /* Use endpoint state to get status */ + retStatus = ConvertEndpointStateToStatus(epState); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_WriteEpNonBlocking +****************************************************************************//** +* +* Write data to be transferred to USB Host from a certain endpoint. +* +* \param endpoint +* The IN data endpoint number. +* +* \param buffer +* The pointer to the buffer containing data bytes to write. \n +* Allocate buffer using \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro to make +* it USBFS driver configuration independent (See \ref group_usb_dev_ep_buf_alloc +* for more information). +* +* \param size +* The number of bytes to write. +* This value must be less than or equal to endpoint maximum packet size. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_WriteEpNonBlocking(uint32_t endpoint, uint8_t const *buffer, + uint32_t size, cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus; + cy_en_usb_dev_ep_state_t epState; + + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + + /* Check that endpoint is ready for operation */ + if ((CY_USB_DEV_EP_IDLE == epState) || (CY_USB_DEV_EP_COMPLETED == epState)) + { + retStatus = (cy_en_usb_dev_status_t) + Cy_USBFS_Dev_Drv_LoadInEndpoint(context->drvBase, + endpoint, buffer, size, context->drvContext); + + /* Write data into the endpoint buffer */ + if (CY_USB_DEV_SUCCESS != retStatus) + + { + retStatus = CY_USB_DEV_DRV_HW_ERROR; + } + } + else + { + retStatus = ConvertEndpointStateToStatus(epState); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: BusResetCallback +****************************************************************************//** +* +* Handles Bus Reset interrupt. +* +* \param base +* The pointer to the USBFS instance. +* +* \param drvContext +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +static void BusResetCallback(USBFS_Type *base, struct cy_stc_usbfs_dev_drv_context *drvContext) +{ + /* Get device context from the driver context */ + cy_stc_usb_dev_context_t *context = (cy_stc_usb_dev_context_t *) Cy_USBFS_Dev_Drv_GetDevContext(base, drvContext); + + /* Get linked list of classes */ + cy_stc_usb_dev_class_ll_item_t *curItem = context->classRoot; + + /* Set device in the DEFAULT state */ + context->state = CY_USB_DEV_DEFAULT; + context->status = 0U; /* Reset remote wakeup and power state */ + context->configuration = 0U; + + /* Notify Bus Reset event for device instance */ + if (NULL != context->eventsCallback) + { + /* Input parameters are zeros. Ignore return for Bus Reset event. */ + (void) context->eventsCallback(CY_USB_DEV_EVENT_BUS_RESET, 0UL, 0UL, context); + } + + /* Notify Bus Reset event for all class instances */ + while (NULL != curItem) + { + if (NULL != curItem->classObj->busReset) + { + /* Execute callback */ + curItem->classObj->busReset(curItem->classData, context); + } + + /* Move to next element */ + curItem = curItem->next; + } +} + + +/******************************************************************************* +* Function Name: DecodeSetupPacket +****************************************************************************//** +* +* Decodes setup packet (populates \ref cy_stc_usb_dev_setup_packet_t). +* +* \param data +* The pointer to buffer with setup packet (raw data). +* +* \param packet +* The pointer to structure that holds setup packet. +* +*******************************************************************************/ +static void DecodeSetupPacket(uint8_t const *data, cy_stc_usb_dev_setup_packet_t *packet) +{ + /* Fill elements of setup packet structure from raw data */ + packet->bmRequestType.direction = (uint8_t) _FLD2VAL(SETUP_RQST_DIR, data[SETUP_RQST_POS]); + packet->bmRequestType.type = (uint8_t) _FLD2VAL(SETUP_RQST_TYPE, data[SETUP_RQST_POS]); + packet->bmRequestType.recipient = (uint8_t) _FLD2VAL(SETUP_RQST_RCPT, data[SETUP_RQST_POS]); + packet->bRequest = (uint8_t) data[SETUP_RQST_TYPE_POS]; + packet->wValue = GET_UINT16(data[SETUP_VALUE_LSB_POS], data[SETUP_VALUE_MSB_POS]); + packet->wIndex = GET_UINT16(data[SETUP_INDEX_LSB_POS], data[SETUP_INDEX_MSB_POS]); + packet->wLength = GET_UINT16(data[SETUP_LENGTH_LSB_POS], data[SETUP_LENGTH_MSB_POS]); +} + + +/******************************************************************************* +* Function Name: HandleSetup +****************************************************************************//** +* +* Handles setup packet received event (generated from Endpoint 0 Interrupt). +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleSetup(cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + cy_stc_usb_dev_control_transfer_t *transfer = &context->ControlTransfer; + + /* Get setup packet from hardware */ + Cy_USBFS_Dev_Drv_Ep0GetSetup(context->drvBase, transfer->buffer, context->drvContext); + + /* Decode setup packet */ + DecodeSetupPacket(transfer->buffer, &transfer->setup); + + /* Prepare for new transfer */ + transfer->ptr = NULL; + transfer->remaining = 0U; + transfer->size = 0U; + transfer->direction = transfer->setup.bmRequestType.direction; + transfer->zlp = false; + transfer->notify = false; + + /* Handle Setup request depends on type */ + switch (transfer->setup.bmRequestType.type) + { + case CY_USB_DEV_STANDARD_TYPE: + case CY_USB_DEV_CLASS_TYPE: + { + if (CY_USB_DEV_STANDARD_TYPE == transfer->setup.bmRequestType.type) + { + /* Handle Standard requests */ + retStatus = HandleStandardRequests(transfer, context); + } + + /* Try handle by Class requests handler */ + if (CY_USB_DEV_SUCCESS != retStatus) + { + retStatus = HandleClassRequests(context->classRoot, transfer, context); + } + } + break; + + case CY_USB_DEV_VENDOR_TYPE: + retStatus = HandleVendorRequests(transfer, context); + break; + + default: + /* Unknown request type: CY_USB_DEV_REQUEST_NOT_HANDLED */ + break; + } + + /* Process standard requests */ + + /* Continue processing if request was handled */ + if (CY_USB_DEV_SUCCESS == retStatus) + { + retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Check transfer setup before continue transfer */ + if (transfer->setup.bmRequestType.direction == transfer->direction) + { + /* Check transfer length */ + if (transfer->setup.wLength > 0U) + { + if (CY_USB_DEV_DIR_DEVICE_TO_HOST == transfer->direction) + { + /* IN data stage is required */ + + /* Transfer must be less than or equal to the size requested by the host */ + if (transfer->remaining > transfer->setup.wLength) + { + transfer->remaining = transfer->setup.wLength; + } + + retStatus = CY_USB_DEV_SUCCESS; + } + else + { + /* OUT data stage is required */ + + /* Transfer must be equal to the size requested by the Host and + * buffer for data must be large enough + */ + if ((transfer->remaining == transfer->setup.wLength) && + (transfer->remaining <= transfer->bufferSize)) + { + retStatus = CY_USB_DEV_SUCCESS; + } + } + } + else + { + /* No data stage: transfer size must be zero */ + if (0U == transfer->remaining) + { + retStatus = CY_USB_DEV_SUCCESS; + } + } + } + + /* Execute transfer if transfer setup correctly */ + if (CY_USB_DEV_SUCCESS == retStatus) + { + if (transfer->setup.wLength > 0U) + { + /* Data or retStatus stage if applicable */ + if (CY_USB_DEV_DIR_DEVICE_TO_HOST == transfer->direction) + { + /* Define whether send zero length packet at the end of transfer */ + if (transfer->setup.wLength > transfer->remaining) + { + /* Transfer is a multiple of EP0 max packet size */ + transfer->zlp = (0U == (transfer->remaining % Cy_USBFS_Dev_Drv_GetEp0MaxPacket(context->drvBase))); + } + + /* Handle data stage (IN direction) */ + (void) HandleIn(context); + } + else + { + /* Set buffer to accept Host data */ + transfer->ptr = transfer->buffer; + + /* Start data stage (OUT direction) */ + (void) Cy_USBFS_Dev_Drv_Ep0Read(context->drvBase, transfer->ptr, (uint32_t) transfer->remaining, context->drvContext); + } + } + else + { + /* No data state: move to status stage (IN direction) */ + (void) Cy_USBFS_Dev_Drv_Ep0Write(context->drvBase, NULL, 0U, context->drvContext); + } + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: HandleIn +****************************************************************************//** +* +* Handles IN packet received event (generated from Endpoint 0 Interrupt). +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleIn(cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + cy_stc_usb_dev_control_transfer_t *transfer = &context->ControlTransfer; + + if (CY_USB_DEV_DIR_DEVICE_TO_HOST == transfer->direction) + { + /* Data stage (direction IN) */ + + /* Send data packet or zero length packet. Skip processing after zero length is sent */ + if (false == ((0U == transfer->remaining) && (!transfer->zlp))) + { + if ((transfer->remaining == 0U) && (transfer->zlp)) + { + /* Zero length packet is send by code below */ + transfer->zlp = false; + } + + /* Write to endpoint 0 */ + uint16_t packetSize = (uint16_t) Cy_USBFS_Dev_Drv_Ep0Write(context->drvBase, + transfer->ptr, + (uint32_t) transfer->remaining, + context->drvContext); + + /* Update transfer */ + transfer->ptr += packetSize; + transfer->remaining -= packetSize; + + /* After last packet has been written move to move to status stage. + * Do not wait for the next IN event because it can be dropped if + * ACK from host is corrupted. + * For more info on this see section 8.5.3.3 of the USB2.0 specification. + * */ + if ((0U == transfer->remaining) && (transfer->zlp == false)) + { + /* Data stage completed: move to status stage (direction OUT) */ + (void) Cy_USBFS_Dev_Drv_Ep0Read(context->drvBase, NULL, 0UL, context->drvContext); + } + } + + retStatus = CY_USB_DEV_SUCCESS; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: HandleOut +****************************************************************************//** +* +* Handles OUT packet received event (generated from Endpoint 0 Interrupt). +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleOut(cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + cy_stc_usb_dev_control_transfer_t *transfer = &context->ControlTransfer; + + if (CY_USB_DEV_DIR_HOST_TO_DEVICE == transfer->direction) + { + /* Control transfer: DATA stage (direction OUT) */ + + /* Read from endpoint 0 */ + uint16_t packetSize = (uint16_t) Cy_USBFS_Dev_Drv_Ep0ReadResult(context->drvBase, context->drvContext); + + /* Check whether transfer size is valid */ + if (packetSize <= transfer->remaining) + { + /* Update transfer counters */ + transfer->ptr += packetSize; + transfer->size += packetSize; + transfer->remaining -= packetSize; + + /* Check whether all bytes received */ + if (transfer->remaining > 0U) + { + /* Continue: there are more bytes to receive */ + Cy_USBFS_Dev_Drv_Ep0Read(context->drvBase, + transfer->ptr, + (uint32_t) transfer->remaining, + context->drvContext); + + retStatus = CY_USB_DEV_SUCCESS; + } + else + { + /* Notify class layer DATA stage completed */ + if (transfer->notify) + { + /* Clear notify and reset buffer pointer */ + transfer->notify = false; + transfer->ptr = transfer->buffer; + + /* Handle Setup request depends on type */ + switch(transfer->setup.bmRequestType.type) + { + case CY_USB_DEV_STANDARD_TYPE: + /* Return CY_USB_DEV_REQUEST_NOT_HANDLED because + * Standard request handler does not use notification. + */ + break; + + case CY_USB_DEV_CLASS_TYPE: + retStatus = HandleClassRequestsCompleted(context->classRoot, transfer, context); + break; + + case CY_USB_DEV_VENDOR_TYPE: + retStatus = HandleVendorRequestsCompleted(transfer, context); + break; + + default: + /* Unknown request type: return CY_USB_DEV_REQUEST_NOT_HANDLED */ + break; + } + } + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Move to STATUS stage (direction IN) */ + (void) Cy_USBFS_Dev_Drv_Ep0Write(context->drvBase, NULL, 0U, context->drvContext); + } + } + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Ep0SetupCallback +****************************************************************************//** +* +* Implements callback for setup received event (generated from Endpoint 0 +* Interrupt). The Endpoint 0 is STALLED if processing was successful. +* +* \param base +* The pointer to the USBFS instance. +* +* \param drvContext +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +static void Ep0SetupCallback(USBFS_Type *base, struct cy_stc_usbfs_dev_drv_context *drvContext) +{ + /* Get device context from the driver context */ + cy_stc_usb_dev_context_t *context = (cy_stc_usb_dev_context_t *) Cy_USBFS_Dev_Drv_GetDevContext(base, drvContext); + + /* Endpoint 0 setup event */ + if (CY_USB_DEV_SUCCESS != HandleSetup(context)) + { + /* Protocol stall */ + Cy_USBFS_Dev_Drv_Ep0Stall(base); + } +} + + +/******************************************************************************* +* Function Name: Ep0InCallback +****************************************************************************//** +* +* Implements callback for IN packet received event (generated from Endpoint 0 +* Interrupt). The Endpoint 0 is STALLED if processing was successful. +* +* \param base +* The pointer to the USBFS instance. +* +* \param drvContext +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +static void Ep0InCallback(USBFS_Type *base, struct cy_stc_usbfs_dev_drv_context *drvContext) +{ + /* Get device context from the driver context */ + cy_stc_usb_dev_context_t *context = (cy_stc_usb_dev_context_t *) Cy_USBFS_Dev_Drv_GetDevContext(base, drvContext); + + /* Endpoint 0 IN packet received event */ + if (CY_USB_DEV_SUCCESS != HandleIn(context)) + { + /* Protocol stall */ + Cy_USBFS_Dev_Drv_Ep0Stall(base); + } +} + + +/******************************************************************************* +* Function Name: Ep0OutCallback +****************************************************************************//** +* +* Implements callback for OUT packet received event (generated from Endpoint 0 +* Interrupt). The Endpoint 0 is STALLED if processing was successful. +* +* \param base +* The pointer to the USBFS instance. +* +* \param drvContext +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +static void Ep0OutCallback(USBFS_Type *base, struct cy_stc_usbfs_dev_drv_context *drvContext) +{ + /* Get device context from the driver context */ + cy_stc_usb_dev_context_t *context = (cy_stc_usb_dev_context_t *) Cy_USBFS_Dev_Drv_GetDevContext(base, drvContext); + + /* Endpoint 0 OUT packet received */ + if (CY_USB_DEV_SUCCESS != HandleOut(context)) + { + /* Protocol stall */ + Cy_USBFS_Dev_Drv_Ep0Stall(base); + } +} + +#if defined(CY_IP_MXUSBFS) +/******************************************************************************* +* Function Name: InitSerialNumberString +****************************************************************************//** +* +* Initializes serial number string using silicon ID. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +static void InitSerialNumberString(cy_stc_usb_dev_context_t *context) +{ + const uint8_t hex[] = "0123456789ABCDEF"; + uint8_t *strDescr = context->serialNumDescr; + uint8_t *id; + uint32_t i = 0U; + uint32_t j = 0U; + uint64_t tmp; + + /* Place header: length and type */ + strDescr[STRING_DESCR_LENGTH_POS] = CY_USB_DEV_SN_STRING_DESR_LENGTH; + strDescr[STRING_DESCR_TYPE_POS] = CY_USB_DEV_STRING_DESCR; + + /* Get unique ID - 8 bytes */ + tmp = Cy_SysLib_GetUniqueId(); + + /* Get start address of uint64_t */ + id = (uint8_t *) &tmp; + + /* Fill descriptor using unique silicon ID */ + for (i = 2U; i < CY_USB_DEV_SN_STRING_DESR_LENGTH; i += 4U) + { + strDescr[i + 0U] = hex[(id[j] & 0x0FU)]; + strDescr[i + 1U] = 0U; + strDescr[i + 2U] = hex[(id[j] >> 4U)]; + strDescr[i + 3U] = 0U; + ++j; + } +} +#endif /* defined(CY_IP_MXUSBFS) */ + +/******************************************************************************* +* Function Name: GetDescriptorRequest +****************************************************************************//** +* +* Handles GET_DESCRIPTOR standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetDescriptorRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + switch (CY_USB_DEV_GET_DESCR_TYPE(transfer->setup.wValue)) + { + case CY_USB_DEV_DEVICE_DESCR: + { + /* Return device descriptor */ + transfer->ptr = (uint8_t *) context->devDescriptors->deviceDescriptor; + transfer->remaining = CY_USB_DEV_DEVICE_DESCR_LENGTH; + + retStatus = CY_USB_DEV_SUCCESS; + } + break; + + case CY_USB_DEV_CONFIG_DESCR: + { + /* Get configuration index */ + uint32_t idx = CY_USB_DEV_GET_DESCR_IDX(transfer->setup.wValue); + + /* Check whether requested configuration descriptor exists */ + if (idx < context->devDescriptors->numConfigurations) + { + uint8_t *configDescr = (uint8_t *) context->devDescriptors->configurations[idx]->configDescriptor; + + /* Return configuration descriptor */ + transfer->ptr = configDescr; + transfer->remaining = GET_UINT16(configDescr[CONFIG_DESCR_LENGTH_LSB_POS], + configDescr[CONFIG_DESCR_LENGTH_MSB_POS]); + + retStatus = CY_USB_DEV_SUCCESS; + } + } + break; + + case CY_USB_DEV_BOS_DESCR: + { + uint8_t *bosDescr = (uint8_t *) context->devDescriptors->bosDescriptor; + + /* Check if BOS descriptor exists */ + if (NULL != bosDescr) + { + /* Return BOS descriptor */ + transfer->ptr = bosDescr; + transfer->remaining = GET_UINT16(bosDescr[BOS_DESCR_LENGTH_LSB_POS], + bosDescr[BOS_DESCR_LENGTH_MSB_POS]); + + retStatus = CY_USB_DEV_SUCCESS; + } + } + break; + + case CY_USB_DEV_STRING_DESCR: + { + uint8_t *strDescr = NULL; + + /* Get string index */ + uint32_t idx = CY_USB_DEV_GET_DESCR_IDX(transfer->setup.wValue); + + /* Get pool of strings */ + cy_stc_usb_dev_string_t const *descr = context->devDescriptors->strings; + + /* Special case: Microsoft OS Descriptors String descriptor */ + if (idx == STRING_IMSOS_INDEX) + { + if (NULL != descr->osStringDescriptors) + { + /* Get string */ + strDescr = (uint8_t *) descr->osStringDescriptors->msOsDescriptor; + + retStatus = CY_USB_DEV_SUCCESS; + } + } + /* Other string descriptors (included serial number string) */ + else + { + /* Check that string exists */ + if ((NULL != descr->stringDescriptors) && (descr->numStrings > 0U) && (idx < descr->numStrings)) + { + /* Get string from descriptors */ + strDescr = (uint8_t *) descr->stringDescriptors[idx]; + + /* Check whether requested string is serial number */ + if ((idx != STRING_LANGID_INDEX) && + (idx == context->devDescriptors->deviceDescriptor[DEVICE_DESCR_ISN_STRING_POS])) + { + /* Check options for serial string */ + if (strDescr != NULL) + { + /* Serial number is part of device descriptor */ + retStatus = CY_USB_DEV_SUCCESS; + } + else + { + if (context->getSerialNumString != NULL) + { + /* Get serial number using callback */ + strDescr = context->getSerialNumString(); + if (strDescr != NULL) + { + retStatus = CY_USB_DEV_SUCCESS; + } + } + else + { + /* Get serial number using silicon ID */ + strDescr = &context->serialNumDescr[0]; + retStatus = CY_USB_DEV_SUCCESS; + } + } + } + else + { + retStatus = CY_USB_DEV_SUCCESS; + } + } + } + + /* Return string if it was found */ + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* User defined descriptor */ + transfer->ptr = strDescr; + transfer->remaining = strDescr[STRING_DESCR_LENGTH_POS]; + } + } + break; + + case CY_USB_DEV_INTERFACE_DESCR: + case CY_USB_DEV_ENDPOINT_DESCR: + /* These descriptor types are not supported */ + break; + + default: + /* The descriptor type was not recognized */ + break; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: GetConfigurationRequest +****************************************************************************//** +* +* Handles SET_CONFIGURATION standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetConfigurationRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context) +{ + /* Send the device configuration */ + transfer->ptr = (uint8_t *) &context->configuration; + transfer->remaining = (uint16_t)sizeof(context->configuration); + + return CY_USB_DEV_SUCCESS; +} + + +/******************************************************************************* +* Function Name: GetInterfaceRequest +****************************************************************************//** +* +* Handles GET_INTERFACE standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetInterfaceRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + uint32_t interface = transfer->setup.wIndex; + + if (CY_USB_DEV_CONFIGURED != context->state) + { + return CY_USB_DEV_REQUEST_NOT_HANDLED; + } + + /* Check whether interface exists in current configuration */ + if (interface < context->devDescriptors->configurations[VAL2IDX(context->configuration)]->numInterfaces) + { + /* Return current alternate setting for an interface */ + transfer->ptr = (uint8_t *) &context->alternate[interface]; + transfer->remaining = (uint16_t)sizeof(context->alternate[interface]); + + retStatus = CY_USB_DEV_SUCCESS; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: GetStatusRequest +****************************************************************************//** +* +* Handles GET_STATUS standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetStatusRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t const *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + uint16_t response; + + /* Endpoint or interface must be zero if device is not configured */ + if (context->state != CY_USB_DEV_CONFIGURED) + { + if (0U != transfer->setup.wIndex) + { + return CY_USB_DEV_REQUEST_NOT_HANDLED; + } + } + + /* Find request recipient */ + switch (transfer->setup.bmRequestType.recipient) + { + case CY_USB_DEV_RECIPIENT_DEVICE: + { + /* Return device status: powered or remote wakeup */ + response = (uint16_t) context->status; + retStatus = CY_USB_DEV_SUCCESS; + } + break; + + case CY_USB_DEV_RECIPIENT_INTERFACE: + { + /* All status bits are Reserved (Reset to zero) */ + response = 0U; + retStatus = CY_USB_DEV_SUCCESS; + } + break; + + case CY_USB_DEV_RECIPIENT_ENDPOINT: + { + uint32_t endpoint = CY_USB_DEV_EPADDR2EP(transfer->setup.wIndex); + + cy_en_usb_dev_ep_state_t epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, endpoint, context->drvContext); + + /* Check that valid endpoint is requested */ + if ((CY_USB_DEV_EP_INVALID != epState) && (CY_USB_DEV_EP_DISABLED != epState)) + { + /* Get endpoint state */ + response = (CY_USB_DEV_EP_STALLED == epState) ? CY_USB_DEV_ENDPOINT_STATUS_HALT : 0U; + retStatus = CY_USB_DEV_SUCCESS; + } + } + break; + + default: + { + /* Do nothing. */ + break; + } + } + + /* Put response into the buffer */ + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Send the status to host */ + transfer->buffer[0U] = CY_LO8(response); + transfer->buffer[1U] = CY_HI8(response); + + transfer->ptr = transfer->buffer; + transfer->remaining = (uint16_t)sizeof(response); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: ClearFeatureRequest +****************************************************************************//** +* +* Handles CLEAR_FEATURE standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t ClearFeatureRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Endpoint or interface must be zero if device is not configured */ + if (context->state != CY_USB_DEV_CONFIGURED) + { + if (transfer->setup.wIndex != 0U) + { + return CY_USB_DEV_REQUEST_NOT_HANDLED; + } + } + + /* Find request recipient */ + switch (transfer->setup.bmRequestType.recipient) + { + case CY_USB_DEV_RECIPIENT_DEVICE: + { + /* Check feature selector: TEST_MODE is not supported */ + if (transfer->setup.wValue == CY_USB_DEV_DEVICE_REMOTE_WAKEUP) + { + context->status &= (uint8_t) ~CY_USB_DEV_STATUS_REMOTE_WAKEUP_MASK; + + retStatus = CY_USB_DEV_SUCCESS; + } + } + break; + + case CY_USB_DEV_RECIPIENT_INTERFACE: + /* There is no feature selector this recipient */ + break; + + case CY_USB_DEV_RECIPIENT_ENDPOINT: + { + /* Check that feature selector is ENDPOINT_HALT */ + if (transfer->setup.wValue == CY_USB_DEV_ENDPOINT_HALT) + { + uint32_t endpoint = CY_USB_DEV_EPADDR2EP(transfer->setup.wIndex); + + /* Only enabled and data endpoints can be STALLED */ + retStatus = (cy_en_usb_dev_status_t) + Cy_USBFS_Dev_Drv_UnStallEndpoint(context->drvBase, + endpoint, context->drvContext); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + } + } + } + break; + + default: + /* Unknown recipient */ + break; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: SetAddressRequest +****************************************************************************//** +* +* Handles SET_ADDRESS standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t SetAddressRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context) +{ + uint8_t devAddress = CY_LO8(transfer->setup.wValue); + + /* Request to change address after status status */ + Cy_USBFS_Dev_Drv_SetAddress(context->drvBase, devAddress, context->drvContext); + + /* Set device state depends on address value */ + context->state = (0U != devAddress) ? CY_USB_DEV_ADDRESSED : CY_USB_DEV_DEFAULT; + + return CY_USB_DEV_SUCCESS; +} + + +/******************************************************************************* +* Function Name: ConfigureDataEndpoints +****************************************************************************//** +* +* Configures data endpoints that belong to a certain configuration. +* +* \param config +* Configuration index (configuration value - 1). +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of executed operation \ref cy_en_usb_dev_status_t. +* CY_USB_DEV_SUCCESS is returned if no data endpoints are to be configured. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t ConfigureDataEndpoints(uint32_t config, cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_SUCCESS; + + uint32_t intf, alt, ep; + + uint32_t numIntr = context->devDescriptors->configurations[config]->numInterfaces; + cy_stc_usb_dev_interface_t const **descr = context->devDescriptors->configurations[config]->interfaces; + + /* Go through all interfaces that belong to configuration */ + for (intf = 0U; intf < numIntr; ++intf) + { + uint32_t mask = context->devDescriptors->configurations[config]->interfaces[intf]->endpointsMask; + uint32_t endpoint = 1UL; + + /* Use mask to find only endpoints that belong to interface */ + while (0U != mask) + { + /* Configure enabled endpoint */ + if (0U != (mask & 0x01U)) + { + bool configured = false; + + cy_stc_usb_dev_ep_config_t epConfig = {0}; + + epConfig.enableEndpoint = false; + epConfig.allocBuffer = true; + + /* Go through all alternate */ + for (alt = 0U; alt < descr[intf]->numAlternates; ++alt) + { + /* Go thorough all endpoints that belong to alternate */ + for (ep = 0U; ep < descr[intf]->alternates[alt]->numEndpoints; ++ep) + { + cy_stc_usbdev_endpoint_descr_t const *epDescr = (cy_stc_usbdev_endpoint_descr_t const *) ((const void *)(descr[intf]->alternates[alt]->endpoints[ep]->endpointDescriptor)); + + /* Find endpoint that needs to be configured */ + if (CY_USB_DEV_EPADDR2EP(epDescr->bEndpointAddress) == endpoint) + { + if (false == configured) + { + /* Enable endpoint that belongs to alternate 0 */ + if (0U == alt) + { + epConfig.enableEndpoint = true; + } + + /* Initialize endpoint configuration structure */ + epConfig.endpointAddr = epDescr->bEndpointAddress; + epConfig.attributes = epDescr->bmAttributes; + epConfig.maxPacketSize = GET_CFG_WORD(&epDescr->wMaxPacketSize); + epConfig.bufferSize = GET_CFG_WORD(&epDescr->wMaxPacketSize); + + /* Set configuration of the 1st endpoint instance */ + configured = true; + } + else + { + /* Find maximum packet size for this endpoint in all alternates */ + if (epConfig.bufferSize < GET_CFG_WORD(&epDescr->wMaxPacketSize)) + { + epConfig.bufferSize = GET_CFG_WORD(&epDescr->wMaxPacketSize); + } + } + + break; + } + } + } + + /* Add endpoint */ + retStatus = (cy_en_usb_dev_status_t) + Cy_USBFS_Dev_Drv_AddEndpoint(context->drvBase, + &epConfig, context->drvContext); + + /* Check operation result */ + if (CY_USB_DEV_SUCCESS != retStatus) + { + retStatus = CY_USB_DEV_DRV_HW_ERROR; + break; + } + } + + mask >>= 1U; + ++endpoint; + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: SetConfigurationRequest +****************************************************************************//** +* +* Handles SET_CONFIGURATION standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t SetConfigurationRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + uint32_t config = (uint32_t) transfer->setup.wValue; + + if (0U == config) + { + /* Disable all data endpoints */ + Cy_USBFS_Dev_Drv_UnConfigureDevice(context->drvBase, context->drvContext); + + /* Store configuration and move to configured state */ + context->configChanged = true; + context->configuration = (uint8_t) config; + context->state = CY_USB_DEV_ADDRESSED; + + retStatus = CY_USB_DEV_SUCCESS; + } + else + { + /* Check whether configuration is valid */ + if (config <= context->devDescriptors->numConfigurations) + { + uint32_t configIdx = VAL2IDX(config); + + /* Clear context fields that keep configuration related data */ + (void) memset((void *) context->alternate, 0, CY_USB_DEV_NUM_INTERFACES_MAX); + + /* Set device endpoints into the default state before configure them */ + Cy_USBFS_Dev_Drv_UnConfigureDevice(context->drvBase, context->drvContext); + + /* Configure endpoints */ + retStatus = ConfigureDataEndpoints(configIdx, context); + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Notify Bus Reset event for device instance */ + if (NULL != context->eventsCallback) + { + /* Input parameters are zeros. Ignore return for Bus Reset event. */ + retStatus = context->eventsCallback(CY_USB_DEV_EVENT_SET_CONFIG, config, 0UL, context); + } + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Get linked list of classes */ + cy_stc_usb_dev_class_ll_item_t *curItem = context->classRoot; + + /* Call Set Configuration callback for all class instances */ + while (NULL != curItem) + { + if (NULL != curItem->classObj->setConfiguration) + { + /* Execute callback */ + retStatus = curItem->classObj->setConfiguration(config, curItem->classData, context); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + /* Operation failed break the loop */ + break; + } + } + + /* Move to next element */ + curItem = curItem->next; + } + } + } + + if (CY_USB_DEV_SUCCESS == retStatus) + { + const uint32_t attribute = context->devDescriptors->configurations[configIdx]->configDescriptor[CONFIG_DESCR_ATTRIB_POS]; + + /* Complete device configuration (endpoints were configured) */ + Cy_USBFS_Dev_Drv_ConfigDevice(context->drvBase, context->drvContext); + + /* Set power status (remote wakeup status was cleared on bus reset) */ + if (0U != (attribute & CONFIG_ATTR_SELF_POWERED_MASK)) + { + context->status |= (uint8_t) CY_USB_DEV_STATUS_SELF_POWERED_MASK; + } + else + { + context->status &= (uint8_t) ~CY_USB_DEV_STATUS_SELF_POWERED_MASK; + } + + /* Store configuration and move to configured state */ + context->configChanged = true; + context->configuration = (uint8_t) config; + context->state = CY_USB_DEV_CONFIGURED; + } + else + { + /* Set configuration failed, remain in current state */ + Cy_USBFS_Dev_Drv_UnConfigureDevice(context->drvBase, context->drvContext); + + retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + } + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: InterfaceRemoveDataEndpoints +****************************************************************************//** +* +* Disables data endpoints that belong to a certain interface. +* +* \param numEndpoints +* The number of data endpoints. +* +* \param epsPool +* The pointer to pointer to the array of the endpoints. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of executed operation \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t InterfaceRemoveDataEndpoints(uint32_t numEndpoints, + cy_stc_usb_dev_endpoint_t const * const *epsPool, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + uint32_t endpoint; + + if (0U == numEndpoints) + { + /* Interface with zero endpoints return success */ + return CY_USB_DEV_SUCCESS; + } + + /* Remove endpoints that are available in pool */ + for (endpoint = 0UL; endpoint < numEndpoints; ++endpoint) + { + /* Get endpoint parsed endpoint descriptor */ + cy_stc_usbdev_endpoint_descr_t const *epDescr = (cy_stc_usbdev_endpoint_descr_t const *)((const void *) (epsPool[endpoint]->endpointDescriptor)); + + /* Remove endpoint */ + retStatus = (cy_en_usb_dev_status_t) + Cy_USBFS_Dev_Drv_RemoveEndpoint(context->drvBase, (uint32_t) epDescr->bEndpointAddress, + context->drvContext); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + /* Remove operation failed */ + retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + break; + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: InterfaceAddDataEndpoints +****************************************************************************//** +* +* Configures data endpoints that belong to a certain interface to operate. +* +* \param numEndpoints +* The number of data endpoints. +* +* \param epsPool +* The pointer to pointer to the array of the endpoints. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t InterfaceAddDataEndpoints(uint32_t numEndpoints, + cy_stc_usb_dev_endpoint_t const *const *epsPool, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + uint32_t endpoint; + + if (0U == numEndpoints) + { + /* Interface with zero endpoints return success */ + return CY_USB_DEV_SUCCESS; + } + + /* Add endpoints that are available the pool */ + for (endpoint = 0UL; endpoint < numEndpoints; ++endpoint) + { + cy_stc_usbdev_endpoint_descr_t const *epDescr = (cy_stc_usbdev_endpoint_descr_t const *)((const void *) (epsPool[endpoint]->endpointDescriptor)); + cy_stc_usb_dev_ep_config_t epConfig; + + /* Setup configuration structure */ + epConfig.allocBuffer = false; + epConfig.enableEndpoint = true; + epConfig.endpointAddr = epDescr->bEndpointAddress; + epConfig.attributes = epDescr->bmAttributes; + epConfig.maxPacketSize = GET_CFG_WORD(&epDescr->wMaxPacketSize); + + /* Add endpoint */ + retStatus = (cy_en_usb_dev_status_t) + Cy_USBFS_Dev_Drv_AddEndpoint(context->drvBase, &epConfig, + context->drvContext); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + /* Add operation failed */ + retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + break; + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: CallSetInterfaceCallbacks +****************************************************************************//** +* +* Calls Class callbacks for SET_INTERFACE standard request. +* +* \param interface +* The interface number. +* +* \param alternate +* The alternate setting for the interface. +* +* \param curItem +* The pointer to class linked list element. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t CallSetInterfaceCallbacks(uint32_t interface, + uint32_t alternate, + cy_stc_usb_dev_class_ll_item_t *curItem, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_SUCCESS; + + /* Call registered Set Interface callbacks for all class instances */ + while (NULL != curItem) + { + /* Execute callback */ + if (NULL != curItem->classObj->setInterface) + { + retStatus = curItem->classObj->setInterface(interface, alternate, + curItem->classData, context); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + break; + } + } + + /* Move to next element */ + curItem = curItem->next; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: SetInterfaceRequest +****************************************************************************//** +* +* Handles SET_INTERFACE standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t SetInterfaceRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + uint32_t cfg = (uint32_t) VAL2IDX(context->configuration); + uint32_t intf = (uint32_t) transfer->setup.wIndex; + uint32_t alt = (uint32_t) transfer->setup.wValue; + + /* Not supported when configuration is set */ + if (CY_USB_DEV_CONFIGURED != context->state) + { + return CY_USB_DEV_REQUEST_NOT_HANDLED; + } + + /* Check whether interface exists */ + if (intf < context->devDescriptors->configurations[cfg]->numInterfaces) + { + /* Check whether alternate for this interface exists */ + if (alt < context->devDescriptors->configurations[cfg]->interfaces[intf]->numAlternates) + { + /* Get pointer to interface descriptor structure */ + const cy_stc_usb_dev_interface_t *descr = context->devDescriptors->configurations[cfg]->interfaces[intf]; + + /* If alternate settings are not changed, do nothing with current alternate */ + if (alt != context->alternate[intf]) + { + /* Remove endpoints used by current alternate (old) */ + uint32_t altOld = context->alternate[intf]; + + retStatus = InterfaceRemoveDataEndpoints((uint32_t) descr->alternates[altOld]->numEndpoints, + (cy_stc_usb_dev_endpoint_t const * const *) descr->alternates[altOld]->endpoints, + context); + + /* Add endpoints used by new alternate (received) */ + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Add endpoints used by new alternate (received) */ + retStatus = InterfaceAddDataEndpoints((uint32_t) descr->alternates[alt]->numEndpoints, + (cy_stc_usb_dev_endpoint_t const * const *) descr->alternates[alt]->endpoints, + context); + } + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Notify Bus Reset event for device instance */ + if (NULL != context->eventsCallback) + { + /* Input parameters are zeros. Ignore return for Bus Reset event. */ + retStatus = context->eventsCallback(CY_USB_DEV_EVENT_SET_INTERFACE, alt, intf, context); + } + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Call Set Interface callbacks for a Class */ + retStatus = CallSetInterfaceCallbacks(intf, alt, context->classRoot, context); + } + } + + /* Check request complete status */ + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Store current alternate settings */ + context->configChanged = true; + context->alternate[intf] = (uint8_t) alt; + } + } + else + { + /* Do nothing: current alternate is already set */ + retStatus = CY_USB_DEV_SUCCESS; + } + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: SetFeatureRequest +****************************************************************************//** +* +* Handles SET_FEATURE standard request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t SetFeatureRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Endpoint or interface must be zero if device is not configured */ + if (CY_USB_DEV_CONFIGURED != context->state) + { + if (0U != transfer->setup.wIndex) + { + return CY_USB_DEV_REQUEST_NOT_HANDLED; + } + } + + /* Find request recipient */ + switch (transfer->setup.bmRequestType.recipient) + { + case CY_USB_DEV_RECIPIENT_DEVICE: + { + /* Check feature selector: TEST_MODE is not supported */ + if (CY_USB_DEV_DEVICE_REMOTE_WAKEUP == transfer->setup.wValue) + { + context->status |= CY_USB_DEV_STATUS_REMOTE_WAKEUP_MASK; + retStatus = CY_USB_DEV_SUCCESS; + } + } + break; + + case CY_USB_DEV_RECIPIENT_INTERFACE: + /* There is no feature selector this recipient */ + break; + + case CY_USB_DEV_RECIPIENT_ENDPOINT: + { + /* Check that feature selector is ENDPOINT_HALT */ + if (CY_USB_DEV_ENDPOINT_HALT == transfer->setup.wValue) + { + uint32_t endpoint = CY_USB_DEV_EPADDR2EP(transfer->setup.wIndex); + + /* Only enabled and data endpoints can be STALLED */ + retStatus = (cy_en_usb_dev_status_t) + Cy_USBFS_Dev_Drv_StallEndpoint(context->drvBase, + endpoint, context->drvContext); + + if (CY_USB_DEV_SUCCESS != retStatus) + { + retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + } + } + } + break; + + default: + /* Unknown recipient */ + break; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: HandleStandardRequests +****************************************************************************//** +* +* Handles supported standard requests. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleStandardRequests(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Direction is Device to Host: DATA stage direction is IN */ + if (CY_USB_DEV_DIR_DEVICE_TO_HOST == transfer->direction) + { + switch (transfer->setup.bRequest) + { + case CY_USB_DEV_RQST_GET_DESCRIPTOR: + retStatus = GetDescriptorRequest(transfer, context); + break; + + case CY_USB_DEV_RQST_GET_CONFIGURATION: + retStatus = GetConfigurationRequest(transfer, context); + break; + + case CY_USB_DEV_RQST_GET_INTERFACE: + retStatus = GetInterfaceRequest(transfer, context); + break; + + case CY_USB_DEV_RQST_GET_STATUS: + retStatus = GetStatusRequest(transfer, context); + break; + + default: + /* Do nothing. */ + break; + } + } + /* Direction is Host to Device: DATA stage direction is OUT or no DATA stage */ + else + { + switch (transfer->setup.bRequest) + { + case CY_USB_DEV_RQST_SET_ADDRESS: + retStatus = SetAddressRequest(transfer, context); + break; + + case CY_USB_DEV_RQST_SET_DESCRIPTOR: + /* This request is optional and not supported */ + break; + + case CY_USB_DEV_RQST_SET_CONFIGURATION: + retStatus = SetConfigurationRequest(transfer, context); + break; + + case CY_USB_DEV_RQST_SET_INTERFACE: + retStatus = SetInterfaceRequest(transfer, context); + break; + + case CY_USB_DEV_RQST_CLEAR_FEATURE: + retStatus = ClearFeatureRequest(transfer, context); + break; + + case CY_USB_DEV_RQST_SET_FEATURE: + retStatus = SetFeatureRequest(transfer, context); + break; + + default: + /* Do nothing. */ + break; + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: HandleClassRequests +****************************************************************************//** +* +* Handles supported class requests. +* +* \param curItem +* The pointer to class linked list element. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleClassRequests(cy_stc_usb_dev_class_ll_item_t *curItem, + cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Call Request Received callback for all class instances */ + while (NULL != curItem) + { + /* Execute callback */ + if (NULL != curItem->classObj->requestReceived) + { + retStatus = curItem->classObj->requestReceived(transfer, curItem->classData, context); + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Request is handled, exit loop */ + break; + } + } + + /* Move to next element */ + curItem = curItem->next; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: HandleClassRequestsComplete +****************************************************************************//** +* +* Handles supported class requests completion stage (data was +* received from the USB Host). +* +* \param curItem +* The pointer to class linked list element. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleClassRequestsCompleted(cy_stc_usb_dev_class_ll_item_t *curItem, + cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Call Request Complete callback for all class instances */ + while (NULL != curItem) + { + /* Execute callback */ + if (NULL != curItem->classObj->requestCompleted) + { + retStatus = curItem->classObj->requestCompleted(transfer, curItem->classData, context); + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* Request is handled, exit loop */ + break; + } + } + + /* Move to next element */ + curItem = curItem->next; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: GetExtOsStringDescriptors +****************************************************************************//** +* +* Handles supported vendor-specific requests. +* +* \param msOsString +* The pointer to the MS OS String structure \ref cy_stc_usb_dev_ms_os_string_t. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetExtOsStringDescriptors(cy_stc_usb_dev_ms_os_string_t const *msOsString, + cy_stc_usb_dev_control_transfer_t *transfer) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Direction is Device to Host: DATA stage direction is IN */ + if (CY_USB_DEV_DIR_DEVICE_TO_HOST == transfer->direction) + { + if (transfer->setup.bRequest == msOsString->msVendorCode) + { + switch(transfer->setup.wIndex) + { + case CY_USB_DEV_MS_OS_STRING_EXT_COMPAT_ID: + case CY_USB_DEV_MS_OS_STRING_EXT_PROPERTEIS: + { + /* Get Extended Compat ID / Properties OS Descriptor (ignores wValue) */ + uint8_t *strDescr = (uint8_t *) ((CY_USB_DEV_MS_OS_STRING_EXT_COMPAT_ID == transfer->setup.wIndex) ? + msOsString->extCompatIdDescriptor : msOsString->extPropertiesDescriptor); + + if (NULL != strDescr) + { + transfer->ptr = strDescr; + transfer->remaining = GET_UINT16(strDescr[EXT_OS_DESC_LENGTH_BYTE0_POS], + strDescr[EXT_OS_DESC_LENGTH_BYTE1_POS]); + + retStatus = CY_USB_DEV_SUCCESS; + } + } + break; + + default: + /* Do nothing. */ + break; + } + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: HandleVendorRequests +****************************************************************************//** +* +* Handles supported vendor-specific requests. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleVendorRequests(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Get pointer to MS OS String descriptor structure */ + const cy_stc_usb_dev_ms_os_string_t *msOsString = context->devDescriptors->strings->osStringDescriptors; + + if (NULL != msOsString) + { + retStatus = GetExtOsStringDescriptors(msOsString, transfer); + } + + if ((CY_USB_DEV_SUCCESS != retStatus) && (NULL != context->vndRequestReceived)) + { + /* There is no classContext for vendor-specific callbacks */ + retStatus = context->vndRequestReceived(transfer, NULL, context); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: HandleVendorRequestsComplete +****************************************************************************//** +* +* Handles supported vendor-specific requests completion stage (data was +* received from the USB Host). +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleVendorRequestsCompleted(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + if (NULL != context->vndRequestCompleted) + { + /* There is no classContext for vendor-specific callbacks */ + retStatus = context->vndRequestCompleted(transfer, NULL, context); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterClass +****************************************************************************//** +* +* Registers device class that will be supported by USB Device. +* The USB Device provides a hooks to implement required class support. +* +* \param classItem +* The pointer to class linked list element. +* +* \param classObj +* The pointer to the class structure. +* +* \param classContext +* The pointer to the context class structure allocated by the user. +* The structure is used during the custom class operation for internal +* configuration and data retention. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_RegisterClass(cy_stc_usb_dev_class_ll_item_t *classItem, + cy_stc_usb_dev_class_t *classObj, + void *classContext, + cy_stc_usb_dev_context_t *context) +{ + if ((NULL == classItem) || (NULL == classObj)) + { + return CY_USB_DEV_BAD_PARAM; + } + + /* Get linked list of classes */ + cy_stc_usb_dev_class_ll_item_t *curItem = context->classRoot; + + /* Store data members */ + classItem->classObj = classObj; + classItem->classData = classContext; + classItem->next = NULL; + + if (NULL == curItem) + { + /* Add 1st element */ + context->classRoot = classItem; + } + else + { + /* Find last element */ + while (NULL != curItem->next) + { + curItem = curItem->next; + } + + /* Add current item to the end of the list */ + curItem->next = classItem; + } + + return CY_USB_DEV_SUCCESS; +} + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev.h new file mode 100644 index 0000000000000000000000000000000000000000..f2d82e1562e2bb3a634a1531ecc92814996d3608 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev.h @@ -0,0 +1,1953 @@ +/***************************************************************************//** +* \file cy_usb_dev.h +* \version 2.10 +* +* Provides API declarations of the USBFS device middleware. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + + +/** +* \mainpage USB Device Middleware Library 2.10 +* +* The USB Device middleware provides a full-speed USB 2.0 Chapter 9 specification +* -compliant device framework. It uses the USBFS driver from PDL to interface +* with the hardware. The middleware provides support for Audio, CDC, and HID +* classes. Also, it allows implementing other class support. +* The USB Configurator tool makes it easy to construct the USB +* Device descriptor. +* +* Features: +* * USB Full-Speed Device Framework +* * \ref group_usb_dev_cfg_tool +* * The following USB Classes are supported: +* * \ref group_usb_dev_audio_class_info +* * \ref group_usb_dev_cdc_class_info +* * \ref group_usb_dev_hid_class_info +* +******************************************************************************** +* \section section_usb_dev_general General Description +******************************************************************************** +* +* The USB Device structure is divided into layers. The implementation +* is event-driven: the USBFS driver receives interrupts from the hardware and +* provides callbacks to the USB Device layer which implements them and provides +* events to the Class layer. A simplified image is shown below. \n \n +* \image html usb_dev_solution_struct.png +* +* Include cy_usb_dev.h along with the header for the USB class to be used +* (cy_usb_dev_hid.h, cy_usb_dev_cdc.h, cy_usb_dev_audio.h) to get access to +* all the functions and other declarations in this library. +* If you use ModusToolbox USB Device Configurator, also include cycfg_usbdev.h. +* +******************************************************************************** +* \section section_usb_dev_quick_start Quick Start Guide +******************************************************************************** +* +* Cypress USB Device middleware can be used in various software environments. +* Refer to the \ref section_usb_dev_toolchain. +* The quickest way to get started is using the Code Examples. +* Cypress Semiconductor continuously extends its portfolio of code examples +* at Cypress Semiconductor website +* and at +* Cypress Semiconductor GitHub. +* +* This quick start guide is for an environment configured to use for development +* MTB CAT1A Peripheral Driver Library (PSoC6) or MTB CAT2 Peripheral Driver Library +* (PSoC4 & PMG1) included in the project. +* +* To easily run a USB, use the ModusToolbox USBCommDevice or USBM project. +* The steps below show how to set up a USB Device based on a basic +* ModusToolbox project (like Hello_World). +* +* The following steps set up a USB device recognized as an standard HID device - +* USB mouse and moves it from right to the left, and vice-versa. +* \note Some steps contain a corresponding to the figure below number in +* brackets. +* +* \subsection subsection_qsg_step1 STEP 1: Enable the USB Device middleware. +* +* Launch ModusToolbox Library Manager and enable the USB Device middleware. +* This step is required only if the ModusToolbox IDE is used. Otherwise, ensure +* the USB Device Middleware is included in your project. +* +* \subsection subsection_qsg_step2 STEP 2: Generate initialization code. +* +* 1. Launch the ModusToolbox Device Configurator Tool and switch to the +* Peripherals tab (#1.1). +* 2. Enable the USB personality under Communication and enter Alias (#1.2). +* We use USBHID in \ref section_usb_dev_quick_start +* 3. Go to the Parameters pane and configure the USB personality: assign +* the peripheral clock divider (#1.3) for Clock (Bus Reset). +* Any available free divider can be used. +* This is not required to be done for the PMG1 family of devices. +* 4. Set Endpoint Mask to 1 to enable data endpoint 1 (#1.4) Enabled data +* endpoints must match the descriptor tree in the USB Configurator. +* \image html usb_dev_device_cfg.png +* 5. Switch to the System tab (#2.1). +* 6. Check the IMO clock is enabled (#2.2). Select Trim with USB (#2.3) +* 7. Select one of the PLLs, if your device supports more than one. +* Enable the PLL and set a frequency of 48 MHz (#2.4). +* 8. Select the CLK_HF3 USB clock (#2.5). Assign the source clock to +* the CLK_PATH connected to the configured previously PLL.
+* (Not required for PMG1 devices) (#2.6). +* 9. Check the FLL clock is enabled (Not required for PMG1 devices) (#2.7). +* 10. Select File->Save to generate initialization code. +* \image html usb_dev_system_cfg.png +* +* \subsection subsection_qsg_step3 STEP 3: Generate USB descriptors. +* +* 1. Run the USB Configurator. +* 2. In the Device Descriptor node, set bDeviceClass - 0x02(#3.1), +* iProduct - the device name to identify among connected devices. We use +* "USB Device Quick Start guide"(#3.2). +* 3. Remove default Alternate Settings. +* 4. Add HID Alternate Settings. +* 5. Add HID Descriptor and select 3-Button Mouse in HID Report (#3.3). +* 6. Add Endpoint Descriptor and set: direction - IN, +* Transfer Type - Interrupt, wMaxPacketSize - 3, bInterval - 10(#3.4). +* 7. Perform File->Save to generate initialization code. If configuration is +* saved for the first time, choose a name (like design.cyusbdev) and save it +* to the project root. +* \image html usb_dev_configurator.png +* +* \subsection subsection_qsg_step4 STEP 4: Update main.c +* +* 1. Include the USB headers to get access to the generated descriptor +* structures, USB driver, device, and class layers APIs. +* \snippet usb_dev/snippet/main.c snipped_cy_usb_dev_headers +* 2. Declare the USB context global variables: +* \snippet usb_dev/snippet/main.c snipped_cy_usb_dev_hid_globals +* 3. Configure the USB interrupt structures and declare interrupt handlers +* (refer to the Configure Interrupts section of the USBFS +* driver in the PDL API Reference). +* \snippet usb_dev/snippet/main.c snipped_cy_usb_dev_interrupt_configuration +* 4. Implement the interrupt handlers: +* \snippet usb_dev/snippet/main.c snipped_cy_usb_dev_interrupt_handlers +* 5. Update the main() function with the USB and interrupt initialization +* routines: +* \snippet usb_dev/snippet/main.c snipped_USB_Dev_InitEnableHID +* 6. Example of the routine to move mouse from right to the left, +* and vice-versa. +* \snippet usb_dev/snippet/main.c snipped_USB_Dev_MouseMove +* +* \subsection subsection_qsg_step5 STEP 5: Build and program the device. +* +* Connect the device to the Host PC. On the PC, verify a new USB device was +* enumerated as a mouse device. The mouse's cursor shall move left to +* right and vice-versa. +* +******************************************************************************** +* \section group_usb_dev_configuration Configuration Considerations +******************************************************************************** +* +* This section explains how to configure the USB Device for operation. +* +******************************************************************************** +* \subsection group_usb_dev_config_drv Configure USBFS driver +******************************************************************************** +* +* The driver and system resources configuration details are provided in the +* USBFS driver section Configuration Considerations in the PDL API Reference +* Manual. The provided code snippets expect that driver and system resources +* configuration is done. +* +******************************************************************************** +* \subsection group_usb_dev_config_descr Construct USB Device Descriptors +******************************************************************************** +* +* Run standalone USB Configurator tool to construct the USB Device descriptors. +* After USB Device descriptors are +* constructed, save generated source and header files. Add these files to your +* project. Open header files to get external definitions for: +* * USB Device configuration structure \ref cy_stc_usb_dev_config_t instance. +* * Array of USB Devices structures \ref cy_stc_usb_dev_device_t. +* * CDC and/or HID class configuration structure instances. +* +* These definitions will be required in the configuration steps provided below. +* +******************************************************************************** +* \subsection group_usb_dev_config Configure USB Device +******************************************************************************** +* +* To initialize the USB Device middleware, call \ref Cy_USB_Dev_Init function +* providing: +* * The pointer to the USBFS instance. +* * The pointer to the filled USBFS driver configuration structure cy_stc_usbfs_dev_drv_config_t. +* * The pointer to the allocated USBFS driver context structure cy_stc_usbfs_dev_drv_context_t. +* * The pointer to the generated middleware USB Device structure \ref cy_stc_usb_dev_device_t. +* * The pointer to the generated middleware USB Device configuration structure \ref cy_stc_usb_dev_config_t. +* * The pointer to the allocated middleware USB Device context structure \ref cy_stc_usb_dev_context_t. +* +******************************************************************************** +* \subsection group_usb_dev_config_class Configure USB Classes +******************************************************************************** +* +* The USB Device middleware provides support of Audio, HID, and CDC classes. +* Each class has own initialization function. This function must be called +* after \ref Cy_USB_Dev_Init to initialize class data and register it. The +* class-specific request will be passed to the class handler after registration. +* Note that the USB Configurator tool generates HID and CDC Class configuration +* structures that are required class initialization. Find these structure +* external declaration in the generated header file. +* +* To initialize the Audio Class, call \ref Cy_USB_Dev_Audio_Init function +* providing: +* * The NULL pointer (reserved for possible future use). +* * The pointer to the allocated Audio Class context structure \ref cy_stc_usb_dev_audio_context_t. +* * The pointer to the allocated USB Device context structure \ref cy_stc_usb_dev_context_t. +* +* To initialize the CDC Class, call \ref Cy_USB_Dev_CDC_Init function +* providing: +* * The pointer to the populated CDC Class configuration structure \ref cy_stc_usb_dev_cdc_config_t. +* * The pointer to the allocated CDC Class context structure \ref cy_stc_usb_dev_cdc_context_t. +* * The pointer to the allocated USB Device context structure \ref cy_stc_usb_dev_context_t. +* +* To initialize the HID Class, call \ref Cy_USB_Dev_HID_Init function +* providing: +* * The pointer to the populated HID Class configuration structure \ref cy_stc_usb_dev_hid_config_t. +* * The pointer to the allocated HID Class context structure \ref cy_stc_usb_dev_hid_context_t. +* * The pointer to the allocated USB Device context structure \ref cy_stc_usb_dev_context_t. +* +******************************************************************************** +* \subsection group_usb_dev_config_enable Enable USB Device +******************************************************************************** +* +* Finally, enable the USB Device operation calling \ref Cy_USB_Dev_Connect. +* This function call enables pull-up on D+ to signal USB Device connection on +* USB Bus. The USB Host detects device connection and starts device enumeration. +* It requests the device descriptors to define device capabilities and finally +* sets device configuration for the following operation. +* The \ref Cy_USB_Dev_Connect provides an argument to block until enumeration +* completes or exits after the USB Device is enabled. +* +* \snippet usb_dev/snippet/main.c snipped_Cy_USB_Dev_InitEnable +* +* \note +* The interrupts are mandatory for the USB Device operation. Therefore, USBFS +* interrupts must be enabled in the NVIC and global interrupts must be +* enabled as well. +* +******************************************************************************** +* \section section_usb_dev_design Design Considerations +******************************************************************************** +* +* The typical use case is that application calls the middleware API interface +* provided by the USB Device or Class layer to implement application logic. +* However, some features are provided only by the USBFS driver layer. Therefore, if +* the application needs them, the driver API interface must be used. The list of +* these features is provided in the section \ref group_usb_dev_drv_features. +* +******************************************************************************** +* \subsection group_usb_dev_cfg_tool USB Configurator +******************************************************************************** +* +* The standalone USB Configurator tool helps construct USB Device descriptors. +* The USB device descriptors +* provide to the USB Host complete information about the connected device. The tool +* output are generated source and header files that contain information about the +* USB Device: device descriptors plus structures that help access device +* descriptors. Generated files are mandatory for the middleware operation and must be +* added to your project. The header file provides access to +* instances of the USB Device configuration structure \ref cy_stc_usb_dev_config_t +* and array of the USB Device structures \ref cy_stc_usb_dev_device_t. Both these +* definitions are required for USB Device configuration. The tool also generates +* instances of configuration structures required for CDC and HID Class +* configuration. +* +* A detailed information about USB Descriptors is provided by the +* [USB Specification](http://www.usb.org/developers/docs/usb20_docs/) +* +* The USB Configurator tool provides the User Guide, which can be found in the +* documentation. +* +******************************************************************************** +* \subsection group_usb_dev_std_requests Standard Request Support +******************************************************************************** +* +* The USB Device supports standard requests listed in the table below. +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
Standard RequestRequest Processing DescriptionUSB Spec Reference
CLEAR_FEATUREClears or disables a specific feature. Support recipients: Device, +* Interface and Endpoint. The TEST_MODE feature selector is not supported.9.4.1
GET_CONFIGURATIONReturns the current device configuration value.9.4.2
GET_DESCRIPTORReturns the specified descriptor if the descriptor exists.9.4.3
GET_INTERFACEReturns the selected alternate interface setting for the specified +* interface.9.4.4
GET_STATUSReturns status for the specified recipient. Support recipients: +* Device, Interface, and Endpoint.9.4.5
SET_ADDRESSSets the device address for all future device accesses.9.4.6
SET_CONFIGURATIONSets the device configuration. After this request, the device is ready for +* communication.9.4.7
SET_DESCRIPTORNot supported (optional request).9.4.8
SET_FEATUREEnables a specific feature. Support recipients: Device, Interface, and Endpoint. +* The TEST_MODE feature selector is not supported.9.4.9
SET_INTERFACEAllows the USB Host to select an alternate setting for the specified +* interface.9.4.10
SYNCH_FRAMENot supported.9.4.11
+* +******************************************************************************** +* \subsection group_usb_dev_audio_class_info Audio Class +******************************************************************************** +* +* The USB Audio class can be used in a large amount of applications, +* either Made for iPod (MFI) or general USB Audio based. These applications +* consist of, but are not limited to, speakers, microphones, headsets, music +* creation tools (DJ equipment, guitar jacks, etc), and mixers. +* An additional application for the Audio class is in Musical Instrument +* Digital Interface (MIDI) applications. This interface uses a digital UART-like +* interface and allows the information to be sent across to the Host to +* be used with software applications, such as Apple Garage Band. Various +* instruments, such as electronic pianos, interface with MIDI. +* +* A detailed description about Audio Class is provided by the +* [USB Implementers Forum (USB-IF) Class Documentation] +* (http://www.usb.org/developers/docs/devclass_docs/) +* +* The Audio Class does not provide support any of Audio v1.0 or v2.0 requests +* processing and provides only the API interface to register Audio request handlers +* implemented on the application level. However, \ref group_usb_dev_cfg_tool +* supports Audio v1.0 or v2.0 descriptors. +* +* \note +* The MIDI Class support is not available in this version. +* +******************************************************************************** +* \subsection group_usb_dev_cdc_class_info CDC: Communication Device Class +******************************************************************************** +* +* Common use case for this class in a PSoC design is to replace a legacy serial +* (RS232) COM port with a USB connection. This allows customers to use +* legacy serial software while updating the communication interface to +* something more readily available on today's computers. The type of data +* that might be streamed across USB can vary depending on the end application. +* This could be as simple as streaming raw ADC counts to an entire command +* protocol. Additionally, CDC is extremely useful for debug purposes. +* Users can easily develop a USB interface that can send and receive +* information across CDC. On the Host side, GUI applications are widely +* available to view the data being transmitted, such as TeraTerm, Terminal, +* or Hyper-Terminal (depending on version of Microsoft Windows). +* +* A detailed description about CDC class is provided by the +* [USB Implementers Forum (USB-IF) Class Documentation] +* (http://www.usb.org/developers/docs/devclass_docs/) +* +* The CDC Class supports requests listed in the table below. +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
Class RequestRequest Processing DescriptionCommunications Class Subclass Specification for PSTN Devices
SET_LINE_CODINGAllows the host to specify typical asynchronous line-character +* formatting properties such as: data terminal rate, number of stop bits, +* parity type and number of data bits. It applies to data transfers both +* from the Host to the Device and from the Device to the Host.6.3.10
GET_LINE_CODINGAllows the host to discover the currently configured line coding.6.3.11
SET_CONTROL_LINE_STATEGenerates RS-232/V.24 style control signals - RTS and DTR.6.3.12
+* +* The CDC Class supports notifications listed in the table below. +* +* +* +* +* +* +* +*
Class NotificationNotification Processing DescriptionCommunications Class Subclass Specification for PSTN Devices
SERIAL_STATEAllows the Host to read the current state of the carrier detect (CD), +* DSR, break, and ring signal (RI).6.3.4
+* +******************************************************************************** +* \subsection group_usb_dev_hid_class_info HID: Human Interface Device +******************************************************************************** +* +* There are many possible use cases for HID depending on the end application. +* A keyboard/keypad is a common HID application that has been implemented +* previously with PSoC. Additionally, customers can use PSoC to implement a +* PC mouse or game controller device. A more generic use case seen is with +* regards to customers using USB as general-purpose interface between PSoC and +* the Host, without conforming to specific USAGE such as a Keyboard, Mouse, etc. +* Instead the user configures the HID descriptor to be a generic device, which +* allows them to transfer Vendor-Specific information, such as ADC data, +* button presses, etc., across the HID protocol. This allows customers to +* perform custom/generic data transfers over USB, without needing to provide +* an INF or SYS file during enumeration or worry about WHQL certification. +* All this is accomplished using the HID drivers that are built into all +* modern operation systems today. This includes Windows, Mac, and Linux. +* +* A detailed description about HID is provided by the +* [USB Implementers Forum (USB-IF) Class Documentation] +* (http://www.usb.org/developers/docs/devclass_docs/) +* +* The HID Class supports requests listed in the table below. +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
Class RequestRequest Processing DescriptionHID Spec Reference
GET_REPORTAllows the USB Host to receive a report via the control pipe.7.2.1
SET_REPORTAllows the USB Host to send a report via the control pipe (set a +* state of input, output, or feature report controls).7.2.2
GET_IDLEReads the current idle rate for a particular Input report. \n +* The recommended default idle rate (rate when the device is initialized) +* is 500 milliseconds for keyboards (delay before first repeat rate) and +* infinity for joysticks and mice.7.2.3
SET_IDLESets idle rate for a particular report. This request is used to limit +* the reporting frequency of an interrupt in endpoint.\n +* When the idle rate byte is 0 (zero), the duration is indefinite. +* The endpoint reports only when a change is detected in the report data. +* When the idle rate byte is non-zero, then a fixed duration is +* used (defined by idle rate).7.2.4
GET_PROTOCOLReads which protocol is currently active (either the boot or the +* report protocol).7.2.5
SET_PROTOCOLSwitches between the boot protocol and the report protocol (or vice versa).7.2.6
+* +******************************************************************************** +* \subsection group_usb_dev_class_x Adding Custom Class +******************************************************************************** +* +* The USB Device middleware provides API interface that allows the user to +* implement custom class support. The middleware notifies registered class about +* following events: +* * Bus Reset detected ( \ref cy_cb_usb_dev_bus_reset_t ). +* * Set Configuration request received ( \ref cy_cb_usb_dev_set_config_t ). +* * Set Interface request received ( \ref cy_cb_usb_dev_set_interface_t ). +* * Setup packet received ( \ref cy_cb_usb_dev_request_received_t ). +* * Data is received in response for current setup packet ( \ref cy_cb_usb_dev_request_cmplt_t ). +* +* To create a new custom Class, follow the steps below: +* 1. Implement functions to service events (from the list above) required +* for class operation. Typically, class should implement service of class-specific +* requests therefore needs to implement functions defined by \ref cy_cb_usb_dev_request_received_t +* and \ref cy_cb_usb_dev_request_cmplt_t. +* 2. Initialize instance of \ref cy_stc_usb_dev_class_t structure using implemented +* service functions. Provide NULL pointer as function pointer if class does not +* use this event. +* 3. Allocate instance of \ref cy_stc_usb_dev_class_ll_item_t structure to +* provide storage for a linked list item of the class. +* 4. The class might need a context to store class-specific data. If needed, +* define context type specific for this class and allocate it. +* 5. To enable class operation, this needs to be registered using +* \ref Cy_USB_Dev_RegisterClass function after USB Device middleware is +* initialized. +* +* Any of supported classes can be taken as an example to implement a custom class. +* +******************************************************************************** +* \subsection group_usb_dev_vendor Vendor-Specific Requests Support +******************************************************************************** +* +* The vendor-specific requests are STALLed by USB Device middleware by default. +* The exception is MS OS String vendor-specific request to retrieve an OS Feature +* Descriptor (Note that USB device must contain MS OS String descriptor to handle +* this vendor-specific by middleware). +* The middleware provides the \ref Cy_USB_Dev_RegisterVendorCallbacks function +* to register callbacks to handle vendor-specific requests. +* +******************************************************************************** +* \subsection group_usb_dev_ep_buf_alloc Allocate Data Endpoint Buffer +******************************************************************************** +* +* The application allocates buffers for data endpoints to operate. The buffer +* allocation depends on USBFS driver endpoint buffer access type configuration. +* It specifies which hardware register set 8-bit or 16-bit is used to access +* hardware endpoints buffer. The 16-bit access requires that the specific rules for +* the endpoints buffer allocation must be met (See Hardware Buffer Access +* section of the USBFS driver for more information). \n +* To make endpoint buffer allocation configuration independent, use +* the \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro. +* +******************************************************************************** +* \subsection group_usb_dev_self_powered_dev Self-Powered Devices +******************************************************************************** +* +* The USB Device responds to GET_STATUS requests based on the status set with +* the \ref Cy_USB_Dev_SetPowerStatus function. To set the correct status, +* \ref Cy_USB_Dev_SetPowerStatus must be called during initialization if USB +* Device is configured as self-powered. The \ref Cy_USB_Dev_SetPowerStatus must +* be called any time the device changes status. A self-powered device also requires +* monitoring VBUS to control pull-up resistors. The pull-up resistor does +* not supply power to the data line until you call \ref Cy_USB_Dev_Connect. +* \ref Cy_USB_Dev_Disconnect disconnects the pull-up resistor from the data line. +* Find information about how to add VBUS monitoring in your application in the USBFS driver +* section VBUS Detection in the PDL API Reference Manual. +* +******************************************************************************** +* \subsection group_usb_dev_std_timeout Timeout Function Redefinition +******************************************************************************** +* +* The USB Device middleware provides following blocking functions: \ref Cy_USB_Dev_ReadEpBlocking, +* \ref Cy_USB_Dev_WriteEpBlocking, and \ref Cy_USB_Dev_Connect (the behavior +* defined by the blocking parameter of the connect function). The blocking functions +* parameter timeout defines how many milliseconds to wait before timeout. +* The SysLib driver function Cy_SysLib_Delay is used to implement a 1 millisecond +* wait cycle. The middleware provides function \ref Cy_USB_Dev_OverwriteHandleTimeout +* that allows overriding the wait function implementation. This might be +* useful when an operation system is used in your application. +* +* \note +* The blocking function must be used carefully to not cause application lock-up. +* The preferred solution is using non-blocking functions. +* +******************************************************************************** +* \subsection group_usb_dev_drv_features Driver Features +******************************************************************************** +* +* There are driver features that do not have corresponding an API +* interface provided in the middleware. However, the application might need +* these features for USB Device implementation. If there is such a need, the +* driver functions must be used. These features are listed below: +* * Data Endpoint 1 - 8 Completion, SOF received and LPM transfer ACKed events +* notification. +* * Low power support: Suspend / Resume, Remote wakeup signaling. +* * Link Power Management (LPM) support. +* +* Find more information in the appropriate section of the USBFS driver documentation +* provided in the PDL API Reference Manual. +* +******************************************************************************** +* \section section_usb_dev_toolchain Supported Software and Tools +******************************************************************************** +* +* For supported software and tools, refer to the Supported Software and Tools +* section in in the +* [RELEASE.md](https://github.com/Infineon/usbdev/blob/master/RELEASE.md#supported-software-and-tools) +* +******************************************************************************** +* \section section_usb_dev_errata Errata +******************************************************************************** +* +* This section lists the known problems with the USB Device middleware. +* +* +* +* +* +* +* +* +* +* +* +* +* +*
Cypress IDKnown IssueWorkaround
DRIVERS-1401 +* The USB Device ignores LPM requests after wake up from Deep Sleep. +* +* Call USBFS driver Cy_USBFS_Dev_Drv_Lpm_SetResponse() after calling +* Cy_USBFS_Dev_Drv_Resume() to restore response to the LPM packets. +*
DRIVERS-1427 +* The USB Device modes with DMA do not work after wake up from Deep +* Sleep, due to incorrect restore of the ARB_CFG register. +* +* Save ARB_CFG values before entering Deep Sleep and restore it after +* calling of Cy_USBFS_Dev_Drv_Resume. +* \snippet usb_dev/snippet/main.c snippet_WorkaroundDmaResume +*
+* +******************************************************************************** +* \section group_usb_dev_changelog Changelog +******************************************************************************** +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
VersionChangesReason for Change
2.10Updated DocumentationPMG1 Integration
Fixed vendor request handlingDefect Fixes
Added support for configurations without any data endpointsDefect Fixes
Minor enhancements in several functions.Enabled compliance with MISRA-C:2012 standard.
2.0Updated the internal processing to support USBFS driver updates.The USBFS driver is updated to v2.0.
Moved the timeout from Cy_USB_Dev_AbortEpTransfer() to the driver layer. +* The maximum function's wait time is significantly reduced.Align with the changes of the USBFS driver.
Changed the functions parameter name and the structure member name class to classObj.Fixed the ambiguity related to the usage of the C++ keyword class as a name.
Enclosed middleware sources within a conditional compilation to +* exclude the USB Device middleware for devices without USB hardware.Fixed a compilation error for devices without USB hardware.
Updated the major and minor version defines to follow the naming convention.
1.0The initial version.
+* +******************************************************************************** +* \section group_usb_dev_more_information More Information +******************************************************************************** +* +* For more information, refer to the links in the +* [README.md](https://github.com/Infineon/usbdev/blob/master/README.md#more-information) +* +* \note +* The links to the other software component's documentation (middleware and PDL) +* point to GitHub to the software latest available version. +* To get documentation of the specified version, download from GitHub and unzip +* the component archive. The documentation is available in the docs folder. +* +******************************************************************************** +* \defgroup group_usb_device Device +* This section provides an API description for the core functionality of the +* USB Device: initialization, status information, data transfers, and class +* support. +* \{ +* \defgroup group_usb_dev_macros Macros +* \{ +* \defgroup group_usb_dev_macros_device_descr Descriptors +* \} +* +* \defgroup group_usb_dev_functions Functions +* \{ +* \defgroup group_usb_dev_functions_common Initialization Functions +* \defgroup group_usb_dev_functions_service Service Functions +* \defgroup group_usb_dev_functions_data_transfer Data Transfer Functions +* \defgroup group_usb_dev_functions_vendor_support Vendor Request Support Functions +* \defgroup group_usb_dev_functions_class_support Class Support Functions +* \} +* +* \defgroup group_usb_dev_data_structures Data Structures +* \{ +* \defgroup group_usb_dev_structures_device Device Information +* \defgroup group_usb_dev_structures_device_descr Device Descriptors +* \defgroup group_usb_dev_structures_control Control Transfer +* \defgroup group_usb_dev_structures_class Class Support +* \defgroup group_usb_dev_structures_func_ptr Function Pointers +* \} +* +* \defgroup group_usb_dev_enums Enumerated Types +* \} +* +* \defgroup group_usb_dev_audio Audio Class +* \defgroup group_usb_dev_cdc CDC Class +* \defgroup group_usb_dev_hid HID Class +* +*/ + + +#if !defined(CY_USB_DEV_H) +#define CY_USB_DEV_H + +#include +#include +#include +#include + +#include "cy_usbfs_dev_drv.h" +#include "cy_usb_dev_descr.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +#if defined(__cplusplus) +extern "C" { +#endif + +/** +* \addtogroup group_usb_dev_macros +* \{ +*/ + +/******************************************************************************* +* Middleware Version +*******************************************************************************/ + +/** USB Device Middleware major version */ +#define CY_USB_DEV_MW_VERSION_MAJOR (2) + +/** USB Device Middleware minor version */ +#define CY_USB_DEV_MW_VERSION_MINOR (10) + +/** USB Device Middleware identifier */ +#define CY_USB_DEV_ID CY_PDL_DRV_ID(0x08U) + +/** Maximum number of interfaces (this equals to the maximum number of hardware +* endpoints where each interface has at least one endpoint). +*/ +#define CY_USB_DEV_NUM_INTERFACES_MAX CY_USBFS_DEV_DRV_NUM_EPS_MAX + +/** USBFS Device endpoint 0 packet size */ +#define CY_USB_DEV_EP0_PACKET_SIZE CY_USBFS_DEV_DRV_EP0_BUFFER_SIZE + +/** Length of serial string number generated from silicon ID */ +#define CY_USB_DEV_SN_STRING_LENGTH (32U) + +/** Length of serial string number */ +#define CY_USB_DEV_SN_STRING_DESR_LENGTH (CY_USB_DEV_SN_STRING_LENGTH + 2U) +/** \} group_usb_dev_macros */ + + +/******************************************************************************* +* Enumerated Types +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_enums +* \{ +*/ + +/** USBFS Device return codes */ +typedef enum +{ + /** Operation completed successfully */ + CY_USB_DEV_SUCCESS = 0U, + + /** One or more input parameters are invalid */ + CY_USB_DEV_BAD_PARAM = (CY_USB_DEV_ID | CY_PDL_STATUS_ERROR | 1U), + + /** The request is not handled */ + CY_USB_DEV_REQUEST_NOT_HANDLED = (CY_USB_DEV_ID | CY_PDL_STATUS_ERROR | 2U), + + /** Timeout occurred for the operation */ + CY_USB_DEV_TIMEOUT = (CY_USB_DEV_ID | CY_PDL_STATUS_ERROR | 3U), + + /** The hardware is busy executing previous operation */ + CY_USB_DEV_DRV_HW_BUSY = (CY_USB_DEV_ID | CY_PDL_STATUS_ERROR | 4U), + + /** The hardware is disabled */ + CY_USB_DEV_DRV_HW_DISABLED = (CY_USB_DEV_ID | CY_PDL_STATUS_ERROR | 5U), + + /** The hardware error occurred during operation */ + CY_USB_DEV_DRV_HW_ERROR = (CY_USB_DEV_ID | CY_PDL_STATUS_ERROR | 6U), + +} cy_en_usb_dev_status_t; + +/** Device states */ +typedef enum +{ + CY_USB_DEV_DISABLED, /**< Device is disabled */ + CY_USB_DEV_ATTACHED, /**< Device is attached */ + CY_USB_DEV_POWERED, /**< Device is powered */ + CY_USB_DEV_DEFAULT, /**< Device is in default state (after bus reset) */ + CY_USB_DEV_ADDRESSED, /**< Device set address (device is ready to communicate using this address) */ + CY_USB_DEV_CONFIGURED /**< Device is configured (device is ready to communicate using data endpoints) */ +} cy_en_usb_dev_state_t; + +/** Power Status */ +typedef enum +{ + CY_USB_DEV_STATUS_BUS_POWERED, /**< Device is bus powered */ + CY_USB_DEV_STATUS_SELF_POWERED /**< Device is self powered */ +} cy_en_usb_dev_power_status_t; + +/** Callback events */ +typedef enum +{ + CY_USB_DEV_EVENT_BUS_RESET, /**< Bus Reset detected */ + CY_USB_DEV_EVENT_SET_CONFIG, /**< SET_CONFIGURATION request received */ + CY_USB_DEV_EVENT_SET_INTERFACE /**< SET_INTERFACE request received */ +} cy_en_usb_dev_callback_events_t; +/** \} group_usb_dev_enums */ + + +/******************************************************************************* +* Type Definitions +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_structures_control +* \{ +*/ + +/** Parsed bmRequest */ +typedef struct +{ + uint8_t direction; /**< Transfer direction */ + uint8_t type; /**< Transfer type */ + uint8_t recipient; /**< Transfer recipient */ +} cy_stc_usb_dev_bm_request; + +/** Store request */ +typedef struct +{ + cy_stc_usb_dev_bm_request bmRequestType; /**< Request type */ + uint8_t bRequest; /**< Request value */ + uint16_t wValue; /**< Request value (2 bytes) */ + uint16_t wIndex; /**< Request index (2 bytes) */ + uint16_t wLength; /**< Request length (2 bytes) */ +} cy_stc_usb_dev_setup_packet_t; + +/** Execute transfer use this structure */ +typedef struct +{ + cy_stc_usb_dev_setup_packet_t setup; /**< Request packet */ + uint8_t *ptr; /**< Pointer to data to transfer or space to store data */ + uint8_t *buffer; /**< Pointer to buffer to store data send from host to device during control transfer */ + uint16_t remaining; /**< Number of bytes remaining to complete send or receive */ + uint16_t size; /**< Number of bytes to send or receive */ + uint16_t bufferSize; /**< Size of the buffer to store data */ + uint8_t direction; /**< Transfer direction */ + bool zlp; /**< Defines whether zero length packet is needed to complete data stage */ + bool notify; /**< Defines whether trigger callback that notifies end of data stage (device received data) */ +} cy_stc_usb_dev_control_transfer_t; + +/** \} group_usb_dev_structures_control */ + + +/** \cond INTERNAL */ +/** Get compiler know what is cy_stc_usb_dev_context. +* The cy_stc_usb_dev_context_t is defined below. +*/ +struct cy_stc_usb_dev_context; +/** \endcond */ + + +/** +* \addtogroup group_usb_dev_structures_func_ptr +* \{ +*/ + +/** +* Pointer to a function that implements a callback for the following events: +* Bus Reset detected, SET_CONFIGURATION request received and SET_INTERFACE request +* received. The notified events are defined by event argument +* (see \ref cy_en_usb_dev_callback_events_t). +* Only one event is notified when callback invoked. +* This callback invoked in the USB interrupt handler context and must be short +* as possible. \n +* Input arguments: +* * Bus Reset detected event: ignore wValue and wIndex arguments. +* * SET_CONFIGURATION request received event: the wValue is new configuration +* value and wIndex can be ignored. +* * SET_CONFIGURATION request received event: the wValue is new alternative +* setting value and wIndex interface value to which alternate belongs. \n +* +* The returned status defines following operation: +* * Bus Reset detected event: status is ignored and event processing is passed to +* class event handlers. +* * SET_CONFIGURATION or SET_INTERFACE received event: the returned status defines +* following request processing. If returned status fail the request is +* STALLed and event notification stops. +* If returned status is success the event is notified to the appropriate class +* event handlers which status defines request response STALL or ACK. +*/ +typedef cy_en_usb_dev_status_t (* cy_cb_usb_dev_events_callback_t)(cy_en_usb_dev_callback_events_t event, + uint32_t wValue, uint32_t wIndex, + struct cy_stc_usb_dev_context *devContext); + +/** +* Pointer to a function that implements a timeout handler. The function accepts the +* number of milliseconds that remain to wait before timeout expires. +* This returns the number of milliseconds remaining to wait minus the milliseconds +* that have elapsed inside the function. +*/ +typedef int32_t (* cy_fn_usb_dev_handle_timeout_ptr_t)(int32_t milliseconds); + +/** +* Pointer to function that returns pointer to uint8_t array, which contains a serial number string +* and accepts the device context \ref cy_stc_usb_dev_context_t. +* This type is used to define a callback that returns serial number string. +*/ +typedef uint8_t * (* cy_fn_usb_dev_sn_string_ptr_t)(void); + +/** +* Pointer to function that returns nothing and accepts a pointer to void and a pointer to \ref cy_stc_usb_dev_context_t. +* This type is used to define a callback that notifies the class about a bus reset event. +*/ +typedef void (* cy_cb_usb_dev_bus_reset_t)(void *classData, struct cy_stc_usb_dev_context *devContext); + +/** +* Pointer to function that returns the status of operation and accepts received configuration number, +* pointer to class context, and pointer to device context \ref cy_stc_usb_dev_context_t. +* This type is used to define a callback that notifies the class about a set configuration request event. +*/ +typedef cy_en_usb_dev_status_t (* cy_cb_usb_dev_set_config_t)(uint32_t configuration, void *classData, + struct cy_stc_usb_dev_context *devContext); + +/** +* Pointer to function that returns the status of operation and accepts received interface +* alternate settings number, pointer to class context, and pointer to device context \ref cy_stc_usb_dev_context_t. +* This type is used to define a callback that notifies the class about a set interface request event. +*/ +typedef cy_en_usb_dev_status_t (* cy_cb_usb_dev_set_interface_t)(uint32_t interface, uint32_t alternate, + void *classContext, + struct cy_stc_usb_dev_context *devContext); + +/** +* Pointer to function that returns the status of operation and accepts pointer to received control transfer +* number, pointer to class context, and pointer to device context \ref cy_stc_usb_dev_context_t. +* This type is used to define a callback that notifies the class about a request received event. +*/ +typedef cy_en_usb_dev_status_t (* cy_cb_usb_dev_request_received_t)(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + struct cy_stc_usb_dev_context *devContext); + +/** +* Pointer to function that returns status of operation and accepts pointer to received control transfer +* number, pointer to class context, and pointer to device context \ref cy_stc_usb_dev_context_t. +* This type is used to define a callback that notifies the class that a request completed (data is received in +* response for current request) event. +*/ +typedef cy_en_usb_dev_status_t (* cy_cb_usb_dev_request_cmplt_t)(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + struct cy_stc_usb_dev_context *devContext); + +/** \} group_usb_dev_structures_func_ptr */ + +/** +* \addtogroup group_usb_dev_structures_class +* \{ +*/ + +/** Class support definition - each class must provide this structure */ +typedef struct +{ + /** Called after bus reset is serviced. Initialize Class here */ + cy_cb_usb_dev_bus_reset_t busReset; + + /** + * Called after Set Configuration request is received. + * The endpoint available for this configuration must be configured here. + * Returns status of the event processing. + */ + cy_cb_usb_dev_set_config_t setConfiguration; + + /** + * Called after Set Interface request is received. + * Probably the endpoint configuration requires correction here. + * Returns status of the event processing. + */ + cy_cb_usb_dev_set_interface_t setInterface; + + /** + * This function is called when a setup packet was received from the USB Host but + * was not recognized. Therefore, it might require the user to do the class processing. + */ + cy_cb_usb_dev_request_received_t requestReceived; + + /** + * This function is called when the USB Device received data from the USB Host + * as part of current request processing. The requestReceivedHandle function + * must enable notification to trigger this event. This makes sense only when CDC + * request processing requires a data stage. + */ + cy_cb_usb_dev_request_cmplt_t requestCompleted; + +} cy_stc_usb_dev_class_t; + + +/** Class linked list element. It includes class and class data pointers +* and pointer to the next class linked list element. +*/ +typedef struct cy_stc_usb_dev_class_ll_item +{ + /** Next item in the class driver linked list */ + struct cy_stc_usb_dev_class_ll_item *next; + + /** Pointer to the class structure */ + cy_stc_usb_dev_class_t *classObj; + + /** Pointer to the class data (context) */ + void *classData; + +} cy_stc_usb_dev_class_ll_item_t; +/** \} group_usb_dev_structures_class */ + + +/** +* \addtogroup group_usb_dev_data_structures +* \{ +*/ +/** USB Device configuration structure */ +typedef struct +{ + /** Pointer to the buffer to store data received from the USB Host through + * Endpoint 0. The buffer size must be large enough to store received data + * for all supported requests. + */ + uint8_t *ep0Buffer; + + /** Buffer size for Endpoint 0 */ + uint16_t ep0BufferSize; + +} cy_stc_usb_dev_config_t; + + +/** USB Device context structure. +* All fields for the USB Device context structure are internal. Firmware never +* reads or writes these values. Firmware allocates the structure and provides +* the address of the structure to the middleware in function calls. Firmware +* must ensure that the defined instance of this structure remains in scope while +* the middleware is in use. +*/ +typedef struct cy_stc_usb_dev_context +{ + /** \cond INTERNAL*/ + + /** Device state */ + volatile cy_en_usb_dev_state_t state; + + /** Configuration changed status */ + volatile bool configChanged; + + /** Device status */ + volatile uint8_t status; + + /** Device configuration */ + volatile uint8_t configuration; + + /** Device interface alternate settings */ + volatile uint8_t alternate[CY_USB_DEV_NUM_INTERFACES_MAX]; + + /** Storage for serial number string descriptor (constructed from silicon ID) */ + uint8_t serialNumDescr[CY_USB_DEV_SN_STRING_DESR_LENGTH]; + + /** Pointer to function that implements timeout in milliseconds */ + cy_fn_usb_dev_handle_timeout_ptr_t handleTimeout; + + /** Control transfer data */ + cy_stc_usb_dev_control_transfer_t ControlTransfer; + + /** Pointers to structure that describes device */ + const cy_stc_usb_dev_device_t *devDescriptors; + + /** Pointer to function that returns serial string */ + cy_fn_usb_dev_sn_string_ptr_t getSerialNumString; + + /** Callback for events: bus reset, set configuration and set interface */ + cy_cb_usb_dev_events_callback_t eventsCallback; + + /** Vendor-Specific callback to handle Setup packet received event */ + cy_cb_usb_dev_request_received_t vndRequestReceived; + + /** Vendor-Specific callback to handle notification that OUT stage is completed */ + cy_cb_usb_dev_request_cmplt_t vndRequestCompleted; + + /** Pointer to linked list of class structures */ + cy_stc_usb_dev_class_ll_item_t *classRoot; + + /** Pointer to driver base address */ + USBFS_Type *drvBase; + + /** Pointer to driver context */ + struct cy_stc_usbfs_dev_drv_context *drvContext; + + /** \endcond */ +} cy_stc_usb_dev_context_t; +/** \} group_usb_dev_data_structures */ + + +/******************************************************************************* +* Function Prototypes +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_functions_common +* \{ +*/ +cy_en_usb_dev_status_t Cy_USB_Dev_Init(USBFS_Type *base, + struct cy_stc_usbfs_dev_drv_config const *drvConfig, + struct cy_stc_usbfs_dev_drv_context *drvContext, + cy_stc_usb_dev_device_t const *device, + cy_stc_usb_dev_config_t const *config, + cy_stc_usb_dev_context_t *context); + +void Cy_USB_Dev_DeInit(cy_stc_usb_dev_context_t *context); +cy_en_usb_dev_status_t Cy_USB_Dev_Connect(bool blocking, int32_t timeout, + cy_stc_usb_dev_context_t *context); +void Cy_USB_Dev_Disconnect(cy_stc_usb_dev_context_t *context); +/** \} group_usb_dev_functions_common */ + + +/** +* \addtogroup group_usb_dev_functions_service +* \{ +*/ +__STATIC_INLINE void Cy_USB_Dev_RegisterEventsCallback(cy_cb_usb_dev_events_callback_t callback, + cy_stc_usb_dev_context_t *context); + +__STATIC_INLINE uint32_t Cy_USB_Dev_GetConfiguration (cy_stc_usb_dev_context_t const *context); +__STATIC_INLINE uint32_t Cy_USB_Dev_GetAlternateSettings (uint32_t interface, + cy_stc_usb_dev_context_t const *context); +__STATIC_INLINE bool Cy_USB_Dev_IsConfigurationChanged(cy_stc_usb_dev_context_t *context); + +__STATIC_INLINE bool Cy_USB_Dev_IsRemoteWakeupEnabled(cy_stc_usb_dev_context_t const *context); +__STATIC_INLINE void Cy_USB_Dev_SetPowerStatus (cy_en_usb_dev_power_status_t status, + cy_stc_usb_dev_context_t *context); + +__STATIC_INLINE uint8_t* Cy_USB_Dev_GetSerialNumberString(cy_stc_usb_dev_context_t *context); +__STATIC_INLINE void Cy_USB_Dev_RegisterSerialNumStringCallback(cy_fn_usb_dev_sn_string_ptr_t callback, + cy_stc_usb_dev_context_t *context); +__STATIC_INLINE cy_en_usb_dev_status_t Cy_USB_Dev_SetupControlRead(cy_stc_usb_dev_control_transfer_t *transfer, + uint8_t *ptr, + uint32_t size); + +__STATIC_INLINE cy_en_usb_dev_status_t Cy_USB_Dev_SetupControlWrite(cy_stc_usb_dev_control_transfer_t *transfer, + uint32_t size); + +__STATIC_INLINE cy_en_usb_dev_status_t Cy_USB_Dev_SetupControlWriteResult(cy_stc_usb_dev_control_transfer_t const *transfer, + uint8_t *ptr); +/** \cond INTERNAL */ +__STATIC_INLINE uint32_t Cy_USB_Dev_GetConfigurationIdx(cy_stc_usb_dev_context_t const *context); +/** \endcond */ + +/** \} group_usb_dev_functions_service */ + + +/** +* \addtogroup group_usb_dev_functions_data_transfer +* \{ +*/ +cy_en_usb_dev_status_t Cy_USB_Dev_StartReadEp(uint32_t endpoint, + cy_stc_usb_dev_context_t *context); + +cy_en_usb_dev_status_t Cy_USB_Dev_ReadEpBlocking(uint32_t endpoint, + uint8_t *buffer, + uint32_t size, + uint32_t *actSize, + int32_t timeout, + cy_stc_usb_dev_context_t *context); + +cy_en_usb_dev_status_t Cy_USB_Dev_ReadEpNonBlocking(uint32_t endpoint, + uint8_t *buffer, + uint32_t size, + uint32_t *actSize, + cy_stc_usb_dev_context_t *context); + +cy_en_usb_dev_status_t Cy_USB_Dev_AbortEpTransfer(uint32_t endpoint, + cy_stc_usb_dev_context_t *context); + +__STATIC_INLINE uint32_t Cy_USB_Dev_GetEpNumToRead(uint32_t endpoint, + cy_stc_usb_dev_context_t const *context); + + +cy_en_usb_dev_status_t Cy_USB_Dev_WriteEpBlocking(uint32_t endpoint, + uint8_t const *buffer, + uint32_t size, + int32_t timeout, + cy_stc_usb_dev_context_t *context); + +cy_en_usb_dev_status_t Cy_USB_Dev_WriteEpNonBlocking(uint32_t endpoint, + uint8_t const *buffer, + uint32_t size, + cy_stc_usb_dev_context_t *context); + +__STATIC_INLINE void Cy_USB_Dev_OverwriteHandleTimeout(cy_fn_usb_dev_handle_timeout_ptr_t handleTimeout, + cy_stc_usb_dev_context_t *context); +/** \} group_usb_dev_functions_data_transfer */ + + +/** +* \addtogroup group_usb_dev_functions_class_support +* \{ +*/ +cy_en_usb_dev_status_t Cy_USB_Dev_RegisterClass(cy_stc_usb_dev_class_ll_item_t *classItem, + cy_stc_usb_dev_class_t *classObj, + void *classContext, + cy_stc_usb_dev_context_t *context); + +__STATIC_INLINE void Cy_USB_Dev_RegisterClassBusResetCallback(cy_cb_usb_dev_bus_reset_t callback, + cy_stc_usb_dev_class_t *classObj); + +__STATIC_INLINE void Cy_USB_Dev_RegisterClassSetConfigCallback(cy_cb_usb_dev_set_config_t callback, + cy_stc_usb_dev_class_t *classObj); + +__STATIC_INLINE void Cy_USB_Dev_RegisterClassSetInterfaceCallback(cy_cb_usb_dev_set_interface_t callback, + cy_stc_usb_dev_class_t *classObj); + +__STATIC_INLINE void Cy_USB_Dev_RegisterClassRequestRcvdCallback(cy_cb_usb_dev_request_received_t callback, + cy_stc_usb_dev_class_t *classObj); + +__STATIC_INLINE void Cy_USB_Dev_RegisterClassRequestCmpltCallback(cy_cb_usb_dev_request_cmplt_t callback, + cy_stc_usb_dev_class_t *classObj); +/** \} group_usb_dev_functions_class_support */ + +/** +* \addtogroup group_usb_dev_functions_vendor_support +* \{ +*/ +__STATIC_INLINE void Cy_USB_Dev_RegisterVendorCallbacks(cy_cb_usb_dev_request_received_t requestReceivedHandle, + cy_cb_usb_dev_request_cmplt_t requestCompletedHandle, + cy_stc_usb_dev_context_t *context); +/** \} group_usb_dev_functions_vendor_support */ + + +/******************************************************************************* +* API Constants +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_macros +* \{ +*/ + +/** Timeout value that defines wait forever */ +#define CY_USB_DEV_WAIT_FOREVER (0) + +/** Allocates static buffer for data endpoint. The size parameter must be a constant. +* The allocated buffer is aligned on a 2 byte boundary. An odd buffer size is +* converted to even consuming 1 extra byte. The application must discard this +* extra byte. This manipulation is needed to support different 8-bit and 16-bit +* hardware buffer access types in the driver (See Hardware Buffer Access +* section of the USBFS driver for more information). +*/ +#define CY_USB_DEV_ALLOC_ENDPOINT_BUFFER(buf, size) CY_USBFS_DEV_DRV_ALLOC_ENDPOINT_BUFFER(buf,size) + +/* bmRequestType.Type: transfer direction */ +#define CY_USB_DEV_DIR_HOST_TO_DEVICE (0U) /**< Transfer direction from Host to Device (setup packet) */ +#define CY_USB_DEV_DIR_DEVICE_TO_HOST (1U) /**< Transfer direction from Device to Host (setup packet) */ + +/* bmRequestType.Type */ +#define CY_USB_DEV_STANDARD_TYPE (0U) /**< Standard request type (setup packet) */ +#define CY_USB_DEV_CLASS_TYPE (1U) /**< Class-specific request type (setup packet) */ +#define CY_USB_DEV_VENDOR_TYPE (2U) /**< Vendor-specific request type (setup packet) */ +#define CY_USB_DEV_RESERVED_TYPE (3U) /**< Reserved request type (setup packet) */ + +/* bmRequestType.Recipient */ +#define CY_USB_DEV_RECIPIENT_DEVICE (0U) /**< Request recipient device (setup packet) */ +#define CY_USB_DEV_RECIPIENT_INTERFACE (1U) /**< Request recipient interface (setup packet) */ +#define CY_USB_DEV_RECIPIENT_ENDPOINT (2U) /**< Request recipient endpoint (setup packet) */ +#define CY_USB_DEV_RECIPIENT_OTHER (3U) /**< Request recipient other (setup packet) */ + +/* USB v2.0 spec: Table 9-4. Standard Request Codes */ +#define CY_USB_DEV_RQST_GET_STATUS (0U) /**< GET_STATUS standard request */ +#define CY_USB_DEV_RQST_CLEAR_FEATURE (1U) /**< CLEAR_FEATURE standard request */ +#define CY_USB_DEV_RQST_SET_FEATURE (3U) /**< SET_FEATURE standard request */ +#define CY_USB_DEV_RQST_SET_ADDRESS (5U) /**< SET_ADDRESS standard request */ +#define CY_USB_DEV_RQST_GET_DESCRIPTOR (6U) /**< GET_DESCRIPTOR standard request */ +#define CY_USB_DEV_RQST_SET_DESCRIPTOR (7U) /**< SET_DESCRIPTOR standard request */ +#define CY_USB_DEV_RQST_GET_CONFIGURATION (8U) /**< GET_CONFIGURATION standard request */ +#define CY_USB_DEV_RQST_SET_CONFIGURATION (9U) /**< SET_CONFIGURATION standard request */ +#define CY_USB_DEV_RQST_GET_INTERFACE (10U) /**< GET_INTERFACE standard request */ +#define CY_USB_DEV_RQST_SET_INTERFACE (11U) /**< SET_INTERFACE standard request */ +#define CY_USB_DEV_RQST_SYNCH_FRAME (12U) /**< SYNCH_FRAME standard request */ + +/* USB v2.0 spec: Table 9-6. Standard Feature Selectors */ +#define CY_USB_DEV_DEVICE_REMOTE_WAKEUP (1U) /**< REMOTE_WAKEUP feature selector */ +#define CY_USB_DEV_ENDPOINT_HALT (0U) /**< ENDPOINT_HALT feature selector */ +#define CY_USB_DEV_ENDPOINT_STATUS_HALT (1U) /**< ENDPOINT_STATUS_HALT feature selector */ +#define CY_USB_DEV_TEST_MODE (2U) /**< TEST_MODE feature selector */ + +/** \cond INTERNAL */ +/* Vendor Specific Request: Microsoft OS String Descriptor */ +#define CY_USB_DEV_RQST_GET_EXTENDED_CONFIG_DESCR (0x01U) + +/* Start position of SN string in SN string descriptor */ +#define CY_USB_DEV_STRING_DESCR_SN_STR_POS (2U) + +/* USB v2.0 spec: Table 9-5. Descriptor Types */ +#define CY_USB_DEV_GET_DESCR_TYPE(wValue) (CY_HI8(wValue)) +#define CY_USB_DEV_GET_DESCR_IDX(wValue) (CY_LO8(wValue)) + +/* Device status */ +#define CY_USB_DEV_STATUS_BUS_POWERED_MASK (0x0U) +#define CY_USB_DEV_STATUS_SELF_POWERED_MASK (0x1U) +#define CY_USB_DEV_STATUS_REMOTE_WAKEUP_MASK (0x2U) + +/* Endpoint direction bit */ +#define CY_USB_DEV_EP_IN_DIRECTION (0x80U) +#define CY_USB_DEV_EP_NUM_MASK (0x0FU) + +#define CY_USB_DEV_EPADDR2EP(endpointAddr) ((uint32_t) (endpointAddr) & CY_USB_DEV_EP_NUM_MASK) +#define CY_USB_DEV_IS_EP_DIR_IN(endpointAddr) (0U != ((endpointAddr) & CY_USB_DEV_EP_IN_DIRECTION)) +#define CY_USB_DEV_IS_EP_DIR_OUT(endpointAddr) (0U == ((endpointAddr) & CY_USB_DEV_EP_IN_DIRECTION)) + +#if (CY_CPU_CORTEX_M0P) + #define CY_USB_DEV_GET_CFG_WORD(addr) ( (uint16_t) (((uint16_t) (* (((uint8_t const volatile *) (addr)) + 1U))) << 8U) | \ + (* (( uint8_t const volatile *) (addr))) ) +#else + #define CY_USB_DEV_GET_CFG_WORD(addr) (* ((uint16_t const *) (addr)) ) +#endif + +/* +* These defines are obsolete and kept for backward compatibility only. +* They will be removed in the future versions. +*/ +#define CY_USB_DEV_VERSION_MAJOR (CY_USB_DEV_MW_VERSION_MAJOR) +#define CY_USB_DEV_VERSION_MINOR (CY_USB_DEV_MW_VERSION_MINOR) + +/** \endcond */ + +/** \} group_usb_dev_macros */ + + +/******************************************************************************* +* In-line Function Implementation +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_functions_service +* \{ +*/ +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterEventsCallback +****************************************************************************//** +* +* Registers a callback function to notify number of events: Bus Reset detected, +* SET_CONFIGURATION request received and SET_INTERFACE request received. +* To remove the callback function, pass NULL as the function pointer. +* +* \param callback +* The pointer to a callback function. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_RegisterEventsCallback(cy_cb_usb_dev_events_callback_t callback, + cy_stc_usb_dev_context_t *context) +{ + context->eventsCallback = callback; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_GetConfiguration +****************************************************************************//** +* +* Returns USB Device configuration. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Configuration value. The configuration value is 0 until USB Device +* was not enumerated by the USB Host. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_GetConfiguration(cy_stc_usb_dev_context_t const *context) +{ + return (uint32_t) context->configuration; +} + + +/** \cond INTERNAL */ +/******************************************************************************* +* Function Name: Cy_USB_Dev_GetConfigurationIdx +****************************************************************************//** +* +* This function returns current USB Device configuration index. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Configuration index. If device is not configured, returns 0. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_GetConfigurationIdx(cy_stc_usb_dev_context_t const *context) +{ + uint32_t configIdx = 0UL; + + if (CY_USB_DEV_CONFIGURED == context->state) + { + configIdx = (uint32_t) context->configuration - 1UL; + } + + return configIdx; +} +/** \endcond */ + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_GetAlternateSettings +****************************************************************************//** +* +* Returns alternate setting for a certain interface. +* This function is useful to determine which alternate settings are active for +* a certain interface. +* +* \param interface +* Interface number. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Alternate settings value. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_GetAlternateSettings(uint32_t interface, + cy_stc_usb_dev_context_t const *context) +{ + CY_ASSERT_L1(interface < CY_USB_DEV_NUM_INTERFACES_MAX); + + return (uint32_t) context->alternate[interface]; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_IsConfigurationChanged +****************************************************************************//** +* +* Returns configuration state that is cleared after read. +* This function is useful to determine which configuration or alternate settings +* of the interface were changed. After configuration state has been changed, +* \ref group_usb_dev_functions_data_transfer functions should be used to start +* communication with the USB Host. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* True - if configuration has been changed since last call. False - otherwise. +* +* \note +* This function is not interrupt-protected and to prevent a race condition, +* it should be protected from the USBFS interruption in the place where it +* is called. +* +*******************************************************************************/ +__STATIC_INLINE bool Cy_USB_Dev_IsConfigurationChanged(cy_stc_usb_dev_context_t *context) +{ + bool isChanged = context->configChanged; + + if (isChanged) + { + context->configChanged = false; + } + + return isChanged; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_SetPowerStatus +****************************************************************************//** +* +* Sets Power status to report it when USB Host issues GET_STATUS standard +* requests. Call this function any time when power source is changed from +* Self-Powered to Bus-Powered or vice versa. +* +* \param status +* Power status \ref cy_en_usb_dev_power_status_t +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_SetPowerStatus(cy_en_usb_dev_power_status_t status, + cy_stc_usb_dev_context_t *context) +{ + if (status == CY_USB_DEV_STATUS_SELF_POWERED) + { + context->status |= (uint8_t) CY_USB_DEV_STATUS_SELF_POWERED_MASK; + } + else + { + context->status &= (uint8_t) ~CY_USB_DEV_STATUS_SELF_POWERED_MASK; + } +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_IsRemoteWakeupEnabled +****************************************************************************//** +* +* Returns Remote Wakeup status. +* This function is useful to determine whether Remote Wakeup was enabled by the USB +* Host when USB Device supports this option. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* True - if Remote Wakeup was enabled by the USB Host. False - otherwise. +* +*******************************************************************************/ +__STATIC_INLINE bool Cy_USB_Dev_IsRemoteWakeupEnabled(cy_stc_usb_dev_context_t const *context) +{ + return (0U != (context->status & CY_USB_DEV_STATUS_REMOTE_WAKEUP_MASK)); +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_GetSerialNumberString +****************************************************************************//** +* +* Returns pointer to the serial number string generated from silicon ID. +* The string length is \ref CY_USB_DEV_SN_STRING_LENGTH. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* The pointer to the serial number string. +* +*******************************************************************************/ +__STATIC_INLINE uint8_t* Cy_USB_Dev_GetSerialNumberString(cy_stc_usb_dev_context_t *context) +{ + return &context->serialNumDescr[CY_USB_DEV_STRING_DESCR_SN_STR_POS]; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterSerialNumStringCallback +****************************************************************************//** +* +* Registers a callback function that returns the serial string descriptor when +* it is requested by the USB Host. +* +* \param callback +* The pointer to a callback function. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_RegisterSerialNumStringCallback(cy_fn_usb_dev_sn_string_ptr_t callback, + cy_stc_usb_dev_context_t *context) +{ + context->getSerialNumString = callback; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_SetupControlRead +****************************************************************************//** +* +* Setup control read (Host reads) transfer. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param ptr +* The pointer to the data which will be read by the Host. +* +* \param size +* Number of bytes to read. +* +* \return +* Returns \ref CY_USB_DEV_SUCCESS (there is input parameters verification). +* +*******************************************************************************/ +__STATIC_INLINE cy_en_usb_dev_status_t Cy_USB_Dev_SetupControlRead(cy_stc_usb_dev_control_transfer_t *transfer, + uint8_t *ptr, + uint32_t size) +{ + /* Setup control transfer (Host reads) */ + transfer->ptr = ptr; + transfer->remaining = (uint16_t) size; + + return CY_USB_DEV_SUCCESS; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_SetupControlWrite +****************************************************************************//** +* +* Setup control write transfer (Host writes) and sets \ref CY_USB_DEV_SUCCESS status +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param size +* Number of bytes which Host is allowed to write. +* +* \return +* Returns \ref CY_USB_DEV_SUCCESS (there is input parameters verification). +* +*******************************************************************************/ +__STATIC_INLINE cy_en_usb_dev_status_t Cy_USB_Dev_SetupControlWrite(cy_stc_usb_dev_control_transfer_t *transfer, + uint32_t size) +{ + /* Setup control transfer (Host writes) */ + transfer->remaining = (uint16_t) size; + transfer->notify = true; + + return CY_USB_DEV_SUCCESS; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_SetupControlWriteResult +****************************************************************************//** +* +* Copies data received from the Host into the specified memory location. There +* must provide enough place to store number of bytes provided in +* \ref Cy_USB_Dev_SetupControlWrite. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param ptr +* The pointer to the memory location to copy to. +* +* \return +* Returns \ref CY_USB_DEV_SUCCESS (there is input parameters verification). +* +*******************************************************************************/ +__STATIC_INLINE cy_en_usb_dev_status_t Cy_USB_Dev_SetupControlWriteResult(cy_stc_usb_dev_control_transfer_t const *transfer, + uint8_t *ptr) +{ + /* Copy data from internal buffer to the user provided location */ + (void) memcpy(ptr, transfer->buffer, (uint32_t) transfer->size); + + return CY_USB_DEV_SUCCESS; +} +/** \} group_usb_dev_functions_service */ + + +/** +* \addtogroup group_usb_dev_functions_data_transfer +* \{ +*/ +/******************************************************************************* +* Function Name: Cy_USB_Dev_GetEpNumToRead +****************************************************************************//** +* +* Returns the number of bytes that available to be read from a certain +* endpoint buffer. Before calling this function ensure that the Host wrote data +* into the endpoint. The returned value is updated after the Host access to the +* endpoint but remains unchanged after data has been read from the endpoint +* buffer. +* +* \param endpoint +* The OUT data endpoint number. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \return +* Number of bytes in OUT endpoint buffer. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_GetEpNumToRead(uint32_t endpoint, + cy_stc_usb_dev_context_t const *context) +{ + return Cy_USBFS_Dev_Drv_GetEndpointCount(context->drvBase, endpoint); +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_OverwriteHandleTimeout +****************************************************************************//** +* +* Overwrite the handle timeout function that is implemented internally. +* The internal implementation converts one timeout unit to milliseconds. +* +* \param handleTimeout +* The pointer to function to be executed to handle timeout for blocking +* operations. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_OverwriteHandleTimeout(cy_fn_usb_dev_handle_timeout_ptr_t handleTimeout, + cy_stc_usb_dev_context_t *context) +{ + context->handleTimeout = handleTimeout; +} +/** \} group_usb_dev_functions_data_transfer */ + +/** +* \addtogroup group_usb_dev_functions_class_support +* \{ +*/ +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterClassBusResetCallback +****************************************************************************//** +* +* Registers a callback function to notify a certain class about a Bus Reset event. +* To remove the callback function, pass NULL as the function pointer. +* +* \param callback +* The pointer to a callback function. +* +* \param classObj +* The pointer to the class structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_RegisterClassBusResetCallback(cy_cb_usb_dev_bus_reset_t callback, + cy_stc_usb_dev_class_t *classObj) +{ + classObj->busReset = callback; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterClassSetConfigCallback +****************************************************************************//** +* +* Registers a callback function to notify a certain class that SET_CONFIGURATION +* request was received from USB Host. +* To remove the callback function, pass a NULL as the function pointer. +* +* \param callback +* The pointer to a callback function. +* +* \param classObj +* The pointer to the class structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_RegisterClassSetConfigCallback(cy_cb_usb_dev_set_config_t callback, + cy_stc_usb_dev_class_t *classObj) + +{ + classObj->setConfiguration = callback; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterClassSetInterfaceCallback +****************************************************************************//** +* +* Registers a callback function to notify a certain class that SET_INTERFACE +* request was received from the USB Host. +* To remove the callback function, pass a NULL as the function pointer. +* +* \param callback +* The pointer to a callback function. +* +* \param classObj +* The pointer to the class structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_RegisterClassSetInterfaceCallback(cy_cb_usb_dev_set_interface_t callback, + cy_stc_usb_dev_class_t *classObj) +{ + classObj->setInterface = callback; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterClassRequestRcvdCallback +****************************************************************************//** +* +* Registers a callback function to notify a certain class that setup packet was +* received from USB Host but was not recognized. Therefore, this might require +* manual class processing. +* To remove the callback function, pass a NULL as the function pointer. +* +* \param callback +* The pointer to a callback function. +* +* \param classObj +* The pointer to the class structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_RegisterClassRequestRcvdCallback(cy_cb_usb_dev_request_received_t callback, + cy_stc_usb_dev_class_t *classObj) +{ + classObj->requestReceived = callback; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterClassRequestCmpltCallback +****************************************************************************//** +* +* Registers a callback function to notify a certain class that the USB Device +* received data from the USB Host as part of current request processing. +* The class setup packet callback function must enable notification to trigger +* this event. This makes sense only when class request processing requires a data +* stage. +* To remove callback function pass NULL as function pointer. +* +* \param callback +* The pointer to a callback function. +* +* \param classObj +* The pointer to the class structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_RegisterClassRequestCmpltCallback(cy_cb_usb_dev_request_cmplt_t callback, + cy_stc_usb_dev_class_t *classObj) +{ + classObj->requestCompleted = callback; +} +/** \} group_usb_dev_functions_class_support */ + +/** +* \addtogroup group_usb_dev_functions_vendor_support +* \{ +*/ +/******************************************************************************* +* Function Name: Cy_USB_Dev_RegisterVendorCallbacks +****************************************************************************//** +* +* Registering user callback to handle Vendor-Specific requests. +* +* \param requestReceivedHandle +* The pointer to a callback function. +* This function is called when setup packet was received from USB Host but was +* not recognized. Therefore this might require manual class processing. +* To remove the callback function, pass a NULL as the function pointer. +* +* \param requestCompletedHandle +* The pointer to a callback function. +* This function is called when the USB Device received data from the USB Host +* as part of current request processing. The requestReceivedHandle function +* must enable notification to trigger this event. This makes sense only when CDC +* request processing requires a data stage. +* To remove callback function pass NULL as function pointer. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for internal +* configuration and data retention. The user must not modify anything in this +* structure. +* +* \note +* The callbacks registered by this function does not overrides processing of +* MS OS String vendor-specific request to retrieve an OS Feature Descriptor. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_RegisterVendorCallbacks(cy_cb_usb_dev_request_received_t requestReceivedHandle, + cy_cb_usb_dev_request_cmplt_t requestCompletedHandle, + cy_stc_usb_dev_context_t *context) +{ + context->vndRequestReceived = requestReceivedHandle; + context->vndRequestCompleted = requestCompletedHandle; +} +/** \} group_usb_dev_functions_vendor_support */ + +/** \} group_usb_dev */ + +#if defined(__cplusplus) +} +#endif + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + +#endif /* (CY_USB_DEV_H) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio.c b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio.c new file mode 100644 index 0000000000000000000000000000000000000000..11af18741036e77ad2cdd5112e7b77141c8ff863 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio.c @@ -0,0 +1,65 @@ +/***************************************************************************//** +* \file cy_usb_dev_audio.c +* \version 2.10 +* +* Provides Audio class-specific API implementation. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + +#include "cy_usb_dev_audio.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +/******************************************************************************* +* Function Name: Cy_USB_Dev_Audio_Init +****************************************************************************//** +* +* Initializes the Audio class. +* This function must be called to enable USB Device Audio functionality. +* +* \param config +* Pass NULL as an argument (left for future purposes). +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_audio_context_t +* allocated by the user. The structure is used during the Audio Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \param devContext +* The pointer to the USB Device context structure \ref cy_stc_usb_dev_context_t. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_Audio_Init(void const *config, + cy_stc_usb_dev_audio_context_t *context, + cy_stc_usb_dev_context_t *devContext) +{ + /* Suppress a compiler warning about unused variables */ + (void) config; + + if ((NULL == context) || (NULL == devContext)) + { + return CY_USB_DEV_BAD_PARAM; + } + + /* Store device context */ + context->devContext = devContext; + + return Cy_USB_Dev_RegisterClass(&context->classItem, &context->classObj, context, devContext); +} + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + + +/* [] END OF FILE */ + diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio.h new file mode 100644 index 0000000000000000000000000000000000000000..175a4e5a3a130003c4229066276d2bb12b961d9e --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio.h @@ -0,0 +1,217 @@ +/***************************************************************************//** +* \file cy_usb_dev_audio.h +* \version 2.10 +* +* Provides Audio class-specific API declarations. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_audio +* This section provides API description for the Audio class. +* \{ +* \defgroup group_usb_dev_audio_macros Macros +* \defgroup group_usb_dev_audio_functions Functions +* \defgroup group_usb_dev_audio_data_structures Data Structures +* \} +*/ + +#if !defined(CY_USB_DEV_AUDIO_H) +#define CY_USB_DEV_AUDIO_H + +#include "cy_usb_dev.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +#if defined(__cplusplus) +extern "C" { +#endif + + +/******************************************************************************* +* Enumerated Types +*******************************************************************************/ + + +/******************************************************************************* +* Type Definitions +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_audio_data_structures +* \{ +*/ + +/** Audio class context structure. +* All fields for the Audio context structure are internal. Firmware never reads or +* writes these values. Firmware allocates the structure and provides the +* address of the structure to the middleware in Audio function calls. Firmware +* must ensure that the defined instance of this structure remains in scope while +* the middleware is in use. +*/ +typedef struct +{ + /** \cond INTERNAL*/ + + /** Pointer to device context */ + cy_stc_usb_dev_context_t *devContext; + + /** Audio class functions pointers */ + cy_stc_usb_dev_class_t classObj; + + /** Audio class linked list item */ + cy_stc_usb_dev_class_ll_item_t classItem; + + /** \endcond */ + +} cy_stc_usb_dev_audio_context_t; + +/** \} group_usb_dev_audio_data_structures */ + + +/******************************************************************************* +* Function Prototypes +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_audio_functions +* \{ +*/ +cy_en_usb_dev_status_t Cy_USB_Dev_Audio_Init(void const *config, + cy_stc_usb_dev_audio_context_t *context, + cy_stc_usb_dev_context_t *devContext); + +__STATIC_INLINE void Cy_USB_Dev_Audio_RegisterUserCallback(cy_cb_usb_dev_request_received_t requestReceivedHandle, + cy_cb_usb_dev_request_cmplt_t requestCompletedHandle, + cy_stc_usb_dev_audio_context_t *context); + +__STATIC_INLINE cy_stc_usb_dev_class_t * Cy_USB_Dev_Audio_GetClass(cy_stc_usb_dev_audio_context_t *context); +/** \} group_usb_dev_audio_functions */ + + +/******************************************************************************* +* API Constants +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_audio_macros +* \{ +*/ +#define CY_USB_DEV_AUDIO_RQST_GET_CUR (0x81u) /**< GET_CUR Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_GET_MIN (0x82u) /**< GET_MIN Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_GET_MAX (0x83u) /**< GET_MAX Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_GET_RES (0x84u) /**< GET_RES Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_GET_MEM (0x85u) /**< GET_MEM Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_GET_STAT (0xFFu) /**< GET_STAT Audio v1.0 request */ + +#define CY_USB_DEV_AUDIO_RQST_SET_CUR (0x01u) /**< SET_CUR Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_SET_MIN (0x02u) /**< SET_MIN Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_SET_MAX (0x03u) /**< SET_MAX Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_SET_RES (0x04u) /**< SET_RES Audio v1.0 request */ +#define CY_USB_DEV_AUDIO_RQST_SET_MEM (0x05u) /**< SET_STAT Audio v1.0 request */ + +#define CY_USB_DEV_AUDIO2_RQST_CUR (0x01u) /**< CUR Audio v2.0 request */ +#define CY_USB_DEV_AUDIO2_RQST_RANGE (0x02u) /**< RANGE Audio v2.0 request */ +#define CY_USB_DEV_AUDIO2_RQST_MEM (0x03u) /**< MEM Audio v2.0 request */ + +#define CY_USB_DEV_AUDIO_MASTER_CHANNEL (0U) /**< Master channel */ +#define CY_USB_DEV_AUDIO_VOLUME_MIN (0x8001U) /**< Volume minimum value */ +#define CY_USB_DEV_AUDIO_VOLUME_MAX (0x7FFFU) /**< Volume maximum value */ +#define CY_USB_DEV_AUDIO_VOLUME_SILENCE (0x8000U) /**< Volume value that represent silence (CUR attribute only) */ +#define CY_USB_DEV_AUDIO_VOLUME_MIN_MSB (0x80U) /**< Volume minimum value MSB */ +#define CY_USB_DEV_AUDIO_VOLUME_MIN_LSB (0x01U) /**< Volume minimum value LSB */ +#define CY_USB_DEV_AUDIO_VOLUME_MAX_MSB (0x7FU) /**< Volume maximum value MSB */ +#define CY_USB_DEV_AUDIO_VOLUME_MAX_LSB (0xFFU) /**< Volume maximum value LSB */ +/** \} group_usb_dev_audio_macros */ + + +/******************************************************************************* +* Internal Constants +*******************************************************************************/ + + +/******************************************************************************* +* In-line Function Implementation +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_audio_functions +* \{ +*/ + +/******************************************************************************* +* Function Name: Cy_USB_Dev_Audio_RegisterUserCallback +****************************************************************************//** +* +* Registers the user callbacks to handle Audio class requests. +* +* \param requestReceivedHandle +* The pointer to a callback function. +* This function is called when setup packet was received from the USB Host but was +* not recognized. Therefore this might require Audio class processing. +* To remove the callback function, pass a NULL as the function pointer. +* +* \param requestCompletedHandle +* The pointer to a callback function. +* This function is called when the USB Device received data from the USB Host +* as part of current request processing. The requestReceivedHandle function +* must enable notification to trigger this event. This makes sense only when class +* request processing requires a data stage. +* To remove the callback function, pass a NULL as the function pointer. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the Audio Class operation for +* internal configuration and data retention. The user must not modify anything +* in this structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_Audio_RegisterUserCallback(cy_cb_usb_dev_request_received_t requestReceivedHandle, + cy_cb_usb_dev_request_cmplt_t requestCompletedHandle, + cy_stc_usb_dev_audio_context_t *context) +{ + Cy_USB_Dev_RegisterClassRequestRcvdCallback(requestReceivedHandle, Cy_USB_Dev_Audio_GetClass(context)); + Cy_USB_Dev_RegisterClassRequestCmpltCallback(requestCompletedHandle, Cy_USB_Dev_Audio_GetClass(context)); +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_Audio_GetClass +****************************************************************************//** +* +* Returns pointer to the class structure for Audio class. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the Audio Class operation for +* internal configuration and data retention. The user must not modify anything +* in this structure. +* +* \return +* Status pointer to the class \ref cy_stc_usb_dev_class_t. +* +*******************************************************************************/ +__STATIC_INLINE cy_stc_usb_dev_class_t * Cy_USB_Dev_Audio_GetClass(cy_stc_usb_dev_audio_context_t *context) +{ + return &(context->classObj); +} + +/** \} group_usb_dev_audio_functions */ + +#if defined(__cplusplus) +} +#endif + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + +#endif /* (CY_USB_DEV_AUDIO_H) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio_descr.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio_descr.h new file mode 100644 index 0000000000000000000000000000000000000000..7aa47e07c1a82a31df3da025afb08785fa04efd4 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_audio_descr.h @@ -0,0 +1,273 @@ +/***************************************************************************//** +* \file cy_usb_dev_audio_descr.h +* \version 2.10 +* +* Provides Audio class-specific descriptor defines. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + +#if !defined(CY_USB_DEV_AUDIO_DESCR_H) +#define CY_USB_DEV_AUDIO_DESCR_H + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +#if defined(__cplusplus) +extern "C" { +#endif + + +/******************************************************************************* +* USB AUDIO +*******************************************************************************/ + +/** \cond INTERNAL */ +/** +* Audio Interface Class, Subclass and Protocol Codes +*/ +#define CY_USB_DEV_AUDIO_CLASS (0x01U) +#define CY_USB_DEV_AUDIO_SUBCLASS_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO_SUBCLASS_AUDIO_CONTROL (0x01U) +#define CY_USB_DEV_AUDIO_SUBCLASS_AUDIO_STREAMING (0x02U) +#define CY_USB_DEV_AUDIO_SUBCLASS_MIDI_STREAMING (0x03U) +#define CY_USB_DEV_AUDIO_PROTOCOL_UNDEFINED (0x00U) + +/** +* Audio Class-Specific Descriptor Types +*/ +#define CY_USB_DEV_AUDIO_CS_UNDEFINED (0x20U) +#define CY_USB_DEV_AUDIO_CS_DEVICE (0x21U) +#define CY_USB_DEV_AUDIO_CS_CONFIGURATION (0x22U) +#define CY_USB_DEV_AUDIO_CS_STRING (0x23U) +#define CY_USB_DEV_AUDIO_CS_INTERFACE (0x24U) +#define CY_USB_DEV_AUDIO_CS_ENDPOINT (0x25U) + + +/******************************************************************************* +* USB AUDIO version 1.0 +*******************************************************************************/ + +/** +* Audio Class-Specific AC Interface Descriptor Subtypes +*/ +#define CY_USB_DEV_AUDIO_AC_DESCRIPTOR_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO_HEADER (0x01U) +#define CY_USB_DEV_AUDIO_INPUT_TERMINAL (0x02U) +#define CY_USB_DEV_AUDIO_OUTPUT_TERMINAL (0x03U) +#define CY_USB_DEV_AUDIO_MIXER_UNIT (0x04U) +#define CY_USB_DEV_AUDIO_SELECTOR_UNIT (0x05U) +#define CY_USB_DEV_AUDIO_FEATURE_UNIT (0x06U) +#define CY_USB_DEV_AUDIO_PROCESSING_UNIT (0x07U) +#define CY_USB_DEV_AUDIO_EXTENSION_UNIT (0x08U) + +/** +* Audio Class-Specific AS Interface Descriptor Subtypes +*/ +#define CY_USB_DEV_AUDIO_AS_DESCRIPTOR_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO_AS_GENERAL (0x01U) +#define CY_USB_DEV_AUDIO_FORMAT_TYPE (0x02U) +#define CY_USB_DEV_AUDIO_FORMAT_SPECIFIC (0x03U) + +/** +* Processing Unit Process Types +*/ +#define CY_USB_DEV_AUDIO_PROCESS_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO_UP_DOWNMIX_PROCESS (0x01U) +#define CY_USB_DEV_AUDIO_DOLBY_PROLOGIC_PROCESS (0x02U) +#define CY_USB_DEV_AUDIO_3D_STEREO_EXTENDER_PROCESS (0x03U) +#define CY_USB_DEV_AUDIO_REVERBERATION_PROCESS (0x04U) +#define CY_USB_DEV_AUDIO_CHORUS_PROCESS (0x05U) +#define CY_USB_DEV_AUDIO_DYN_RANGE_COMP_PROCESS (0x06U) + +/** +* Audio Class-Specific Endpoint Descriptor Subtypes +*/ +#define CY_USB_DEV_AUDIO_DESCRIPTOR_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO_EP_GENERAL (0x01U) + +/** +* Terminal Control Selectors +*/ +#define USB_AUDIO_TE_CONTROL_UNDEFINED (0x00U) +#define USB_AUDIO_COPY_PROTECT_CONTROL (0x01U) + +/** +* Feature Unit Control Selectors +*/ +#define CY_USB_DEV_AUDIO_FU_CONTROL_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO_MUTE_CONTROL (0x01U) +#define CY_USB_DEV_AUDIO_VOLUME_CONTROL (0x02U) +#define CY_USB_DEV_AUDIO_BASS_CONTROL (0x03U) +#define CY_USB_DEV_AUDIO_MID_CONTROL (0x04U) +#define CY_USB_DEV_AUDIO_TREBLE_CONTROL (0x05U) +#define CY_USB_DEV_AUDIO_GRAPHIC_EQUALIZER_CONTROL (0x06U) +#define CY_USB_DEV_AUDIO_AUTOMATIC_GAIN_CONTROL (0x07U) +#define CY_USB_DEV_AUDIO_DELAY_CONTROL (0x08U) +#define CY_USB_DEV_AUDIO_BASS_BOOST_CONTROL (0x09U) +#define CY_USB_DEV_AUDIO_LOUDNESS_CONTROL (0x0AU) + +/** +* Endpoint Control Selectors +*/ +#define CY_USB_DEV_AUDIO_EP_CONTROL_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO_SAMPLING_FREQ_CONTROL (0x01U) +#define CY_USB_DEV_AUDIO_PITCH_CONTROL (0x02U) + +/** +* Descriptor Sizes +*/ +#define CY_USB_DEV_AUDIO_AC_HEADER_SIZE(a) (8U + (a)) +#define CY_USB_DEV_AUDIO_AC_IN_TERM_LENGTH (0x0CU) +#define CY_USB_DEV_AUDIO_AC_FE_UNIT_LENGTH (0x09U) +#define CY_USB_DEV_AUDIO_AC_OUT_TERM_LENGTH (0x09U) +#define CY_USB_DEV_AUDIO_AS_GEN_IF_LENGTH (0x07U) +#define CY_USB_DEV_AUDIO_AS_FORMAT_I_LENGTH (0x0BU) + +/** +* Endpoint Control Selectors (AUDIO Table A-19) +*/ +#define CY_USB_DEV_AUDIO_CS_SAMPLING_FREQ_CTRL (0x01U) /**< Audio v1.0: sample frequency control selector */ +#define CY_USB_DEV_AUDIO_CS_PITCH_CTRL (0x02U) /**< Audio v1.0: pitch control selector */ + +/** +* Feature Unit Control Selectors (AUDIO Table A-11) +*/ +#define CY_USB_DEV_AUDIO_CS_MUTE_CONTROL (0x01U) /**< Audio v1.0: mute control selector */ +#define CY_USB_DEV_AUDIO_CS_VOLUME_CONTROL (0x02U) /**< Audio v1.0: volume control selector */ +#define CY_USB_DEV_AUDIO_CS_BASS_CONTROL (0x03U) /**< Audio v1.0: bass control selector */ +#define CY_USB_DEV_AUDIO_CS_MID_CONTROL (0x04U) /**< Audio v1.0: mid control selector */ +#define CY_USB_DEV_AUDIO_CS_TREBLE_CONTROL (0x05U) /**< Audio v1.0: treble control selector */ +#define CY_USB_DEV_AUDIO_CS_GRAPHIC_EQUALIZER_CONTROL (0x06U) /**< Audio v1.0: graphic equalizer control selector */ +#define CY_USB_DEV_AUDIO_CS_AUTOMATIC_GAIN_CONTROL (0x07U) /**< Audio v1.0: automatic gain control selector */ +#define CY_USB_DEV_AUDIO_CS_DELAY_CONTROL (0x08U) /**< Audio v1.0: delay control selector */ +#define CY_USB_DEV_AUDIO_CS_BASS_BOOST_CONTROL (0x09U) /**< Audio v1.0: bass control selector */ +#define CY_USB_DEV_AUDIO_CS_LOUDNESS_CONTROL (0x0AU) /**< Audio v1.0: loudness control selector */ + + +/******************************************************************************* +* USB AUDIO version 1.0 +*******************************************************************************/ + +/** +* Audio Interface Protocol Codes +*/ +#define CY_USB_DEV_AUDIO2_INTERFACE_PROTOCOL_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_IP_VERSION_02_00 (0x20U) + +/** +* A.7 Audio Function Category Codes +*/ +#define CY_USB_DEV_AUDIO2_FUNCTION_SUBCLASS_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_FUNCTION_DESKTOP_SPEAKER (0x01U) +#define CY_USB_DEV_AUDIO2_FUNCTION_HOME_THEATER (0x02U) +#define CY_USB_DEV_AUDIO2_FUNCTION_MICROPHONE (0x03U) +#define CY_USB_DEV_AUDIO2_FUNCTION_HEADSET (0x04U) +#define CY_USB_DEV_AUDIO2_FUNCTION_TELEPHONE (0x05U) +#define CY_USB_DEV_AUDIO2_FUNCTION_CONVERTER (0x06U) +#define CY_USB_DEV_AUDIO2_FUNCTION_SOUND_RECORDER (0x07U) +#define CY_USB_DEV_AUDIO2_FUNCTION_IO_BOX (0x08U) +#define CY_USB_DEV_AUDIO2_FUNCTION_MUSICAL_INSTRUMENT (0x09U) +#define CY_USB_DEV_AUDIO2_FUNCTION_PRO_AUDIO (0x0AU) +#define CY_USB_DEV_AUDIO2_FUNCTION_AUDIO_VIDEO (0x0BU) +#define CY_USB_DEV_AUDIO2_FUNCTION_CONTROL_PANEL (0x0CU) +#define CY_USB_DEV_AUDIO2_FUNCTION_OTHER (0xFFU) + +/** +* A.9 Audio Class-Specific AC Interface Descriptor Subtypes +*/ +#define CY_USB_DEV_AUDIO2_AC_DESCRIPTOR_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_HEADER (0x01U) +#define CY_USB_DEV_AUDIO2_INPUT_TERMINAL (0x02U) +#define CY_USB_DEV_AUDIO2_OUTPUT_TERMINAL (0x03U) +#define CY_USB_DEV_AUDIO2_MIXER_UNIT (0x04U) +#define CY_USB_DEV_AUDIO2_SELECTOR_UNIT (0x05U) +#define CY_USB_DEV_AUDIO2_FEATURE_UNIT (0x06U) +#define CY_USB_DEV_AUDIO2_EFFECT_UNIT (0x07U) +#define CY_USB_DEV_AUDIO2_PROCESSING_UNIT_V2 (0x08U) +#define CY_USB_DEV_AUDIO2_EXTENSION_UNIT_V2 (0x09U) +#define CY_USB_DEV_AUDIO2_CLOCK_SOURCE (0x0AU) +#define CY_USB_DEV_AUDIO2_CLOCK_SELECTOR (0x0BU) +#define CY_USB_DEV_AUDIO2_CLOCK_MULTIPLIER (0x0CU) +#define CY_USB_DEV_AUDIO2_SAMPLE_RATE_CONVERTER (0x0DU) + +/** +* Audio Class-Specific AS Interface Descriptor Subtypes +*/ +#define CY_USB_DEV_AUDIO2_AS_DESCRIPTOR_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_AS_GENERAL (0x01U) +#define CY_USB_DEV_AUDIO2_FORMAT_TYPE (0x02U) +#define CY_USB_DEV_AUDIO2_ENCODER (0x03U) +#define CY_USB_DEV_AUDIO2_DECODER (0x04U) + +/** +* Audio Class-Specific Endpoint Descriptor Subtypes +*/ +#define CY_USB_DEV_AUDIO2_DESCRIPTOR_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_EP_GENERAL (0x01U) + +/** +* Clock Source Control Selectors +*/ +#define CY_USB_DEV_AUDIO2_CS_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_CS_CONTROL_SAM_FREQ (0x01U) +#define CY_USB_DEV_AUDIO2_CS_CONTROL_CLOCK_VALID (0x02U) + +/** +* Clock Selector Control Selectors +*/ +#define CY_USB_DEV_AUDIO2_CX_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_CX_CLOCK_SELECTOR (0x01U) + +/** +* Clock Multiplier Control Selectors +*/ +#define CY_USB_DEV_AUDIO2_CM_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_CM_NUMERATOR (0x01U) +#define CY_USB_DEV_AUDIO2_CM_DENOMINTATOR (0x02U) + +/** +* Terminal Control Selectors +*/ +#define CY_USB_DEV_AUDIO2_TE_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_TE_COPY_PROTECT (0x01U) +#define CY_USB_DEV_AUDIO2_TE_CONNECTOR (0x02U) +#define CY_USB_DEV_AUDIO2_TE_OVERLOAD (0x03U) +#define CY_USB_DEV_AUDIO2_TE_CLUSTER (0x04U) +#define CY_USB_DEV_AUDIO2_TE_UNDERFLOW (0x05U) +#define CY_USB_DEV_AUDIO2_TE_OVERFLOW (0x06U) +#define CY_USB_DEV_AUDIO2_TE_LATENCY (0x07U) + +/** +* AudioStreaming Interface Control Selectors +*/ +#define CY_USB_DEV_AUDIO2_AS_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_AS_ACT_ALT_SETTING (0x01U) +#define CY_USB_DEV_AUDIO2_AS_VAL_ALT_SETTINGS (0x02U) +#define CY_USB_DEV_AUDIO2_AS_AUDIO_DATA_FORMAT (0x03U) + +/** +* Endpoint Control Selectors +*/ +#define CY_USB_DEV_AUDIO2_EP_CS_UNDEFINED (0x00U) +#define CY_USB_DEV_AUDIO2_EP_CS_PITCH (0x01U) +#define CY_USB_DEV_AUDIO2_EP_CS_DATA_OVERRUN (0x02U) +#define CY_USB_DEV_AUDIO2_EP_CS_DATA_UNDERRUN (0x03U) + +/** \endcond */ + +#if defined(__cplusplus) +} +#endif + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + +#endif /* (CY_USB_DEV_AUDIO_DESCR_H) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc.c b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..d90f62838707f075cba8a9012ae153b7436ebcf5 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc.c @@ -0,0 +1,1153 @@ + +/***************************************************************************//** +* \file cy_usb_dev_cdc.c +* \version 2.10 +* +* Provides Class Specific API implementation. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + +#include "cy_usb_dev_cdc.h" +#include "cy_usb_dev_cdc_descr.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + + +/******************************************************************************* +* Internal Constants +*******************************************************************************/ + +#define COM1 (0U) +#define COM2 (1U) +#define INVALID_COM (0xFFU) +#define IS_COM_VALID(com) CY_USB_DEV_CDC_IS_COM_VALID(com) + +#define SET_LINE_CODING_LENGTH (7U) +#define LINE_CODING_RATE_OFFSET (0U) + +#define SERIAL_STATE_REQUEST_TYPE (0xA1U) +#define SERIAL_STATE (0x20U) +#define SERIAL_STATE_LENGTH (0x2U) + +#define SERIAL_STATE_WINDEX_OFFSET (4U) +#define SERIAL_STATE_WSERIALSTATE_LSB_OFFSET (8U) +#define SERIAL_STATE_WSERIALSTATE_MSB_OFFSET (9U) + +#define SINGLE_COM_PORT_EP_NUM (3U) +#define DUAL_COM_PORT_EP_NUM (6U) + +#define INTERFACE_CLASS_POS (5U) + +#define INIT_LINES_CODING \ +{ \ + /* dwDTERate: Data terminal rate, in bits per second */ \ + 0x00U, 0xC2U, 0x01U, 0x00U, \ + /* bCharFormat (Stop bits): 0 - 1bit, 1 - 1.5bits, 2 - 2bits */ \ + 0x00U, \ + /* bParityType: Parity 0 - None, 1 - Odd, 2 - Even, 3 - Mark, 4 - Space */ \ + 0x00U, \ + /* Data bits (5, 6, 7, 8 or 16) */ \ + 0x08U \ +} + +#define INIT_SERIAL_STATE \ +{ \ + SERIAL_STATE_REQUEST_TYPE,/* bRequestType */ \ + SERIAL_STATE, /* bNotification */ \ + 0U, /* wValue */ \ + 0U, /* wValueMSB */ \ + 0U, /* wIndex */ \ + 0U, /* wIndexMSB */ \ + SERIAL_STATE_LENGTH, /* wLength */ \ + 0u, /* wLengthMSB */ \ + 0U, /* wSerialState */ \ + 0U, /* wSerialStateMSB */ \ +} + + +/******************************************************************************* +* Internal Functions +*******************************************************************************/ + +static cy_en_usb_dev_status_t HandleRequest(cy_stc_usb_dev_control_transfer_t *transfer, void *classContext, + cy_stc_usb_dev_context_t *devContext); + +static cy_en_usb_dev_status_t HandleRequestComplete(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + cy_stc_usb_dev_context_t *devContext); + +static cy_en_usb_dev_status_t HandleSetConfig(uint32_t configuration, + void *classContext, + cy_stc_usb_dev_context_t *devContext); + +static uint32_t GetInterfaceComPort(uint32_t interface, cy_stc_usb_dev_cdc_context_t const *context); + +static uint32_t ReadInternalBuffer(cy_stc_usb_dev_cdc_comport_t* port, uint8_t *buffer, + uint32_t size); + +static bool IsEndpointReady(uint32_t endpoint, cy_stc_usb_dev_context_t const *context); + +static cy_stc_usb_dev_cdc_comport_t* GetCom(uint32_t port, cy_stc_usb_dev_cdc_context_t *context); + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_Init +****************************************************************************//** +* +* Initializes the CDC class. +* This function must be called to enable USB Device CDC functionality. +* +* \param config +* The pointer to the CDC configuration +* structure \ref cy_stc_usb_dev_cdc_config_t. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \param devContext +* The pointer to the USB Device context structure \ref cy_stc_usb_dev_context_t. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_CDC_Init(cy_stc_usb_dev_cdc_config_t const *config, + cy_stc_usb_dev_cdc_context_t *context, + cy_stc_usb_dev_context_t *devContext) +{ + if ((NULL == context) || (NULL == devContext)) + { + return CY_USB_DEV_BAD_PARAM; + } + + uint32_t portIndex; + + for (portIndex = 0UL; (portIndex < CY_USB_DEV_CDC_COMPORT_NUMBER); portIndex++) + { + /* Default value for Lines Coding and Serial State notification */ + const uint8_t initLinesCoding[CY_USB_DEV_CDC_LINE_CODING_SIZE] = INIT_LINES_CODING; + const uint8_t initSerialState[CY_USB_DEV_CDC_SERIAL_STATE_SIZE] = INIT_SERIAL_STATE; + + /* Get COM port */ + cy_stc_usb_dev_cdc_comport_t* com = &context->port[portIndex]; + + /* Initialize default values: lines coding and serial state */ + (void) memcpy((void *) com->linesCoding, (const void *)initLinesCoding, CY_USB_DEV_CDC_LINE_CODING_SIZE); + (void) memcpy((void *) com->serialStateNotification, (const void *)initSerialState, CY_USB_DEV_CDC_SERIAL_STATE_SIZE); + + /* Set COM port disable */ + com->valid = false; + com->writeBufIdx = 0U; + com->readBufIdx = 0U; + com->linesChanged = CY_USB_DEV_CDC_LINE_NOT_CHANGED; + + /* Copy data from configuration */ + com->buffer = (NULL != config) ? config->buffer[portIndex] : NULL; + com->bufferSize = (NULL != config) ? config->bufferSize[portIndex] : 0U; + } + + /* Remove custom handlers */ + context->requestCompleted = NULL; + context->requestReceived = NULL; + + /* Store device context */ + context->devContext = devContext; + + /* Register CDC handlers */ + Cy_USB_Dev_RegisterClassSetConfigCallback(&HandleSetConfig, Cy_USB_Dev_CDC_GetClass(context)); + Cy_USB_Dev_RegisterClassRequestRcvdCallback(&HandleRequest, Cy_USB_Dev_CDC_GetClass(context)); + Cy_USB_Dev_RegisterClassRequestCmpltCallback(&HandleRequestComplete, Cy_USB_Dev_CDC_GetClass(context)); + + return Cy_USB_Dev_RegisterClass(&context->classItem, &context->classObj, context, devContext); +} + + +/******************************************************************************* +* Function Name: HandleSetConfig +****************************************************************************//** +* +* Handles SET_CONFIGURATION request event. This function finds COM ports +* information for a certain configuration: CDC interfaces and CDC endpoints. +* This information is used to call any CDC function. +* +* \param configuration +* The CDC configuration index. +* +* \param classContext +* The pointer to the context structure of the Class +* \ref cy_stc_usb_dev_cdc_context_t allocated by the user. +* +* \param devContext +* The pointer to the context structure of the Device +* \ref cy_stc_usb_dev_context_t allocated by the user. +* +* \return +* Returns \ref CY_USB_DEV_SUCCESS. +* The configuration is still valid if COM port is not found. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleSetConfig(uint32_t configuration, + void *classContext, + cy_stc_usb_dev_context_t *devContext) +{ + /* Get CDC context */ + cy_stc_usb_dev_cdc_context_t *context = (cy_stc_usb_dev_cdc_context_t *) classContext; + + /* Invalidate COM ports */ + context->port[COM1].valid = false; + context->port[COM2].valid = false; + + if (configuration > 0U) + { + /* Get current configuration */ + cy_stc_usb_dev_configuration_t const *config = devContext->devDescriptors->configurations[configuration - 1U]; + + uint32_t intf; + uint32_t portInt = 0U; + uint32_t portData = 0U; + uint32_t cdcEpNum = 0U; + + for (intf = 0U; intf < config->numInterfaces; ++intf) + { + /* CDC does not support alternate settings */ + uint32_t alt = 0U; + + /* Get alternate settings that belong to this interface */ + cy_stc_usb_dev_alternate_t const **altStructs = config->interfaces[intf]->alternates; + + /* Get pointer to current alternate descriptor */ + cy_stc_usbdev_interface_descr_t const *curAlternate = (cy_stc_usbdev_interface_descr_t const *) + ((const void *)(altStructs[alt]->interfaceDescriptor)); + + /* Check interface class */ + if (CY_USB_DEV_CDC_CLASS == curAlternate->bInterfaceClass) + { + /* Get endpoint descriptor */ + cy_stc_usbdev_endpoint_descr_t const *ep = (cy_stc_usbdev_endpoint_descr_t const *) + ((const void *)(altStructs[alt]->endpoints[0U]->endpointDescriptor)); + + context->port[portInt].interfaceNum = (uint8_t) intf; + + context->port[portInt].commEp = (uint8_t) CY_USB_DEV_EPADDR2EP(ep->bEndpointAddress); + context->port[portInt].commEpSize = CY_USB_DEV_GET_CFG_WORD(&ep->wMaxPacketSize); + context->port[portInt].serialStateNotification[SERIAL_STATE_WINDEX_OFFSET] = (uint8_t) intf; + + portInt = 1U; + cdcEpNum++; + } + else if (CY_USB_DEV_CDC_CLASS_DATA == curAlternate->bInterfaceClass) + { + uint32_t endpoint; + + /* Check all endpoints that belong to interface */ + for (endpoint = 0U; endpoint < altStructs[alt]->numEndpoints; ++endpoint) + { + /* Get endpoint descriptor */ + cy_stc_usbdev_endpoint_descr_t const *ep = (cy_stc_usbdev_endpoint_descr_t const *) + ((const void *)(altStructs[alt]->endpoints[endpoint]->endpointDescriptor)); + + if (CY_USB_DEV_IS_EP_DIR_IN(ep->bEndpointAddress)) + { + context->port[portData].dataInEp = (uint8_t) CY_USB_DEV_EPADDR2EP(ep->bEndpointAddress); + context->port[portData].dataInEpSize = CY_USB_DEV_GET_CFG_WORD(&ep->wMaxPacketSize); + } + else + { + context->port[portData].dataOutEp = (uint8_t) CY_USB_DEV_EPADDR2EP(ep->bEndpointAddress); + context->port[portData].dataOutEpSize = CY_USB_DEV_GET_CFG_WORD(&ep->wMaxPacketSize); + + /* Enable endpoint to receive data from Host. + * Discard status after set configuration is safe. + */ + (void) Cy_USB_Dev_StartReadEp((uint32_t) context->port[portData].dataOutEp, devContext); + } + + cdcEpNum++; + } + + portData = 1U; + } + else + { + /* Skip: Interface Class is not CDC */ + } + } + + context->port[COM1].valid = (cdcEpNum >= SINGLE_COM_PORT_EP_NUM); + context->port[COM2].valid = (DUAL_COM_PORT_EP_NUM == cdcEpNum); + } + + /* If comport is not found, it is marked not valid */ + return CY_USB_DEV_SUCCESS; +} + + +/******************************************************************************* +* Function Name: HandleRequest +****************************************************************************//** +* +* Handles CDC class requests (SETUP packet received event). +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param classContext +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \param devContext +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for +* internal configuration and data retention. The user must not modify anything +* in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleRequest(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + cy_stc_usb_dev_context_t *devContext) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Process CDC Class requests */ + if (CY_USB_DEV_CLASS_TYPE == transfer->setup.bmRequestType.type) + { + cy_stc_usb_dev_cdc_context_t *context = (cy_stc_usb_dev_cdc_context_t *) classContext; + + uint32_t portNum = GetInterfaceComPort((uint32_t) transfer->setup.wIndex, context); + + if (IS_COM_VALID(portNum)) + { + switch (transfer->setup.bRequest) + { + case CY_USB_DEV_CDC_RQST_SET_LINE_CODING: + { + transfer->remaining = SET_LINE_CODING_LENGTH; + transfer->notify = true; + retStatus = CY_USB_DEV_SUCCESS; + } + break; + + case CY_USB_DEV_CDC_RQST_GET_LINE_CODING: + { + transfer->ptr = (uint8_t *) context->port[portNum].linesCoding; + transfer->remaining = SET_LINE_CODING_LENGTH; + retStatus = CY_USB_DEV_SUCCESS; + } + break; + + case CY_USB_DEV_CDC_RQST_SET_CONTROL_LINE_STATE: + { + context->port[portNum].linesControlBitmap = (uint8_t) transfer->setup.wValue; + context->port[portNum].linesChanged |= CY_USB_DEV_CDC_LINE_CONTROL_CHANGED; + retStatus = CY_USB_DEV_SUCCESS; /* There is Data stage */ + } + break; + + default: + { + /* Request was not recognized. Try custom request handler. */ + if (NULL != context->requestReceived) + { + retStatus = context->requestReceived(transfer, context, devContext); + } + } + break; + } + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: HandleRequestComplete +****************************************************************************//** +* +* Completes handling CDC class requests that expect data from the Host. +* Involved when data from the Host has been received. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param classContext +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \param devContext +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for +* internal configuration and data retention. The user must not modify anything +* in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleRequestComplete(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + cy_stc_usb_dev_context_t *devContext) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Process CDC Class requests */ + if (CY_USB_DEV_CLASS_TYPE == transfer->setup.bmRequestType.type) + { + cy_stc_usb_dev_cdc_context_t *context = (cy_stc_usb_dev_cdc_context_t *) classContext; + + uint32_t portNum = GetInterfaceComPort((uint32_t) transfer->setup.wIndex, context); + + if (IS_COM_VALID(portNum)) + { + switch (transfer->setup.bRequest) + { + case CY_USB_DEV_CDC_RQST_SET_LINE_CODING: + { + /* Copy received data */ + (void) memcpy((void *) context->port[portNum].linesCoding, (const void *)transfer->ptr, CY_USB_DEV_CDC_LINE_CODING_SIZE); + + context->port[portNum].linesChanged |= CY_USB_DEV_CDC_LINE_CODING_CHANGED; + + retStatus = CY_USB_DEV_SUCCESS; + } + break; + + default: + { + /* Request was not recognized. Try custom request handler. */ + if (NULL != context->requestCompleted) + { + retStatus = context->requestCompleted(transfer, context, devContext); + } + } + break; + } + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: GetInterfaceComPort +****************************************************************************//** +* +* Returns number of COM port number that belong to a certain CDC interface. +* +* \param interface +* Interface number. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* COM port number (COM1 or COM2). INVALID_COM if COM port does not exist. +* +*******************************************************************************/ +static uint32_t GetInterfaceComPort(uint32_t interface, cy_stc_usb_dev_cdc_context_t const *context) +{ + uint32_t portNum; + uint32_t locInterface = (uint32_t) CY_LO8(interface); + + if (context->port[COM1].interfaceNum == locInterface) + { + portNum = COM1; + } + else if (context->port[COM2].interfaceNum == locInterface) + { + portNum = COM2; + } + else + { + portNum = INVALID_COM; + } + + return (portNum); +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_PutData +****************************************************************************//** +* +* Sends a specified number of bytes to USB Host. +* Call \ref Cy_USB_Dev_CDC_IsReady function to ensure that the COM port +* (CDC Data interface) is ready for sending data to the USB Host before calling +* this function. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param buffer +* The pointer to the buffer containing data bytes to be sent. \n +* Allocate buffer using \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro to make +* it USBFS driver configuration independent (See \ref group_usb_dev_ep_buf_alloc +* for more information). +* +* \param size +* The number of bytes to send. +* This value must be less than or equal to the maximum packet size of the +* CDC Data interface IN endpoint that belongs to the specified COM port. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_CDC_PutData(uint32_t port, uint8_t const *buffer, uint32_t size, + cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_BAD_PARAM; + cy_stc_usb_dev_cdc_comport_t* com = GetCom(port, context); + + if (com->valid) + { + retStatus = Cy_USB_Dev_WriteEpNonBlocking((uint32_t) com->dataInEp, buffer, size, context->devContext); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_PutString +****************************************************************************//** +* +* Sends a null terminated string to the USB Host. This function is blocking and +* returns after successful USB Host transfer, or an error or timeout occurred. +* Call \ref Cy_USB_Dev_CDC_IsReady function to ensure that the COM port +* (CDC Data interface) is ready for sending data to the USB Host before calling +* this function. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param string +* The pointer to the string to be sent. \n +* The string must be allocated following rules in the section +* \ref group_usb_dev_ep_buf_alloc to be USBFS driver configuration +* independent. +* +* \param timeout +* Defines in milliseconds the time for which this function can block. +* If that time expires, the function returns. +* To wait forever, pass \ref CY_USB_DEV_WAIT_FOREVER. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +* \note +* If string parameter is a constant string (example: "USBUART"), it is stored +* in the stack and aligned to 4 bytes boundary what makes it USBFS +* driver configuration independent. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_CDC_PutString(uint32_t port, char_t const *string, int32_t timeout, + cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_BAD_PARAM; + cy_stc_usb_dev_cdc_comport_t* com = GetCom(port, context); + + if (com->valid) + { + uint32_t endpoint = com->dataInEp; + uint32_t stringLen = strlen(string); + uint32_t sendLen = 0U; + uint32_t sendIndex = 0U; + uint32_t bufSize = com->dataInEpSize; + + do + { + /* Send size equal to endpoint max packet sizes */ + sendLen = (stringLen > bufSize) ? bufSize : stringLen; + + retStatus = Cy_USB_Dev_WriteEpBlocking(endpoint, (uint8_t const *) &string[sendIndex], + sendLen, timeout, context->devContext); + stringLen -= sendLen; + sendIndex += sendLen; + } + while ((stringLen > 0U) && (CY_USB_DEV_SUCCESS == retStatus)); + + /* If last packet is exactly maximum packet size, it shall be followed + * by a zero-length packet to assure the end of segment is properly + * identified by the terminal. + */ + if ((sendLen == bufSize) && (CY_USB_DEV_SUCCESS == retStatus)) + { + uint8_t dummyByte = 0U; + retStatus = Cy_USB_Dev_WriteEpBlocking(endpoint, &dummyByte, + 0U, timeout, context->devContext); + } + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetCount +****************************************************************************//** +* +* Returns the number of bytes that were received from the USB Host and can be +* read using \ref Cy_USB_Dev_CDC_GetData or \ref Cy_USB_Dev_CDC_GetChar +* functions. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Returns the number of bytes that were received. +* +*******************************************************************************/ +uint32_t Cy_USB_Dev_CDC_GetCount(uint32_t port, cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + uint32_t count = 0U; + cy_stc_usb_dev_cdc_comport_t *com = GetCom(port, context); + + if (com->valid) + { + /* Read number of bytes in local buffer */ + count = com->writeBufIdx; + + /* Local buffer is empty. Check if there is data in the endpoint buffer */ + if (0U == count) + { + if (IsEndpointReady((uint32_t) com->dataOutEp, context->devContext)) + { + /* Update count if Host wrote anything into the endpoint */ + count = Cy_USB_Dev_GetEpNumToRead((uint32_t) com->dataOutEp, context->devContext); + } + } + } + + return count; +} + + +/******************************************************************************* +* Function Name: GetCom +****************************************************************************//** +* +* Returns pointer to port structure cy_stc_usb_dev_cdc_comport_t +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Pointer to port structure cy_stc_usb_dev_cdc_comport_t +* +*******************************************************************************/ +static cy_stc_usb_dev_cdc_comport_t* GetCom(uint32_t port, cy_stc_usb_dev_cdc_context_t *context) +{ + return &context->port[port]; +} + + +/******************************************************************************* +* Function Name: IsEndpointReady +****************************************************************************//** +* +* Check if endpoint state is IDLE or COMPLETED. +* +* \param endpoint +* The endpoint number. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* True - endpoint is ready. False - endpoint is not ready. +* +*******************************************************************************/ +static bool IsEndpointReady(uint32_t endpoint, cy_stc_usb_dev_context_t const *context) +{ + cy_en_usb_dev_ep_state_t epState; + + epState = Cy_USBFS_Dev_Drv_GetEndpointState(context->drvBase, + endpoint, + context->drvContext); + + return ((CY_USB_DEV_EP_IDLE == epState) || (CY_USB_DEV_EP_COMPLETED == epState)); +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_IsDataReady +****************************************************************************//** +* +* Returns status if the COM port (CDC Data interface) received data from the +* USB Host (including zero-length packet). +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* * True - the COM port (CDC Data interface) received data from the USB Host. +* * False - the COM port (CDC Data interface) is waiting for data from the +* USB Host. +* +*******************************************************************************/ +bool Cy_USB_Dev_CDC_IsDataReady(uint32_t port, cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + bool retStatus = false; + cy_stc_usb_dev_cdc_comport_t* com = GetCom(port, context); + + if (com->valid) + { + retStatus = IsEndpointReady((uint32_t) com->dataOutEp, context->devContext); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_IsReady +****************************************************************************//** +* +* Returns status if the COM port (CDC Data interface) is ready for sending +* new data. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* * True - the COM port (CDC Data interface) is ready for sending new data. +* * False - the COM port (CDC Data interface) is waiting for the USB Host to +* read previous data. +* +*******************************************************************************/ +bool Cy_USB_Dev_CDC_IsReady(uint32_t port, cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + bool retStatus = false; + cy_stc_usb_dev_cdc_comport_t* com = GetCom(port, context); + + if (com->valid) + { + retStatus = IsEndpointReady((uint32_t) com->dataInEp, context->devContext); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: ReadInternalBuffer +****************************************************************************//** +* +* Internal function used for copy data from internal buffer +* +* \param port +* Pointer to the port structure. +* +* \param buffer +* Pointer to the data array where data will be placed. +* +* \param size +* Number of bytes to read into the data array from the RX buffer. The maximum +* length is limited by the number of received bytes. +* +* \return +* Number of copied bytes. +* +*******************************************************************************/ +static uint32_t ReadInternalBuffer(cy_stc_usb_dev_cdc_comport_t* port, uint8_t *buffer, + uint32_t size) +{ + uint32_t numBytes = port->writeBufIdx; + uint32_t idx = port->readBufIdx; + uint32_t numToCopy = (size > numBytes) ? numBytes : size; + + /* Copy data from internal buffer to the user buffer */ + (void) memcpy(buffer, &port->buffer[idx], numToCopy); + numBytes -= numToCopy; + + /* Adjust buffer pointers */ + if (0U == numBytes) + { + port->readBufIdx = 0U; + port->writeBufIdx = 0U; + } + else + { + port->readBufIdx += numToCopy; + port->writeBufIdx -= numToCopy; + } + + return numToCopy; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetData +****************************************************************************//** +* +* Read a specified number of data bytes received from USB Host by the COM port +* (CDC Data interface). +* Call \ref Cy_USB_Dev_CDC_IsDataReady function to ensure that +* data is received from the USB Host before calling this function. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param buffer +* The pointer to buffer that stores data that was read. \n +* Allocate buffer using \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro to make +* it USBFS driver configuration independent (See \ref group_usb_dev_ep_buf_alloc +* for more information). +* +* \param size +* The number of bytes to read. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data keeping. The user must not modify +* anything in this structure. +* +* \return +* The number of bytes that were actually read. +* +*******************************************************************************/ +uint32_t Cy_USB_Dev_CDC_GetData(uint32_t port, uint8_t *buffer, uint32_t size, + cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + uint32_t actSize = 0U; + cy_stc_usb_dev_cdc_comport_t * com = GetCom(port, context); + + if ((com->valid) && + (NULL != com->buffer) && (com->bufferSize == com->dataOutEpSize)) + { + /* Check whether buffer has some data */ + if (com->writeBufIdx > 0U) + { + actSize = ReadInternalBuffer(com, buffer, size); + } + else + { + cy_en_usb_dev_status_t locStatus; + locStatus = Cy_USB_Dev_ReadEpNonBlocking((uint32_t) com->dataOutEp, com->buffer, com->bufferSize, + &com->writeBufIdx, context->devContext); + + if (CY_USB_DEV_SUCCESS == locStatus) + { + actSize = ReadInternalBuffer(com, buffer, size); + + /* ReadEpNonBlocking returned success therefore safe to discard status */ + (void) Cy_USB_Dev_StartReadEp((uint32_t) com->dataOutEp, context->devContext); + } + } + } + + return actSize; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetAll +****************************************************************************//** +* +* Read all data received from USB Host by the COM port (CDC Data interface). +* Call \ref Cy_USB_Dev_CDC_IsDataReady function to ensure that +* data is received from the USB Host before calling this function. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param buffer +* The pointer to buffer that stores data that was read. \n +* Allocate buffer using \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro to make +* it USBFS driver configuration independent (See \ref group_usb_dev_ep_buf_alloc +* for more information). +* +* \param maxSize +* The size of buffer to read data into. +* This value must be not be less then CDC Data interface OUT endpoint maximum +* packet size that belongs to specified COM port. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* The number of bytes that were actually read. +* +*******************************************************************************/ +uint32_t Cy_USB_Dev_CDC_GetAll(uint32_t port, uint8_t *buffer, uint32_t maxSize, + cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + uint32_t actSize = 0U; + cy_stc_usb_dev_cdc_comport_t * com = GetCom(port, context); + + if (com->valid) + { + cy_en_usb_dev_status_t locStatus; + + locStatus = Cy_USB_Dev_ReadEpNonBlocking((uint32_t) com->dataOutEp, buffer, maxSize, &actSize, + context->devContext); + + /* Start read endpoint after read completed */ + if (CY_USB_DEV_SUCCESS == locStatus) + { + /* ReadEpNonBlocking returned success therefore safe to discard status */ + (void) Cy_USB_Dev_StartReadEp((uint32_t) com->dataOutEp, context->devContext); + } + } + + return actSize; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetChar +****************************************************************************//** +* +* Reads one byte of received data. +* Call \ref Cy_USB_Dev_CDC_IsDataReady function to ensure that +* data is received from the USB Host before calling this function. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Received one character or zero value to indicate there is no data. +* +*******************************************************************************/ +char_t Cy_USB_Dev_CDC_GetChar(uint32_t port, cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + uint8_t data = 0U; + uint32_t number = Cy_USB_Dev_CDC_GetData(port, &data, 1U, context); + + if (0U == number) + { + data = 0U; + } + + return (char_t) data; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_SendSerialState +****************************************************************************//** +* +* Sends the serial state notification to the host using the COM port +* (CDC interface) IN interrupt endpoint. +* Call \ref Cy_USB_Dev_CDC_IsNotificationReady function to ensure that +* COM port (CDC interface) is ready send notification before calling this +* function. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param serialState +* 16-bit value that will be sent from the USB Device to the USB Host as +* SERIAL_STATE notification using the CDC interface IN interrupt endpoint. +* Refer to revision 1.2 of the CDC PSTN Subclass specification for bit field +* definitions of the 16-bit serial state value. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +* \note +* The maximum packet size of the CDC interface IN interrupt endpoint +* (that belongs to specified COM port) must be at least 10 bytes to send +* serial state notifications. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_CDC_SendSerialState(uint32_t port, uint32_t serialState, + cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_BAD_PARAM; + cy_stc_usb_dev_cdc_comport_t* com = GetCom(port, context); + + if ((com->valid) && + (CY_USB_DEV_CDC_SERIAL_STATE_SIZE <= com->commEpSize)) + { + /* Update serial state */ + com->serialStateBitmap = (uint16_t) serialState; + + com->serialStateNotification[SERIAL_STATE_WSERIALSTATE_LSB_OFFSET] = CY_LO8(serialState); + com->serialStateNotification[SERIAL_STATE_WSERIALSTATE_MSB_OFFSET] = CY_HI8(serialState); + + retStatus = Cy_USB_Dev_WriteEpNonBlocking((uint32_t) com->commEp, + (uint8_t *) com->serialStateNotification, + CY_USB_DEV_CDC_SERIAL_STATE_SIZE, + context->devContext); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_IsNotificationReady +****************************************************************************//** +* +* Returns if the COM port (CDC interface) is ready to send notification to +* the USB Host. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* * True - the COM port (CDC interface) is ready for sending new notification. +* * False - the COM port (CDC interface) is waiting for the USB Host to read +* previous notification. +* +*******************************************************************************/ +bool Cy_USB_Dev_CDC_IsNotificationReady(uint32_t port, cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + bool retStatus = false; + cy_stc_usb_dev_cdc_comport_t* com = GetCom(port, context); + + if (com->valid) + { + retStatus = IsEndpointReady((uint32_t) com->commEp, context->devContext); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetDTERate +****************************************************************************//** +* +* Returns the data terminal rate set for this port in bits per second. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Data rate in bits per second. +* +*******************************************************************************/ +uint32_t Cy_USB_Dev_CDC_GetDTERate(uint32_t port, cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(IS_COM_VALID(port)); + + cy_stc_usb_dev_cdc_comport_t* com = GetCom(port, context); + + uint32_t rate = com->linesCoding[LINE_CODING_RATE_OFFSET + 3U]; + + rate = (rate << 8U) | com->linesCoding[LINE_CODING_RATE_OFFSET + 2U]; + rate = (rate << 8U) | com->linesCoding[LINE_CODING_RATE_OFFSET + 1U]; + rate = (rate << 8U) | com->linesCoding[LINE_CODING_RATE_OFFSET]; + + return rate; +} + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc.h new file mode 100644 index 0000000000000000000000000000000000000000..0d1476e2130f60a37e7b0b2739b60249b66a28c9 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc.h @@ -0,0 +1,664 @@ +/***************************************************************************//** +* \file cy_usb_dev_cdc.h +* \version 2.10 +* +* Provides CDC class-specific API declarations. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + + +/** +* \addtogroup group_usb_dev_cdc +* This section provides API description for the CDC class. +* +* \{ +* \defgroup group_usb_dev_cdc_macros Macros +* \defgroup group_usb_dev_cdc_functions Functions +* \defgroup group_usb_dev_cdc_data_structures Data Structures +* \defgroup group_usb_dev_cdc_enums Enumerated Types +* \} +*/ + + +#if !defined(CY_USB_DEV_CDC_H) +#define CY_USB_DEV_CDC_H + +#include "cy_usb_dev.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +#if defined(__cplusplus) +extern "C" { +#endif + + +/******************************************************************************* +* API Constants +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_cdc_macros +* \{ +*/ +/** Number of supported COM ports */ +#define CY_USB_DEV_CDC_COMPORT_NUMBER (2U) + +/* CDC Class requests */ +#define CY_USB_DEV_CDC_RQST_SET_LINE_CODING (0x20U) /**< SetLineCoding CDC class request */ +#define CY_USB_DEV_CDC_RQST_GET_LINE_CODING (0x21U) /**< GetLineCoding CDC class request */ +#define CY_USB_DEV_CDC_RQST_SET_CONTROL_LINE_STATE (0x22U) /**< SetControlLineState CDC class request */ +/** \} group_usb_dev_cdc_macros */ + + +/******************************************************************************* +* Internal Constants +*******************************************************************************/ + +/** \cond INTERNAL */ +#define CY_USB_DEV_CDC_SERIAL_STATE_SIZE (10U) +#define CY_USB_DEV_CDC_LINE_CODING_CHAR_FORMAT_POS (4U) +#define CY_USB_DEV_CDC_LINE_CODING_SIZE (7U) +#define CY_USB_DEV_CDC_LINE_CODING_PARITY_BITS_POS (5U) +#define CY_USB_DEV_CDC_LINE_CODING_DATA_BITS_POS (6U) + +#define CY_USB_DEV_CDC_IS_COM_VALID(com) ((com) <= CY_USB_DEV_CDC_COMPORT_NUMBER) +/** \endcond */ + + +/******************************************************************************* +* Enumerated Types +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_cdc_enums +* \{ +*/ + +/** CDC Stop bit */ +typedef enum +{ + CY_USB_DEV_CDC_STOPBIT_1, /**< 1 stop bit */ + CY_USB_DEV_CDC_STOPBITS_1_5, /**< 1.5 stop bits */ + CY_USB_DEV_CDC_STOPBITS_2, /**< 2 stop bits */ +} cy_en_usb_dev_cdc_stop_bit_t; + +/** CDC Parity type */ +typedef enum +{ + CY_USB_DEV_CDC_PARITY_NONE, /**< None parity */ + CY_USB_DEV_CDC_PARITY_ODD, /**< Odd parity */ + CY_USB_DEV_CDC_PARITY_EVEN, /**< Even parity */ + CY_USB_DEV_CDC_PARITY_MARK, /**< Mark */ + CY_USB_DEV_CDC_PARITY_SPACE, /**< Space */ +} cy_en_usb_dev_cdc_parity_type_t; + +/** \} group_usb_dev_cdc_enums */ + + +/******************************************************************************* +* Type Definitions +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_cdc_data_structures +* \{ +*/ +/** CDC class configuration structure */ +typedef struct +{ + /** The pointers to the buffers to store received data by COM port 0 and 1 + * appropriately. The buffer is mandatory to for \ref Cy_USB_Dev_CDC_GetData + * and \ref Cy_USB_Dev_CDC_GetChar function operation. If these functions + * will not be used by the application pass NULL as a pointer. \n + * Allocate buffer using \ref CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro to make + * it USBFS driver configuration independent (See \ref group_usb_dev_ep_buf_alloc + * for more information). + */ + uint8_t *buffer[CY_USB_DEV_CDC_COMPORT_NUMBER]; + + /** Size of provided buffers to for the COM port 0 and 1 appropriately. + * The buffer size must be equal to the maximum packet size of CDC Data + * interface IN endpoint that belongs to the COM port. + * Pass zero size if the pointer to the buffer is NULL. + */ + uint32_t bufferSize[CY_USB_DEV_CDC_COMPORT_NUMBER]; + + +} cy_stc_usb_dev_cdc_config_t; + +/** \cond INTERNAL: CDC COM port properties structure */ +typedef struct +{ + /** Defines whether port is valid for usage */ + volatile bool valid; + + /** Buffer for byte read organization */ + uint8_t *buffer; + + /** Size of buffer */ + uint32_t bufferSize; + + /** Number of occupied bytes in buffer */ + uint32_t writeBufIdx; + + /** Number of occupied bytes in buffer */ + uint32_t readBufIdx; + + /** Contains the interface number used to define port number in requests. */ + volatile uint8_t interfaceNum; + + /** + * Contains the data IN endpoint size. It is initialized after a + * SET_CONFIGURATION request based on a user descriptor. It is used + * in CDC functions to send data to the Host. + */ + volatile uint16_t dataInEpSize; + + /** + * Contains the data OUT endpoint size. It is initialized after a + * SET_CONFIGURATION request based on user descriptor. It is used in + * CDC functions to receive data from the Host. + */ + volatile uint16_t dataOutEpSize; + + /** + * Contains the IN interrupt endpoint size used for sending serial + * state notification to the Host. It is initialized after a + * SET_CONFIGURATION request based on a user descriptor. It is used + * in the CDC function SendSerialState(). + */ + volatile uint16_t commEpSize; + + /** + * Contains the current line coding structure. The Host sets it using + * a SET_LINE_CODING request and returns it to the user code using + * the GetDTERate(), GetCharFormat(), GetParityType(), and + * GetDataBits() functions. + */ + volatile uint8_t linesCoding[CY_USB_DEV_CDC_LINE_CODING_SIZE]; + /** + * Used as a flag for the IsLineChanged() function, to inform it that + * the host has been sent a request to change line coding or control + * bitmap. + */ + volatile uint8_t linesChanged; + + /** + * Contains the current control-signal bitmap. The Host sets it using + * a SET_CONTROL_LINE request and returns it to the user code using + * the GetLineControl() function. + */ + volatile uint8_t linesControlBitmap; + + /** + * Contains the 16-bit serial state value that was sent using the + * SendSerialState() function. + */ + volatile uint16_t serialStateBitmap; + + /** + * Contains the 16-bit serial state value that was sent using the + * SendSerialState() function. + */ + volatile uint8_t serialStateNotification[CY_USB_DEV_CDC_SERIAL_STATE_SIZE]; + + /** + * Contains the data IN endpoint number. It is initialized after a + * SET_CONFIGURATION request based on a user descriptor. It is used + * in CDC functions to send data to the host. + */ + volatile uint8_t dataInEp; + + /** + * Contains the data OUT endpoint number. It is initialized after a + * SET_CONFIGURATION request based on user descriptor. It is used in + * CDC functions to receive data from the Host. + */ + volatile uint8_t dataOutEp; + + /** + * Contains the IN interrupt endpoint number used for sending serial + * state notification to the host. It is initialized after a + * SET_CONFIGURATION request based on a user descriptor. It is used + * in the CDC function SendSerialState(). + */ + volatile uint8_t commEp; + +} cy_stc_usb_dev_cdc_comport_t; +/** \endcond */ + +/** CDC class context structure. +* All fields for the CDC context structure are internal. Firmware never reads or +* writes these values. Firmware allocates the structure and provides the +* address of the structure to the middleware in CDC function calls. Firmware +* must ensure that the defined instance of this structure remains in scope while +* the middleware is in use. +*/ +typedef struct +{ + /** \cond INTERNAL*/ + + /** COM port description array */ + cy_stc_usb_dev_cdc_comport_t port[CY_USB_DEV_CDC_COMPORT_NUMBER]; + + /** CDC class functions pointers */ + cy_stc_usb_dev_class_t classObj; + + /** CDC class linked list item */ + cy_stc_usb_dev_class_ll_item_t classItem; + + /** Device context */ + cy_stc_usb_dev_context_t *devContext; + + /** + * Called after setupRequest was received (before internal processing). + * Returns status of the event processing. + */ + cy_cb_usb_dev_request_received_t requestReceived; + + /** + * Called after setupRequest was received (before internal processing). + * Returns status of the event processing. + */ + cy_cb_usb_dev_request_cmplt_t requestCompleted; + + /** \endcond */ + +} cy_stc_usb_dev_cdc_context_t; +/** \} group_usb_dev_cdc_data_structures */ + + +/******************************************************************************* +* Function Prototypes +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_cdc_functions +* \{ +*/ +cy_en_usb_dev_status_t Cy_USB_Dev_CDC_Init(cy_stc_usb_dev_cdc_config_t const *config, + cy_stc_usb_dev_cdc_context_t *context, + cy_stc_usb_dev_context_t *devContext); + +cy_en_usb_dev_status_t Cy_USB_Dev_CDC_PutData(uint32_t port, uint8_t const *buffer, uint32_t size, + cy_stc_usb_dev_cdc_context_t *context); + +cy_en_usb_dev_status_t Cy_USB_Dev_CDC_PutString(uint32_t port, char_t const *string, int32_t timeout, + cy_stc_usb_dev_cdc_context_t *context); + +__STATIC_INLINE cy_en_usb_dev_status_t Cy_USB_Dev_CDC_PutChar(uint32_t port, char_t ch, + cy_stc_usb_dev_cdc_context_t *context); + +uint32_t Cy_USB_Dev_CDC_GetCount(uint32_t port, cy_stc_usb_dev_cdc_context_t *context); + +bool Cy_USB_Dev_CDC_IsDataReady(uint32_t port, cy_stc_usb_dev_cdc_context_t *context); + +bool Cy_USB_Dev_CDC_IsReady(uint32_t port, cy_stc_usb_dev_cdc_context_t *context); + +uint32_t Cy_USB_Dev_CDC_GetData(uint32_t port, uint8_t *buffer, uint32_t size, + cy_stc_usb_dev_cdc_context_t *context); + +uint32_t Cy_USB_Dev_CDC_GetAll(uint32_t port, uint8_t *buffer, uint32_t maxSize, + cy_stc_usb_dev_cdc_context_t *context); + +char_t Cy_USB_Dev_CDC_GetChar(uint32_t port, cy_stc_usb_dev_cdc_context_t *context); + +__STATIC_INLINE uint32_t Cy_USB_Dev_CDC_IsLineChanged(uint32_t port, cy_stc_usb_dev_cdc_context_t *context); + +__STATIC_INLINE uint32_t Cy_USB_Dev_CDC_GetLineControl(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context); + +uint32_t Cy_USB_Dev_CDC_GetDTERate(uint32_t port, cy_stc_usb_dev_cdc_context_t *context); + +__STATIC_INLINE cy_en_usb_dev_cdc_stop_bit_t Cy_USB_Dev_CDC_GetCharFormat(uint32_t port, + cy_stc_usb_dev_cdc_context_t const *context); + +__STATIC_INLINE cy_en_usb_dev_cdc_parity_type_t Cy_USB_Dev_CDC_GetParity(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context); + +__STATIC_INLINE uint32_t Cy_USB_Dev_CDC_GetDataBits(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context); + +cy_en_usb_dev_status_t Cy_USB_Dev_CDC_SendSerialState(uint32_t port, uint32_t serialState, + cy_stc_usb_dev_cdc_context_t *context); + +bool Cy_USB_Dev_CDC_IsNotificationReady(uint32_t port, cy_stc_usb_dev_cdc_context_t *context); + +__STATIC_INLINE void Cy_USB_Dev_CDC_RegisterUserCallbacks(cy_cb_usb_dev_request_received_t requestReceivedHandle, + cy_cb_usb_dev_request_cmplt_t requestCompletedHandle, + cy_stc_usb_dev_cdc_context_t *context); + +__STATIC_INLINE cy_stc_usb_dev_class_t * Cy_USB_Dev_CDC_GetClass(cy_stc_usb_dev_cdc_context_t *context); + +__STATIC_INLINE uint32_t Cy_USB_Dev_CDC_GetSerialState(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context); +/** \} group_usb_dev_cdc_functions */ + + +/******************************************************************************* +* API Constants +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_cdc_macros +* \{ +*/ + +/** +* Indicates that a DTR signal is present. This signal corresponds to V.24 +* signal 108/2 and RS232 signal DTR. +*/ +#define CY_USB_DEV_CDC_LINE_CONTROL_DTR (0x1U) + +/** +* Carrier control for half-duplex modems. This signal corresponds to V.24 +* signal 105 and RS232 signal RTS. +*/ +#define CY_USB_DEV_CDC_LINE_CONTROL_RTS (0x2U) + +#define CY_USB_DEV_CDC_LINE_NOT_CHANGED (0U) /**< No line coding/line control changes */ +#define CY_USB_DEV_CDC_LINE_CODING_CHANGED (1U) /**< Line coding changed */ +#define CY_USB_DEV_CDC_LINE_CONTROL_CHANGED (2U) /**< Line control changed */ + +/** \} group_usb_dev_cdc_macros */ + + +/******************************************************************************* +* In-line Function Implementation +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_cdc_functions +* \{ +*/ + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_RegisterUserCallbacks +****************************************************************************//** +* +* Registering user callback to handle CDC class requests that are not supported +* by provided CDC request handler. +* +* \param requestReceivedHandle +* The pointer to a callback function. +* This function is called when setup packet was received from USB Host but was +* not recognized, therefore might require the user class processing. +* To remove callback function pass NULL as function pointer. +* +* \param requestCompletedHandle +* The pointer to a callback function. +* This function is called when USB Device received data from the USB Host +* as part of current request processing. The requestReceivedHandle function +* must enable notification to trigger this event. This makes sense only when CDC +* request processing requires a data stage. +* To remove callback function pass NULL as function pointer. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the Audio Class operation for +* internal configuration and data retention. The user must not modify anything +* in this structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_CDC_RegisterUserCallbacks(cy_cb_usb_dev_request_received_t requestReceivedHandle, + cy_cb_usb_dev_request_cmplt_t requestCompletedHandle, + cy_stc_usb_dev_cdc_context_t *context) +{ + context->requestReceived = requestReceivedHandle; + context->requestCompleted = requestCompletedHandle; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetClass +****************************************************************************//** +* +* Returns pointer to the CDC class structure. +* This function is useful to override class event handlers using +* \ref group_usb_dev_functions_class_support. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* The pointer to the CDC class structure. +* +*******************************************************************************/ +__STATIC_INLINE cy_stc_usb_dev_class_t * Cy_USB_Dev_CDC_GetClass(cy_stc_usb_dev_cdc_context_t *context) +{ + return &context->classObj; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetSerialState +****************************************************************************//** +* +* Returns the current serial state value for the COM port. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* 16-bit serial state value. Refer to revision 1.2 of the CDC PSTN Subclass +* specification for bit field definitions of the 16-bit serial state value. +* Zero in case COM port is invalid. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_CDC_GetSerialState(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context) +{ + CY_ASSERT_L1(CY_USB_DEV_CDC_IS_COM_VALID(port)); + + uint32_t retState = (context->port[port].valid) ? + context->port[port].serialStateBitmap : 0U; + return retState; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_IsLineChanged +****************************************************************************//** +* +* Returns the clear-on-read status of the COM port. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* * \ref CY_USB_DEV_CDC_LINE_CODING_CHANGED when SET_LINE_CODING request is +* received. +* * \ref CY_USB_DEV_CDC_LINE_CONTROL_CHANGED when CDC_SET_CONTROL_LINE_STATE +* request is received. +* * \ref CY_USB_DEV_CDC_LINE_NOT_CHANGED when there were no request since last +* call. +* +* \note +* This function is not interrupt-protected and to prevent a race condition, +* it should be protected from the USBFS interruption in the place where it +* is called. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_CDC_IsLineChanged(uint32_t port, cy_stc_usb_dev_cdc_context_t *context) +{ + CY_ASSERT_L1(CY_USB_DEV_CDC_IS_COM_VALID(port)); + + uint32_t retState = context->port[port].linesChanged; + context->port[port].linesChanged = CY_USB_DEV_CDC_LINE_NOT_CHANGED; + + return retState; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetCharFormat +****************************************************************************//** +* +* Returns the number of stop bits for the COM port. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Number of stop bits \ref cy_en_usb_dev_cdc_stop_bit_t. +* +*******************************************************************************/ +__STATIC_INLINE cy_en_usb_dev_cdc_stop_bit_t Cy_USB_Dev_CDC_GetCharFormat(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context) +{ + CY_ASSERT_L1(CY_USB_DEV_CDC_IS_COM_VALID(port)); + + return (cy_en_usb_dev_cdc_stop_bit_t) context->port[port].linesCoding[CY_USB_DEV_CDC_LINE_CODING_CHAR_FORMAT_POS]; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_PutChar +****************************************************************************//** +* +* Sends a single character to the USB Host. +* Call \ref Cy_USB_Dev_CDC_IsReady function to ensure that the COM port +* (CDC Data interface) is ready for sending data to the USB Host before calling +* this function. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param ch +* Character to be sent. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +__STATIC_INLINE cy_en_usb_dev_status_t Cy_USB_Dev_CDC_PutChar(uint32_t port, char_t ch, + cy_stc_usb_dev_cdc_context_t *context) +{ + /* Put data into the aligned buffer to work with 8-bit and 16-bit access type */ + uint16_t chBuffer = (uint16_t) ch; + + return Cy_USB_Dev_CDC_PutData(port, (uint8_t*) &chBuffer, 1U, context); +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetParity +****************************************************************************//** +* +* Returns the parity type for the COM port. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Parity type \ref cy_en_usb_dev_cdc_parity_type_t. +* +*******************************************************************************/ +__STATIC_INLINE cy_en_usb_dev_cdc_parity_type_t Cy_USB_Dev_CDC_GetParity(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context) +{ + CY_ASSERT_L1(CY_USB_DEV_CDC_IS_COM_VALID(port)); + + return (cy_en_usb_dev_cdc_parity_type_t) context->port[port].linesCoding[CY_USB_DEV_CDC_LINE_CODING_PARITY_BITS_POS]; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetDataBits +****************************************************************************//** +* +* Returns the number of data bits for the COM port. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data keeping. The user must not modify +* anything in this structure. +* +* \return +* Number of data bits, which can be 5, 6, 7, 8, or 16. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_CDC_GetDataBits(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context) +{ + CY_ASSERT_L1(CY_USB_DEV_CDC_IS_COM_VALID(port)); + + return (uint32_t) context->port[port].linesCoding[CY_USB_DEV_CDC_LINE_CODING_DATA_BITS_POS]; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_CDC_GetLineControl +****************************************************************************//** +* +* Returns the line control bitmap for the COM port. +* +* \param port +* COM port number. Valid ports are 0 and 1. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_cdc_context_t +* allocated by the user. The structure is used during the CDC Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Line control bitmap \ref CY_USB_DEV_CDC_LINE_CONTROL_DTR and +* \ref CY_USB_DEV_CDC_LINE_CONTROL_RTS. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_CDC_GetLineControl(uint32_t port, cy_stc_usb_dev_cdc_context_t const *context) +{ + CY_ASSERT_L1(CY_USB_DEV_CDC_IS_COM_VALID(port)); + + return (uint32_t) context->port[port].linesControlBitmap; +} + +/** \} group_usb_dev_cdc_functions */ + +#if defined(__cplusplus) +} +#endif + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + +#endif /* (CY_USB_DEV_CDC_H) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc_descr.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc_descr.h new file mode 100644 index 0000000000000000000000000000000000000000..3a2828dd494cf89fad88d8357f84c7cbb11adeac --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_cdc_descr.h @@ -0,0 +1,45 @@ +/***************************************************************************//** +* \file cy_usb_dev_cdc_descr.h +* \version 2.10 +* +* Provides CDC class-specific descriptor defines. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + +#if !defined(CY_USB_DEV_CDC_DESCR_H) +#define CY_USB_DEV_CDC_DESCR_H + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +#if defined(__cplusplus) +extern "C" { +#endif + + +/******************************************************************************* +* API Constants +*******************************************************************************/ + +/** \cond INTERNAL */ +/* CDC class */ +#define CY_USB_DEV_CDC_CLASS (0x02U) +#define CY_USB_DEV_CDC_CLASS_DATA (0x0AU) +/** \endcond */ + +#if defined(__cplusplus) +} +#endif + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + +#endif /* (CY_USB_DEV_CDC_DESCR_H) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_descr.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_descr.h new file mode 100644 index 0000000000000000000000000000000000000000..33dcbd3e917cc3acf78c23f8b4b77dc8f457e83a --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_descr.h @@ -0,0 +1,333 @@ +/***************************************************************************//** +* \file cy_usb_dev_descr.h +* \version 2.10 +* +* Provides device definition structures and descriptors structures. +* The descriptor structures can be used to access particular descriptors. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + + +#if !defined(CY_USB_DEV_DESCR_H) +#define CY_USB_DEV_DESCR_H + +#include +#include +#include + +#include "cy_usb_dev_audio_descr.h" +#include "cy_usb_dev_cdc_descr.h" +#include "cy_usb_dev_hid_descr.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +#if defined(__cplusplus) +extern "C" { +#endif + + +/******************************************************************************* +* Type Definitions +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_structures_device +* \{ +*/ + +/** USBFS Device endpointDescriptor structure */ +typedef struct +{ + /** Pointer to the endpointDescriptor Descriptor in the Configuration Descriptor */ + const uint8_t *endpointDescriptor; + +} cy_stc_usb_dev_endpoint_t; + + +/** USBFS Device HID structure */ +typedef struct +{ + /** Pointer to the HID Class Descriptor in the Configuration Descriptor */ + const uint8_t *hidDescriptor; + + /** Pointer to uint8_t array that stores HID Report Descriptor */ + const uint8_t *reportDescriptor; + + /** HID Report Descriptor size */ + uint16_t reportDescriptorSize; + + /** Start position of input report IDs in the array */ + uint8_t inputReportPos; + + /** Number of input report IDs */ + uint8_t numInputReports; + + /** Array of indexes for input report IDs */ + const uint8_t *inputReportIdx; + + /** Number of elements in the array of indexes */ + uint8_t inputReportIdxSize; + +} cy_stc_usb_dev_hid_t; + + +/** USBFS Device Alternate Interface structure */ +typedef struct +{ + /** Pointer to the Interface Descriptor in the Configuration Descriptor */ + const uint8_t *interfaceDescriptor; + + /** Pointer to array of pointers to structure that stores Endpoints information */ + const cy_stc_usb_dev_endpoint_t **endpoints; + + /** Number of endpoints that belong to this interface alternates */ + uint8_t numEndpoints; + + /** Pointer to the HID information structure */ + const cy_stc_usb_dev_hid_t *hid; +} cy_stc_usb_dev_alternate_t; + + +/** USBFS Device Interface structure */ +typedef struct +{ + /** Number of supported alternate settings */ + uint8_t numAlternates; + + /** Pointer to array of pointers to structure that stores Interface Alternates information */ + const cy_stc_usb_dev_alternate_t **alternates; + + /** Mask that represents endpoints that belong to Interface Alternates */ + uint16_t endpointsMask; +} cy_stc_usb_dev_interface_t; + + +/** USBFS Device Configuration structure */ +typedef struct +{ + /** Number of supported interfaces */ + uint8_t numInterfaces; + + /** Pointer to uint8_t array that stores Configuration Descriptor */ + const uint8_t *configDescriptor; + + /** Pointer to array of pointers to structure that store Interface information */ + const cy_stc_usb_dev_interface_t **interfaces; +} cy_stc_usb_dev_configuration_t; + +/** USBFS Device MS OS String Descriptors structure */ +typedef struct +{ + /** Pointer to MS OS String descriptor */ + const uint8_t *msOsDescriptor; + + /** Vendor code to get Extended Compat ID and Properties OS Descriptors */ + uint8_t msVendorCode; + + /** Pointer to Extended Compat ID OS Descriptor */ + const uint8_t *extCompatIdDescriptor; + + /** Pointer to Extended Properties OS Descriptor */ + const uint8_t *extPropertiesDescriptor; +} cy_stc_usb_dev_ms_os_string_t; + +/** USBFS Device String Descriptors structure */ +typedef struct +{ + /** Number of String Descriptors */ + uint8_t numStrings; + + /** Defines whether the MS OS String is enabled */ + bool enableWindowsOsDescriptor; + + /** Defines MS OS Strings structures */ + const cy_stc_usb_dev_ms_os_string_t *osStringDescriptors; + + /** Pointer to array of pointers to String Descriptors */ + const uint8_t **stringDescriptors; +} cy_stc_usb_dev_string_t; + + +/** USBFS Device structure */ +typedef struct +{ + /** Pointer to uint8_t array that stores Device Descriptor */ + const uint8_t *deviceDescriptor; + + /** Pointer to uint8_t array that stores BOS Descriptor */ + const uint8_t *bosDescriptor; + + /** Pointer to structure that stores Strings Descriptors information */ + const cy_stc_usb_dev_string_t *strings; + + /** Number of supported configurations */ + uint8_t numConfigurations; + + /** Pointer to array of pointers to structure that stores Configuration information */ + const cy_stc_usb_dev_configuration_t **configurations; + +} cy_stc_usb_dev_device_t; + +/** \} group_usb_dev_structures_device */ + + +/** +* \addtogroup group_usb_dev_structures_device_descr +* \{ +*/ + +/** Device descriptor */ +typedef struct +{ + uint8_t bLength; /**< Size of the Descriptor in Bytes */ + uint8_t bDescriptorType; /**< Constant Device Descriptor */ + uint16_t bcdUSB; /**< USB Specification Number to which the device complies */ + uint8_t bDeviceClass; /**< Class Code (Assigned by USB Org): + * If equal to Zero, each interface specifies its own class code + * If equal to 0xFF, the class code is vendor specified. + * Otherwise, field is valid Class Code. + */ + uint8_t bDeviceSubClass; /**< Subclass Code (Assigned by USB Org) */ + uint8_t bDeviceProtocol; /**< Protocol Code (Assigned by USB Org) */ + uint8_t bMaxPacketSize; /**< Maximum Packet Size for Zero Endpoint. Valid Sizes are 8, 16, 32, 64 */ + uint16_t idVendor; /**< Vendor ID (Assigned by USB Org) */ + uint16_t idProduct; /**< Product ID (Assigned by Manufacturer) */ + uint16_t bcdDevice; /**< Release Number */ + uint8_t iManufacturer; /**< Index of Manufacturer String Descriptor */ + uint8_t iProduct; /**< Index of Product String Descriptor */ + uint8_t iSerialNumber; /**< Index of Serial Number String Descriptor */ + uint8_t bNumConfigurations;/**< Number of Possible Configurations */ +} cy_stc_usbdev_device_descr_t; + +/** Configuration descriptor */ +typedef struct +{ + uint8_t bLength; /**< Size of Descriptor in Bytes */ + uint8_t bDescriptorType; /**< Configuration Descriptor */ + uint16_t wTotalLength; /**< Total length in bytes of data returned */ + uint8_t bNumInterfaces; /**< Number of Interfaces */ + uint8_t bConfigurationValue; /**< Value to use as an argument to select this configuration */ + uint8_t iConfiguration; /**< Index of String Descriptor describing this configuration */ + uint8_t bmAttributes; /**< Bitmap: + * D7 Reserved, set to 1. (USB 1.0 Bus Powered) + * D6 Self Powered + * D5 Remote Wakeup + * D4..0 Reserved, set to 0. + */ + uint8_t bMaxPower; /**< Maximum Power Consumption in 2 mA units */ +} cy_stc_usbdev_config_descr_t; + +/** Interface descriptor */ +typedef struct +{ + uint8_t bLength; /**< Size of Descriptor in Bytes (9 Bytes) */ + uint8_t bDescriptorType; /**< Interface Descriptor */ + uint8_t bInterfaceNumber; /**< Number of Interface */ + uint8_t bAlternateSetting; /**< Value used to select alternative setting */ + uint8_t bNumEndpoints; /**< Number of Endpoints used for this interface */ + uint8_t bInterfaceClass; /**< Class Code (Assigned by USB Org) */ + uint8_t bInterfaceSubClass; /**< Subclass Code (Assigned by USB Org) */ + uint8_t bInterfaceProtocol; /**< Protocol Code (Assigned by USB Org) */ + uint8_t iInterface; /**< Index of String Descriptor describing this interface */ +} cy_stc_usbdev_interface_descr_t; + + +/** Endpoint descriptor */ +typedef struct +{ + uint8_t bLength; /**< Size of Descriptor in Bytes */ + uint8_t bDescriptorType; /**< Endpoint Descriptor */ + uint8_t bEndpointAddress; /**< Endpoint Address: + * Bits 0..3 Endpoint Number. + * Bits 4..6 Reserved. Set to Zero + * Bit 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints) + */ + uint8_t bmAttributes; /**< Bitmap: + * Bits 0..1 Transfer Type: 00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt + * Bits 2..7 are reserved. If Isochronous endpoint, + * Bits 3..2: Synchronization + * Type (Iso Mode): 00 = No Synchronization, 01 = Asynchronous, 10 = Adaptive, 11 = Synchronous + * Bits 5..4 = Usage Type (Iso Mode): 00 = Data Endpoint, 01 = Feedback Endpoint, + * 10 = Explicit Feedback Data Endpoint, 11 = Reserved + */ + uint16_t wMaxPacketSize; /**< Maximum Packet Size this endpoint is capable of sending or receiving */ + uint8_t bInterval; /**< Interval for polling endpoint data transfers. Value in frame counts. + * Ignored for Bulk & Control Endpoints. + * Isochronous must equal 1 and field may range from 1 to 255 for interrupt endpoints. + */ +} cy_stc_usbdev_endpoint_descr_t; + +/** \} group_usb_dev_structures_device_descr */ + + +/******************************************************************************* +* Macro for generation code usage +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_macros_device_descr +* \{ +*/ +#define CY_USB_DEV_USB_VERSION_2_0 (0x0200U) /**< USB Specification Release Number 2.0 */ +#define CY_USB_DEV_USB_VERSION_2_1 (0x0201U) /**< USB Specification Release Number 2.1 */ + +/* USB v2.0 spec: Table 9-5. Descriptor Types */ +#define CY_USB_DEV_DEVICE_DESCR (1U) /**< Device Descriptor type */ +#define CY_USB_DEV_CONFIG_DESCR (2U) /**< Device Configuration Descriptor type */ +#define CY_USB_DEV_STRING_DESCR (3U) /**< Device String Descriptor type */ +#define CY_USB_DEV_INTERFACE_DESCR (4U) /**< Device Interface Descriptor type */ +#define CY_USB_DEV_ENDPOINT_DESCR (5U) /**< Device Endpoint Descriptor type */ +#define CY_USB_DEV_DEVICE_QUALIFIER_DESCR (6U) /**< Device Qualifier Descriptor type */ +#define CY_USB_DEV_OTHER_SPEED_CFG_DESCR (7U) /**< Device Other Speed Descriptor type */ +#define CY_USB_DEV_INTERFACE_POWER_DESCR (8U) /**< Device Interface Power Descriptor type */ +#define CY_USB_DEV_BOS_DESCR (15U) /**< Device BOS Descriptor type */ + +/* MS OS String Descriptors */ +#define CY_USB_DEV_MS_OS_STRING_EXT_COMPAT_ID (4U) /**< Extended Compat ID OS Descriptor */ +#define CY_USB_DEV_MS_OS_STRING_EXT_PROPERTEIS (5U) /**< Extended Properties OS Descriptor */ + +/* Standard descriptor lengths */ +#define CY_USB_DEV_DEVICE_DESCR_LENGTH (18U) /**< Device Descriptor length */ +#define CY_USB_DEV_CONFIG_DESCR_LENGTH (9U) /**< Device Configuration Descriptor length */ +#define CY_USB_DEV_INTERFACE_DESCR_LENGTH (9U) /**< Device Interface Descriptor length */ +#define CY_USB_DEV_ENDPOINT_DESCR_LENGTH (7U) /**< Device Endpoint Descriptor length */ +#define CY_USB_DEV_BOS_DESCR_LENGTH (5U) /**< Device BOS Descriptor length */ + +/* String Language ID length */ +#define CY_USB_DEV_STRING_DESCR_LANG_ID_LENGTH (4U) /**< Device String LANG ID Descriptor length */ + +/* bmAttributes in endpoint descriptor */ +#define CY_USB_DEV_EP_CONTROL (0x00U) /**< Control Transfer type */ +#define CY_USB_DEV_EP_ISOCHRONOUS (0x01U) /**< Isochronous Transfer type */ +#define CY_USB_DEV_EP_BULK (0x02U) /**< Bulk Transfer type */ +#define CY_USB_DEV_EP_INTERRUPT (0x03U) /**< Interrupt Transfer type */ +#define CY_USB_DEV_EP_TRANS_TYPE_MASK (0x03U) /**< Transfer type mask */ + +/* For isochronous endpoints only */ +#define CY_USB_DEV_EP_NO_SYNCHRONIZATION (0x00U) /**< No Synchronization of Isochronous endpoint */ +#define CY_USB_DEV_EP_ASYNCHRONOUS (0x04U) /**< Asynchronous Isochronous endpoint */ +#define CY_USB_DEV_EP_ADAPTIVE (0x08U) /**< Adaptive Isochronous endpoint */ +#define CY_USB_DEV_EP_SYNCHRONOUS (0x0CU) /**< Synchronous Isochronous endpoint */ +#define CY_USB_DEV_EP_DATA (0x00U) /**< Data Isochronous endpoint */ +#define CY_USB_DEV_EP_FEEDBACK (0x10U) /**< Feedback Isochronous endpoint */ +#define CY_USB_DEV_EP_IMPLICIT_FEEDBACK (0x20U) /**< Implicit feedback Isochronous endpoint */ + +/** \} group_usb_dev_macros_device_descr */ + +#if defined(__cplusplus) +} +#endif + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + +#endif /* (CY_USB_DEV_DESCR_H) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid.c b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid.c new file mode 100644 index 0000000000000000000000000000000000000000..8ef1e4586068ad870fe652efc041dbf64e6f4ac2 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid.c @@ -0,0 +1,953 @@ +/***************************************************************************//** +* \file cy_usb_dev_hid.c +* \version 2.10 +* +* Provides HID class-specific API implementation. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + + +#include "cy_usb_dev_hid.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + + +/******************************************************************************* +* Internal Macro +*******************************************************************************/ + +/* Get Idle request response length */ +#define HID_IDLE_RATE_LENGTH (1U) + +/* Get Protocol request response length */ +#define HID_PROTOCOL_LENGTH (1U) + +/* Set protocol mask */ +#define HID_PROTOCOL_MASK (0x01U) + +/* Set default idle rate */ +#define HID_IDLE_RATE_INDEFINITE (0U) + + +/******************************************************************************* +* Internal Functions Prototypes +*******************************************************************************/ + +static void HandleBusReset(void *classContext, cy_stc_usb_dev_context_t *devContext); + +static cy_en_usb_dev_status_t HandleRequest(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + cy_stc_usb_dev_context_t *devContext); + +static cy_en_usb_dev_status_t HandleRequestComplete(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + cy_stc_usb_dev_context_t *devContext); + +static cy_en_usb_dev_status_t GetDescriptorHidReportRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_t const *hid); + +static cy_en_usb_dev_status_t GetDescriptorHidClassRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_t const *hid); + +static cy_en_usb_dev_status_t GetReportRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_context_t const *context); + +static cy_en_usb_dev_status_t GetProtocolRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_context_t *context); + +static cy_en_usb_dev_status_t GetIdleRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_t const *hid, + cy_stc_usb_dev_hid_context_t *context); + +static cy_en_usb_dev_status_t SetReportRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_context_t const *context); + +static cy_en_usb_dev_status_t SetReportRequestComplete(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_context_t const *context); + +static cy_en_usb_dev_status_t SetProtocolRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_hid_context_t *context); + +static void UpdateIdleRateTimer(uint32_t idx, cy_stc_usb_dev_hid_context_t *context); + +static cy_en_usb_dev_status_t SetIdleRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_hid_t const *hid, + cy_stc_usb_dev_hid_context_t *context); + +static cy_stc_usb_dev_hid_t const * GetHidStruct(uint32_t intf, + cy_stc_usb_dev_context_t *devContext); + +static cy_en_usb_dev_status_t GetInputReportIdx(uint32_t reportId, uint32_t *idx, + cy_stc_usb_dev_hid_t const *hid, + cy_stc_usb_dev_hid_context_t const *context); + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_HID_Init +****************************************************************************//** +* +* Initializes the HID class. +* This function must be called to enable USB Device HID functionality. +* +* \param config +* The pointer to the HID configuration +* structure \ref cy_stc_usb_dev_hid_config_t. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \param devContext +* The pointer to the USB Device context structure \ref cy_stc_usb_dev_context_t. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +cy_en_usb_dev_status_t Cy_USB_Dev_HID_Init(cy_stc_usb_dev_hid_config_t const *config, + cy_stc_usb_dev_hid_context_t *context, + cy_stc_usb_dev_context_t *devContext) +{ + /* Input parameters verification */ + if ((NULL == config) || (NULL == context) || (NULL == devContext)) + { + return CY_USB_DEV_BAD_PARAM; + } + + /* SETUP data storage */ + context->idleRate = config->timers; + context->idleTimer = &config->timers[config->timersNum]; + context->timersNum = config->timersNum; + + /* Remove custom handlers */ + context->handleGetReport = NULL; + context->handleSetReport = NULL; + + /* Store device context */ + context->devContext = devContext; + + /* Register HID handlers */ + Cy_USB_Dev_RegisterClassBusResetCallback(&HandleBusReset, Cy_USB_Dev_HID_GetClass(context)); + Cy_USB_Dev_RegisterClassRequestRcvdCallback(&HandleRequest, Cy_USB_Dev_HID_GetClass(context)); + Cy_USB_Dev_RegisterClassRequestCmpltCallback(&HandleRequestComplete, Cy_USB_Dev_HID_GetClass(context)); + + return Cy_USB_Dev_RegisterClass(&context->classItem, &context->classObj, context, devContext); +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_HID_UpdateTimer +****************************************************************************//** +* +* Updates the HID Report idle timer and returns the status of the timer. This +* function also reloads the timer if it expires. +* +* \param interface +* Contains the interface number that contains the HID descriptor whose HID timer +* needs to be updated. +* +* \param reportId +* Report ID whose HID timer needs to be updated. +* Pass 0 if report ID is not used. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* The state of the HID timer \ref cy_en_usb_dev_hid_timer_state_t +* +*******************************************************************************/ +cy_en_usb_dev_hid_timer_state_t Cy_USB_Dev_HID_UpdateTimer(uint32_t interface, + uint32_t reportId, + cy_stc_usb_dev_hid_context_t *context) +{ + cy_en_usb_dev_hid_timer_state_t retState = CY_USB_DEV_HID_TIMER_INDEFINITE; + + cy_stc_usb_dev_hid_t const *hidStruct = GetHidStruct(interface, context->devContext); + + /* Check that HID exists for given interface */ + CY_ASSERT_L1(NULL != hidStruct); + + if (NULL != hidStruct) + { + uint32_t idx; + cy_en_usb_dev_status_t locStatus = GetInputReportIdx(reportId, &idx, hidStruct, context); + + /* Check that Report ID exists for given interface */ + CY_ASSERT_L1(CY_USB_DEV_SUCCESS == locStatus); + + if (CY_USB_DEV_SUCCESS == locStatus) + { + /* Protect from race condition between SET_IDLE request and timer update */ + uint32_t intrState = Cy_SysLib_EnterCriticalSection(); + + /* Check if duration is defined */ + if (context->idleRate[idx] != HID_IDLE_RATE_INDEFINITE) + { + /* Run timer */ + if (context->idleTimer[idx] > 0U) + { + context->idleTimer[idx]--; + retState = CY_USB_DEV_HID_TIMER_RUNNING; + } + else + { + context->idleTimer[idx] = context->idleRate[idx]; + retState = CY_USB_DEV_HID_TIMER_EXPIRED; + } + } + + Cy_SysLib_ExitCriticalSection(intrState); + } + } + + return retState; +} + + +/******************************************************************************* +* Function Name: HandleBusReset +****************************************************************************//** +* +* Handles Bus Reset event: clears HID protocol and idle rate timers. +* +* \param classContext +* Contains the interface number that contains the HID descriptor whose HID timer +* needs to be updated. +* +* \param devContext +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* +*******************************************************************************/ +static void HandleBusReset(void *classContext, cy_stc_usb_dev_context_t *devContext) +{ + /* Suppress a compiler warning about unused variables */ + (void) devContext; + + cy_stc_usb_dev_hid_context_t *context = (cy_stc_usb_dev_hid_context_t *) classContext; + + /* Set protocol to default */ + (void) memset((void *) context->protocol, (int32_t) CY_USB_DEV_HID_PROTOCOL_REPORT, (uint32_t) CY_USB_DEV_NUM_INTERFACES_MAX); + + /* Set idle rate to default */ + (void) memset(context->idleRate, (int32_t) HID_IDLE_RATE_INDEFINITE, (uint32_t) context->timersNum); + (void) memset(context->idleTimer, (int32_t) HID_IDLE_RATE_INDEFINITE, (uint32_t) context->timersNum); +} + + +/******************************************************************************* +* Function Name: HandleRequest +****************************************************************************//** +* +* Handles HID class requests (SETUP packet received event). +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param classContext +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \param devContext +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for +* internal configuration and data retention. The user must not modify anything +* in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleRequest(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + cy_stc_usb_dev_context_t *devContext) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Get HID pointer for this interface (all HID requests using wIndex to pass interface) */ + cy_stc_usb_dev_hid_t const *hidStruct = GetHidStruct((uint32_t) transfer->setup.wIndex, devContext); + + if (NULL == hidStruct) + { + return CY_USB_DEV_REQUEST_NOT_HANDLED; + } + + /* Process standard requests */ + if (CY_USB_DEV_STANDARD_TYPE == transfer->setup.bmRequestType.type) + { + if (CY_USB_DEV_RQST_GET_DESCRIPTOR == transfer->setup.bRequest) + { + switch (CY_USB_DEV_GET_DESCR_TYPE(transfer->setup.wValue)) + { + case CY_USB_DEV_HID_REPORT_DESCRIPTOR: + retStatus = GetDescriptorHidReportRequest(transfer, hidStruct); + break; + + case CY_USB_DEV_HID_DESCRIPTOR: + retStatus = GetDescriptorHidClassRequest(transfer, hidStruct); + break; + + default: + /* The request was not recognized */ + break; + } + } + } + /* Process class-specific requests */ + else if (CY_USB_DEV_CLASS_TYPE == transfer->setup.bmRequestType.type) + { + /* Get HID context */ + cy_stc_usb_dev_hid_context_t *context = (cy_stc_usb_dev_hid_context_t *) classContext; + + if (transfer->direction == CY_USB_DEV_DIR_DEVICE_TO_HOST) + { + switch (transfer->setup.bRequest) + { + case CY_USB_DEV_HID_RQST_GET_REPORT: + retStatus = GetReportRequest(transfer, context); + break; + + case CY_USB_DEV_HID_RQST_GET_PROTOCOL: + retStatus = GetProtocolRequest(transfer, context); + break; + + case CY_USB_DEV_HID_RQST_GET_IDLE: + retStatus = GetIdleRequest(transfer, hidStruct, context); + break; + + default: + /* The request was not recognized */ + break; + } + } + else + { + switch (transfer->setup.bRequest) + { + case CY_USB_DEV_HID_RQST_SET_REPORT: + retStatus = SetReportRequest(transfer, context); + break; + + case CY_USB_DEV_HID_RQST_SET_PROTOCOL: + retStatus = SetProtocolRequest(transfer, context); + break; + + case CY_USB_DEV_HID_RQST_SET_IDLE: + retStatus = SetIdleRequest(transfer, hidStruct, context); + break; + + default: + /* The request was not recognized */ + break; + } + } + } + else + { + /* The request was not recognized */ + } + + return (retStatus); +} + + +/******************************************************************************* +* Function Name: HandleRequestComplete +****************************************************************************//** +* +* Completes handling HID class requests that expects data from the host. +* Involved when data from the host was received. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param classContext +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \param devContext +* The pointer to the context structure \ref cy_stc_usb_dev_context_t allocated +* by the user. The structure is used during the USB Device operation for +* internal configuration and data retention. The user must not modify anything +* in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t HandleRequestComplete(cy_stc_usb_dev_control_transfer_t *transfer, + void *classContext, + cy_stc_usb_dev_context_t *devContext) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + /* Suppress a compiler warning about unused variables */ + (void) devContext; + + if (CY_USB_DEV_HID_RQST_SET_REPORT == transfer->setup.bRequest) + { + retStatus = SetReportRequestComplete(transfer, (cy_stc_usb_dev_hid_context_t *) classContext); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: GetDescriptorHidReportRequest +****************************************************************************//** +* +* Handles GET_DESCRIPOR HID Report request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param hid +* The pointer to the the structure that holds HID Class information. +* +* \return +* Returns \ref CY_USB_DEV_SUCCESS. +* The HandleRequest function checks that HID structure exist for the +* specified interface before calling GetDescriptorHidReportRequest function. +* Therefore GetDescriptorHidReportRequest successfully access to +* the HID structure. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetDescriptorHidReportRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_t const *hid) +{ + /* SETUP control transfer */ + transfer->ptr = (uint8_t *) hid->reportDescriptor; + transfer->remaining = hid->reportDescriptorSize; + + return CY_USB_DEV_SUCCESS; +} + + +/******************************************************************************* +* Function Name: GetDescriptorHidClassRequest +****************************************************************************//** +* +* Handles GET_DESCRIPOR HID Class request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param hid +* The pointer to the the structure that holds HID Class information. +* +* \return +* Returns \ref CY_USB_DEV_SUCCESS. +* The HandleRequest function checks that HID structure exist for the +* specified interface before calling GetDescriptorHidClassRequest function. +* Therefore GetDescriptorHidClassRequest successfully access to +* the HID structure. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetDescriptorHidClassRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_t const *hid) +{ + /* SETUP control transfer */ + transfer->ptr = (uint8_t *) hid->hidDescriptor; + transfer->remaining = CY_USB_DEV_HID_DESCRIPTOR_LENGTH; + + return CY_USB_DEV_SUCCESS; +} + + +/******************************************************************************* +* Function Name: GetReportRequest +****************************************************************************//** +* +* Handles GET_REPORT HID Class request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetReportRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_context_t const *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + if (NULL != context->handleGetReport) + { + uint32_t rptSize; + + /* Get from the user report to send */ + retStatus = context->handleGetReport( + (uint32_t) transfer->setup.wIndex, /* Interface */ + (uint32_t) CY_HI8(transfer->setup.wValue), /* Report Type */ + (uint32_t) CY_LO8(transfer->setup.wValue), /* Report ID */ + &(transfer->ptr), + &rptSize); + + transfer->remaining = (uint16_t) rptSize; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: GetProtocolRequest +****************************************************************************//** +* +* Handles GET_PROTOCOL HID Class request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetProtocolRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + uint32_t interface = transfer->setup.wIndex; + + if (interface < CY_USB_DEV_NUM_INTERFACES_MAX) + { + /* SETUP control transfer */ + transfer->ptr = (uint8_t *) &context->protocol[interface]; + transfer->remaining = HID_PROTOCOL_LENGTH; + + retStatus = CY_USB_DEV_SUCCESS; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: GetIdleRequest +****************************************************************************//** +* +* Handles GET_IDLE HID Class request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param hid +* The pointer to the the structure that holds HID Class information. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetIdleRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_t const *hid, + cy_stc_usb_dev_hid_context_t *context) +{ + cy_en_usb_dev_status_t retStatus; + uint32_t idx; + + retStatus = GetInputReportIdx((uint32_t) transfer->setup.wValue, &idx, hid, context); + + if (CY_USB_DEV_SUCCESS == retStatus) + { + /* SETUP control transfer */ + transfer->ptr = &context->idleRate[idx]; + transfer->remaining = HID_IDLE_RATE_LENGTH; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: SetReportRequest +****************************************************************************//** +* +* Handles SET_REPORT HID Class request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t SetReportRequest(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_context_t const *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + if (NULL != context->handleSetReport) + { + /* SETUP control transfer */ + transfer->remaining = transfer->setup.wLength; + transfer->notify = true; + + retStatus = CY_USB_DEV_SUCCESS; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: SetReportRequestComplete +****************************************************************************//** +* +* Completes handling SET_REPORT HID Class request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t SetReportRequestComplete(cy_stc_usb_dev_control_transfer_t *transfer, + cy_stc_usb_dev_hid_context_t const *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + if (NULL != context->handleSetReport) + { + /* Provide the user with report data */ + retStatus = context->handleSetReport( + (uint32_t) transfer->setup.wIndex, /* Interface */ + (uint32_t) CY_HI8(transfer->setup.wValue), /* Report Type */ + (uint32_t) CY_LO8(transfer->setup.wValue), /* Report ID */ + transfer->ptr, + (uint32_t) transfer->size); + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: SetProtocolRequest +****************************************************************************//** +* +* Handles SET_PROTOCOL HID Class request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t SetProtocolRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_hid_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + uint32_t interface = transfer->setup.wIndex; + + if (interface < CY_USB_DEV_NUM_INTERFACES_MAX) + { + context->protocol[interface] = (uint8_t) (transfer->setup.wValue & HID_PROTOCOL_MASK); + + /* SETUP control transfer, no data stage */ + retStatus = CY_USB_DEV_SUCCESS; + } + + return retStatus; +} + + +/******************************************************************************* +* Function Name: UpdateIdleRateTimer +****************************************************************************//** +* +* Updates Idle Rate timer after SET_IDLE request was received. +* +* \param idx +* Idle Rate timer index. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +*******************************************************************************/ +static void UpdateIdleRateTimer(uint32_t idx, cy_stc_usb_dev_hid_context_t *context) +{ + /* Reset timer if Idle rate indefinite */ + if (HID_IDLE_RATE_INDEFINITE == context->idleRate[idx]) + { + context->idleTimer[idx] = 0U; + } + else + { + /* HID spec: Set_Idle request Latency */ + if (context->idleTimer[idx] >= context->idleRate[idx]) + { + /* Reload the timer: wait new period */ + context->idleTimer[idx] = context->idleRate[idx]; + } + else + { + if (context->idleTimer[idx] >= 1U) + { + /* If the current period has gone past the newly prescribed + * time duration, then a report will be generated immediately. + * Clear timer to return TIMER_EXPIRED on next HID_UpdateTimer call. + */ + context->idleTimer[idx] = 0U; + } + else + { + /* A new request will be executed as if it were issued + * immediately after the last report, if the new request + * is received at least 4 milliseconds before the end of + * the currently executing period. If the new request is + * received within 4 milliseconds of the end of the + * current period, then the new request will have no + * effect until after the report + */ + + /* Do nothing: let HID_UpdateTimer continue to counting + * and return TIMER_EXPIRED status. + */ + } + } + } +} + + +/******************************************************************************* +* Function Name: SetIdleRequest +****************************************************************************//** +* +* Handles SET_IDLE HID Class request. +* +* \param transfer +* Pointer to structure that holds SETUP packet and information for +* request processing. +* +* \param hid +* The pointer to the the structure that holds HID Class information. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status of request processing: \ref CY_USB_DEV_SUCCESS or +* \ref CY_USB_DEV_REQUEST_NOT_HANDLED. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t SetIdleRequest(cy_stc_usb_dev_control_transfer_t const *transfer, + cy_stc_usb_dev_hid_t const *hid, + cy_stc_usb_dev_hid_context_t *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + uint32_t reportId = CY_LO8(transfer->setup.wValue); + uint32_t idx; + + /* Get report ID index */ + retStatus = GetInputReportIdx(reportId, &idx, hid, context); + + if (CY_USB_DEV_SUCCESS == retStatus) + { + if (reportId > 0U) + { + /* Set IdleRate for defined report ID then update idle timers */ + context->idleRate[idx] = CY_HI8(transfer->setup.wValue); + UpdateIdleRateTimer(idx, context); + } + else + { + /* Set IdleRate to all Report IDs for this HID interface */ + (void) memset(&context->idleRate[idx], (int32_t) CY_HI8(transfer->setup.wValue), (uint32_t) hid->numInputReports); + + /* Update idle timers */ + for(;idx < hid->numInputReports; ++idx) + { + UpdateIdleRateTimer(idx, context); + } + } + } + + /* SETUP control transfer, no data stage */ + + return retStatus; +} + + +/******************************************************************************* +* Function Name: GetHidStruct +****************************************************************************//** +* +* Returns the pointer to the structure that holds HID Class information +* for a certain interface. +* +* \param intf +* Interface number. +* +* \param devContext +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t allocated +* by the user. +* +* \return +* The pointer to HID interface structure \ref cy_stc_usb_dev_hid_t. +* If interface protocol is not HID the NULL pointer is returned. +* +*******************************************************************************/ +static cy_stc_usb_dev_hid_t const * GetHidStruct(uint32_t intf, cy_stc_usb_dev_context_t *devContext) +{ + uint32_t cfg = Cy_USB_Dev_GetConfigurationIdx(devContext); + + cy_stc_usb_dev_hid_t const *hidStruct = NULL; + + /* Check if interface is valid */ + if (intf < devContext->devDescriptors->configurations[cfg]->numInterfaces) + { + uint32_t alt = Cy_USB_Dev_GetAlternateSettings(intf, devContext); + + /* Get report descriptor */ + hidStruct = devContext->devDescriptors->configurations[cfg]->interfaces[intf]->alternates[alt]->hid; + } + + return hidStruct; +} + + +/******************************************************************************* +* Function Name: GetInputReportIdx +****************************************************************************//** +* +* Finds idle rate timer index for a certain report ID. +* +* \param reportId +* Report ID. If there is no report ID, zero must be passed. +* +* \param idx +* Idle rate timer index. +* +* \param hid +* The pointer to the the structure that holds HID Class information. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Status code of the function execution \ref cy_en_usb_dev_status_t. +* +*******************************************************************************/ +static cy_en_usb_dev_status_t GetInputReportIdx(uint32_t reportId, uint32_t *idx, + cy_stc_usb_dev_hid_t const *hid, + cy_stc_usb_dev_hid_context_t const *context) +{ + cy_en_usb_dev_status_t retStatus = CY_USB_DEV_REQUEST_NOT_HANDLED; + + if (0U == reportId) + { + /* Return start index in idleTimer array */ + *idx = hid->inputReportPos; + retStatus = CY_USB_DEV_SUCCESS; + } + else + { + /* Check that input report ID exists */ + if (reportId < hid->inputReportIdxSize) + { + /* Get report ID index in timers array */ + uint32_t tmpIdx = (uint32_t) hid->inputReportIdx[reportId]; + + /* Check that index value is valid (0 is free location) */ + if ((tmpIdx > 0U) && (tmpIdx <= context->timersNum)) + { + /* Return index in idleTimer array for report ID */ + *idx = (tmpIdx - 1U); + retStatus = CY_USB_DEV_SUCCESS; + } + } + } + + return retStatus; +} + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid.h new file mode 100644 index 0000000000000000000000000000000000000000..10bc0d00faed23330468abee38ec17b1a5f4931c --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid.h @@ -0,0 +1,321 @@ +/***************************************************************************//** +* \file cy_usb_dev_hid.h +* \version 2.10 +* +* Provides HID class-specific API declarations. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + + +/** +* \addtogroup group_usb_dev_hid +* This section provides the API description for the HID class. +* \{ +* \defgroup group_usb_dev_hid_macros Macros +* \defgroup group_usb_dev_hid_functions Functions +* \defgroup group_usb_dev_hid_data_structures Data Structures +* \defgroup group_usb_dev_hid_enums Enumerated Types +* \} +*/ + + +#if !defined(CY_USB_DEV_HID_H) +#define CY_USB_DEV_HID_H + +#include "cy_usb_dev.h" + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +#if defined(__cplusplus) +extern "C" { +#endif + + +/******************************************************************************* +* Enumerated Types +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_hid_enums +* \{ +*/ + +/** Timer state */ +typedef enum +{ + CY_USB_DEV_HID_TIMER_EXPIRED, /**< Timer expired */ + CY_USB_DEV_HID_TIMER_RUNNING, /**< Timer is running */ + CY_USB_DEV_HID_TIMER_INDEFINITE, /**< Report is sent when data or state changes */ +} cy_en_usb_dev_hid_timer_state_t; + +/** \} group_usb_dev_hid_enums */ + + + +/******************************************************************************* +* Type Definitions +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_hid_data_structures +* \{ +*/ + +/** Handler for GET_REPORT request received */ +typedef cy_en_usb_dev_status_t (* cy_cb_usbfs_dev_hid_get_report_t) + (uint32_t intf, uint32_t type, uint32_t id, + uint8_t **report, uint32_t *size); + +/** Handler for SET_REPORT request completed. The Host sent report data to Device. */ +typedef cy_en_usb_dev_status_t (* cy_cb_usbfs_dev_hid_set_report_t) + (uint32_t intf, uint32_t type, uint32_t id, + uint8_t *report, uint32_t size); + +/** HID class configuration structure */ +typedef struct +{ + /** The pointer to the HID idle rate timers array. The array size must be 2 + * times greater than number of HID idle rate timers. + */ + uint8_t *timers; + + /** Number of HID idle rate timers (equal to number of report IDs, if + * report ID is not used report consumes 1 idle rate timer). + */ + uint8_t timersNum; + +} cy_stc_usb_dev_hid_config_t; + +/** HID class context structure. +* All fields for the HID context structure are internal. Firmware never reads or +* writes these values. Firmware allocates the structure and provides the +* address of the structure to the middleware in HID function calls. Firmware +* must ensure that the defined instance of this structure remains in scope while +* the middleware is in use. +*/ +typedef struct +{ + /** \cond INTERNAL */ + + /** Pointer to device context */ + cy_stc_usb_dev_context_t *devContext; + + /** Class functions pointers */ + cy_stc_usb_dev_class_t classObj; + + /** Class linked list item */ + cy_stc_usb_dev_class_ll_item_t classItem; + + /** HID boot protocol options */ + volatile uint8_t protocol[CY_USB_DEV_NUM_INTERFACES_MAX]; + + /** HID idle rates array */ + uint8_t *idleRate; + + /** HID idle rate timers array */ + uint8_t *idleTimer; + + /** Number of HID idle rate timers (equal to number of report IDs) */ + uint8_t timersNum; + + /** Pointer to function that handles GET_REPORT requests */ + cy_cb_usbfs_dev_hid_get_report_t handleGetReport; + + /** Pointer to function that handles SET_REPORT requests */ + cy_cb_usbfs_dev_hid_set_report_t handleSetReport; + /** \endcond */ + +} cy_stc_usb_dev_hid_context_t; + +/** \} group_usb_dev_hid_data_structures */ + + +/******************************************************************************* +* Function Prototypes +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_hid_functions +* \{ +*/ +cy_en_usb_dev_status_t Cy_USB_Dev_HID_Init(cy_stc_usb_dev_hid_config_t const *config, + cy_stc_usb_dev_hid_context_t *context, + cy_stc_usb_dev_context_t *devContext); + +cy_en_usb_dev_hid_timer_state_t Cy_USB_Dev_HID_UpdateTimer(uint32_t interface, + uint32_t reportId, + cy_stc_usb_dev_hid_context_t *context); + +__STATIC_INLINE uint32_t Cy_USB_Dev_HID_GetProtocol(uint32_t interface, + cy_stc_usb_dev_hid_context_t const *context); + +__STATIC_INLINE void Cy_USB_Dev_HID_RegisterGetReportCallback(cy_cb_usbfs_dev_hid_get_report_t callback, + cy_stc_usb_dev_hid_context_t *context); + +__STATIC_INLINE void Cy_USB_Dev_HID_RegisterSetReportCallback(cy_cb_usbfs_dev_hid_set_report_t callback, + cy_stc_usb_dev_hid_context_t *context); + +__STATIC_INLINE cy_stc_usb_dev_class_t * Cy_USB_Dev_HID_GetClass(cy_stc_usb_dev_hid_context_t *context); + +/** \} group_usb_dev_hid_functions */ + + +/******************************************************************************* +* API Constants +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_hid_macros +* \{ +*/ +/** Protocol options */ +#define CY_USB_DEV_HID_PROTOCOL_BOOT (0U) /**< Boot Protocol */ +#define CY_USB_DEV_HID_PROTOCOL_REPORT (1U) /**< Report Protocol */ + +/** Report types */ +#define CY_USB_DEV_HID_REPORT_TYPE_INPUT (1U) /**< Input report type */ +#define CY_USB_DEV_HID_REPORT_TYPE_OUTPUT (2U) /**< Output report type */ +#define CY_USB_DEV_HID_REPORT_TYPE_FEATURE (3U) /**< Feature report type */ + +/** HID Class Requests */ +#define CY_USB_DEV_HID_RQST_GET_REPORT (0x1U) /**< GET_REPORT HID Class Request */ +#define CY_USB_DEV_HID_RQST_GET_IDLE (0x2U) /**< GET_IDLE HID Class Request */ +#define CY_USB_DEV_HID_RQST_GET_PROTOCOL (0x3U) /**< GET_PROTOCOL HID Class Request */ +#define CY_USB_DEV_HID_RQST_SET_REPORT (0x9U) /**< SET_REPORT HID Class Request */ +#define CY_USB_DEV_HID_RQST_SET_IDLE (0xAU) /**< SET_IDLE HID Class Request */ +#define CY_USB_DEV_HID_RQST_SET_PROTOCOL (0xBU) /**< SET_PROTOCOL HID Class Request */ +/** \} group_usb_dev_hid_functions */ + + +/******************************************************************************* +* In-line Function Implementation +*******************************************************************************/ + +/** +* \addtogroup group_usb_dev_hid_functions +* \{ +*/ + +/******************************************************************************* +* Function Name: Cy_USB_Dev_HID_RegisterGetReportCallback +****************************************************************************//** +* +* Registers a callback function that handles a GET_REPORT request. +* The GET_REPORT request is STALLed if the callback function is not registered +* or returns an error. +* To remove the callback function, pass NULL as the function pointer. +* +* \param callback +* The pointer to a callback function. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_HID_RegisterGetReportCallback(cy_cb_usbfs_dev_hid_get_report_t callback, + cy_stc_usb_dev_hid_context_t *context) +{ + context->handleGetReport = callback; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_HID_RegisterSetReportCallback +****************************************************************************//** +* +* Registers a callback function that handles SET_REPORT request. This function +* is called when data stage of control transfer was completed (USB Device +* received report data from the USB Host). The SET_REPORT request is STALLed +* if the callback function is not registered or returns an error. +* To remove handler, set the handle parameter to NULL and call this function. +* +* \param callback +* The pointer to a callback function. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +*******************************************************************************/ +__STATIC_INLINE void Cy_USB_Dev_HID_RegisterSetReportCallback(cy_cb_usbfs_dev_hid_set_report_t callback, + cy_stc_usb_dev_hid_context_t *context) +{ + context->handleSetReport = callback; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_HID_GetClass +****************************************************************************//** +* +* Returns pointer to the HID class structure. +* This function is useful to override class event handlers using +* \ref group_usb_dev_functions_class_support. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* The pointer to the HID class structure. +* +*******************************************************************************/ +__STATIC_INLINE cy_stc_usb_dev_class_t * Cy_USB_Dev_HID_GetClass(cy_stc_usb_dev_hid_context_t *context) +{ + return &context->classObj; +} + + +/******************************************************************************* +* Function Name: Cy_USB_Dev_HID_GetProtocol +****************************************************************************//** +* +* Returns the HID protocol value for a certain interface. +* +* \param interface +* Interface number. +* +* \param context +* The pointer to the context structure \ref cy_stc_usb_dev_hid_context_t +* allocated by the user. The structure is used during the HID Class operation +* for internal configuration and data retention. The user must not modify +* anything in this structure. +* +* \return +* Supported protocol: \ref CY_USB_DEV_HID_PROTOCOL_BOOT or +* \ref CY_USB_DEV_HID_PROTOCOL_REPORT. +* +*******************************************************************************/ +__STATIC_INLINE uint32_t Cy_USB_Dev_HID_GetProtocol(uint32_t interface, + cy_stc_usb_dev_hid_context_t const *context) +{ + return ((interface < CY_USB_DEV_NUM_INTERFACES_MAX) ? + context->protocol[interface] : (uint32_t) -1); +} + +/** \} group_usb_dev_hid_functions */ + +#if defined(__cplusplus) +} +#endif + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + +#endif /* (CY_USB_DEV_HID_H) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid_descr.h b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid_descr.h new file mode 100644 index 0000000000000000000000000000000000000000..2b46132a05b4805cf9022c0321cae8f870edd6c9 --- /dev/null +++ b/bsp/cypress/libraries/IFX_PSOC6_HAL/mtb_shared/usbdev/cy_usb_dev_hid_descr.h @@ -0,0 +1,54 @@ +/***************************************************************************//** +* \file cy_usb_dev_hid_descr.h +* \version 2.10 +* +* Provides HID class-specific descriptor defines. +* +******************************************************************************** +* \copyright +* (c) 2018-2021, Cypress Semiconductor Corporation (an Infineon company) or +* an affiliate of Cypress Semiconductor Corporation. All rights reserved. +* You may use this file only in accordance with the license, terms, conditions, +* disclaimers, and limitations in the end user license agreement accompanying +* the software package with which this file was provided. +*******************************************************************************/ + +#if !defined(CY_USB_DEV_HID_DESCR_H) +#define CY_USB_DEV_HID_DESCR_H + +#if (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) + +#if defined(__cplusplus) +extern "C" { +#endif + + +/******************************************************************************* +* API Constants +*******************************************************************************/ + +/** \cond INTERNAL */ +/* Supported HID version */ +#define CY_USB_DEV_HID_VERSION_1_11 (0x0111U) + +/* HID Class */ +#define CY_USB_DEV_HID_CLASS (3U) +#define CY_USB_DEV_HID_SUBCLASS_NONE (0U) +#define CY_USB_DEV_HID_PROTOCOL_NONE (0U) + +/* Descriptors */ +#define CY_USB_DEV_HID_DESCRIPTOR (33U) +#define CY_USB_DEV_HID_DESCRIPTOR_LENGTH (9U) +#define CY_USB_DEV_HID_REPORT_DESCRIPTOR (34U) +/** \endcond */ + +#if defined(__cplusplus) +} +#endif + +#endif /* (defined(CY_IP_MXUSBFS) || defined(CY_IP_M0S8USBDSS)) */ + +#endif /* (CY_USB_DEV_HID_DESCR_H) */ + + +/* [] END OF FILE */ diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/.config b/bsp/cypress/psoc6-cy8cproto-4343w/.config index 9351f4e751d6761e16b93fc4d60b8f4dac2f467b..1473c6110bf6c92f05f23be667d97678a8b94388 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/.config +++ b/bsp/cypress/psoc6-cy8cproto-4343w/.config @@ -111,17 +111,7 @@ CONFIG_FINSH_USING_DESCRIPTION=y # CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set # CONFIG_FINSH_USING_AUTH is not set CONFIG_FINSH_ARG_MAX=10 -CONFIG_RT_USING_DFS=y -CONFIG_DFS_USING_POSIX=y -CONFIG_DFS_USING_WORKDIR=y -CONFIG_DFS_FILESYSTEMS_MAX=4 -CONFIG_DFS_FILESYSTEM_TYPES_MAX=4 -CONFIG_DFS_FD_MAX=16 -# CONFIG_RT_USING_DFS_MNTTABLE is not set -# CONFIG_RT_USING_DFS_ELMFAT is not set -CONFIG_RT_USING_DFS_DEVFS=y -# CONFIG_RT_USING_DFS_ROMFS is not set -# CONFIG_RT_USING_DFS_RAMFS is not set +# CONFIG_RT_USING_DFS is not set # CONFIG_RT_USING_FAL is not set # CONFIG_RT_USING_LWP is not set @@ -143,13 +133,11 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64 CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_ADC is not set # CONFIG_RT_USING_DAC is not set -CONFIG_RT_USING_PWM=y +# CONFIG_RT_USING_PWM is not set # CONFIG_RT_USING_MTD_NOR is not set # CONFIG_RT_USING_MTD_NAND is not set # CONFIG_RT_USING_PM is not set -CONFIG_RT_USING_RTC=y -# CONFIG_RT_USING_ALARM is not set -# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_USING_RTC is not set # CONFIG_RT_USING_SDIO is not set # CONFIG_RT_USING_SPI is not set # CONFIG_RT_USING_WDT is not set @@ -176,20 +164,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # POSIX (Portable Operating System Interface) layer # -CONFIG_RT_USING_POSIX_FS=y -CONFIG_RT_USING_POSIX_DEVIO=y -CONFIG_RT_USING_POSIX_STDIO=y -# CONFIG_RT_USING_POSIX_POLL is not set -# CONFIG_RT_USING_POSIX_SELECT is not set -# CONFIG_RT_USING_POSIX_SOCKET is not set -# CONFIG_RT_USING_POSIX_TERMIOS is not set -# CONFIG_RT_USING_POSIX_AIO is not set -# CONFIG_RT_USING_POSIX_MMAN is not set -CONFIG_RT_USING_POSIX_DELAY=y -CONFIG_RT_USING_POSIX_CLOCK=y +# CONFIG_RT_USING_POSIX_FS is not set +# CONFIG_RT_USING_POSIX_DELAY is not set +# CONFIG_RT_USING_POSIX_CLOCK is not set # CONFIG_RT_USING_POSIX_TIMER is not set -CONFIG_RT_USING_PTHREADS=y -CONFIG_PTHREAD_NUM_MAX=8 +# CONFIG_RT_USING_PTHREADS is not set # CONFIG_RT_USING_MODULE is not set # @@ -524,7 +503,6 @@ CONFIG_PTHREAD_NUM_MAX=8 # CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_SHT2X is not set # CONFIG_PKG_USING_SHT3X is not set -# CONFIG_PKG_USING_ADT74XX is not set # CONFIG_PKG_USING_AS7341 is not set # CONFIG_PKG_USING_STM32_SDIO is not set # CONFIG_PKG_USING_ICM20608 is not set @@ -697,20 +675,22 @@ CONFIG_BSP_USING_UART=y # CONFIG_BSP_USING_UART3 is not set # CONFIG_BSP_USING_UART4 is not set CONFIG_BSP_USING_UART5=y -CONFIG_BSP_USING_PWM=y -CONFIG_BSP_USING_PWM0=y -CONFIG_BSP_USING_PWM0_CH7=y -# CONFIG_BSP_USING_PWM0_PORT2 is not set -# CONFIG_BSP_USING_PWM0_PORT5 is not set -# CONFIG_BSP_USING_PWM0_PORT7 is not set -CONFIG_BSP_USING_PWM0_PORT9=y -# CONFIG_BSP_USING_PWM0_PORT10 is not set -# CONFIG_BSP_USING_PWM0_PORT12 is not set +# CONFIG_BSP_USING_PWM is not set +# CONFIG_BSP_USING_SPI is not set # CONFIG_BSP_USING_ADC is not set +# CONFIG_BSP_USING_SDMMC is not set # CONFIG_BSP_USING_QSPI_FLASH is not set # CONFIG_BSP_USING_HW_I2C is not set # CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_USBD is not set +# CONFIG_BSP_USING_RTC is not set +# CONFIG_BSP_USING_ON_CHIP_FLASH is not set +# CONFIG_BSP_USING_WDT is not set +# CONFIG_BSP_USING_DAC is not set +# CONFIG_BSP_USING_TIM is not set # # Board extended module Drivers # +# CONFIG_BSP_USING_SLIDER is not set +# CONFIG_BSP_USING_RW007 is not set diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/.cproject b/bsp/cypress/psoc6-cy8cproto-4343w/.cproject new file mode 100644 index 0000000000000000000000000000000000000000..52796a8a5ddae1535cb1516ce22884f022970b12 --- /dev/null +++ b/bsp/cypress/psoc6-cy8cproto-4343w/.cproject @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/.project b/bsp/cypress/psoc6-cy8cproto-4343w/.project index e9e2cefe654d93982b5c01546a0ef3dc78294eea..f7b356f1f9d1bb0c6930b4eab126bcf73510cb4f 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/.project +++ b/bsp/cypress/psoc6-cy8cproto-4343w/.project @@ -1,28 +1,28 @@ - psoc6-pioneerkit_modus - - + dist_ide_project + + - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.core.ccnature - com.cypress.studio.app.cymodusnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - + + + + org.eclipse.cdt.core.cnature + com.cypress.studio.app.cymodusnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/.settings/dist_ide_project.DAPLink.Debug.rttlaunch b/bsp/cypress/psoc6-cy8cproto-4343w/.settings/dist_ide_project.DAPLink.Debug.rttlaunch new file mode 100644 index 0000000000000000000000000000000000000000..8c8040b3ad7068b35c0726659f2cc089486a56c0 --- /dev/null +++ b/bsp/cypress/psoc6-cy8cproto-4343w/.settings/dist_ide_project.DAPLink.Debug.rttlaunch @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/.settings/dist_ide_project.OpenOCD.Debug.rttlaunch b/bsp/cypress/psoc6-cy8cproto-4343w/.settings/dist_ide_project.OpenOCD.Debug.rttlaunch new file mode 100644 index 0000000000000000000000000000000000000000..2b3931d2f9b34583007da98b964132d6da3a075f --- /dev/null +++ b/bsp/cypress/psoc6-cy8cproto-4343w/.settings/dist_ide_project.OpenOCD.Debug.rttlaunch @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/EventRecorderStub.scvd b/bsp/cypress/psoc6-cy8cproto-4343w/EventRecorderStub.scvd deleted file mode 100644 index 2956b29683898915efa436cc948384a2c431dc31..0000000000000000000000000000000000000000 --- a/bsp/cypress/psoc6-cy8cproto-4343w/EventRecorderStub.scvd +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/README.md b/bsp/cypress/psoc6-cy8cproto-4343w/README.md index cce3675e03df35a816dfe25677713dcb0a937111..ea40bb837e51a8e3fba7df197bcffcf3ec3c47c0 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/README.md +++ b/bsp/cypress/psoc6-cy8cproto-4343w/README.md @@ -34,7 +34,7 @@ | **片上外设** | **支持情况** | **备注** | | :----------: | :----------: | :-----------: | -| USB 转串口 | 支持 | — | +| USB 转串口 | 支持 | UART5 | | GPIO | 支持 | — | | UART | 支持 | UART0-5 | | I2C | 支持 | 软件+硬件 I2C | @@ -42,29 +42,26 @@ | WDT | 支持 | — | | PWM | 支持 | — | | SPI | 支持 | — | -| HardTimer | 暂不支持 | — | -| DAC | 暂不支持 | — | -| Flash | 暂不支持 | — | +| HardTimer | 支持 | — | +| DAC | 支持 | IDAC | +| Flash | 支持 | 片内 Falsh | +| Touch | 支持 | 触摸滑条 | | SDIO | 暂不支持 | — | | USB Device | 暂不支持 | — | | USB Host | 暂不支持 | — | -## 使用说明 +## 快速上手 -- 快速上手 +本 BSP 是以 `MDK V5` 和 `RT-Thread Studio` 为开发环境(编译器:ARMClang / GCC),接下来介绍如何将系统运行起来。 - 本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。 - - -### 快速上手 - -本 BSP 是以 MDK V5 开发环境(编译器:ARMClang ),接下来介绍如何将系统运行起来。 +### 使用 MDK V5 开发 #### 硬件连接 使用数据线连接开发板到 PC。 #### 编译下载 + 1、配置工程: 首先打开 MDK ,若没有安装 `Cypress-PSoC6` 的芯片支持包会提示在线安装,根据提示安装即可。若受网络问题,可以进入 [keil](https://www.keil.com/dd2/pack) 官网下载安装包,离线安装。 @@ -75,17 +72,39 @@ 3、下载此工程: - 工程默认配置使用板载 `DAP-LINK` 使用 `SWD` 方式下载程序,使用数据线连接开发板,编译之后直接点击下载按钮即可。 -#### 运行结果 +### 使用 RT-Thread Studio 开发 + +#### 导入工程 + +* 首先打开 `RT-Thread Studio` 开发工具,点加左上角文件—>导入—> RT-Thread Studio项目到工作空间中。 + +![](./figures/studio1.png) + +* 接着选择 `PSoC6 CY8CKIT-062S2-43012` 开发板支持包的目录,进行导入。 + +![](./figures/studio2.png) + +#### 编译下载 + +* 点击 IDE 左上角的构建选项进行工程的编译。 + +![](./figures/studio3-build.png) + +* 当编译无错误警告时,点击 `Debug` 或 `Download` 选项进行调试/下载。 + + 注:若点击下载并下载成功后串口终端无显示信息,请手动按下复位按键进行重启运行。 + + ![](./figures/studio4-download.png) + +## 运行结果 下载程序成功之后,系统会自动运行。打开终端工具串口助手,选择波特率为 115200。复位设备后,LED 将会以 500HZ 的频率闪烁,而且在终端上可以看到 `RT-Thread` 的输出信息: 注:推荐使用串口调试助手如:`MobaXterm` ``` - \ | / - RT - Thread Operating System / | \ 4.1.1 build Jul 25 2022 18:03:35 @@ -93,7 +112,7 @@ msh > ``` -## 联系人信息 +## 联系人 维护人: diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/board/Kconfig b/bsp/cypress/psoc6-cy8cproto-4343w/board/Kconfig index 7d1f66e6a4e82bce0e2aadd9d56fde3ba98791f2..df955818eb1e519966c8dd25aa8f67b50439a400 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/board/Kconfig +++ b/bsp/cypress/psoc6-cy8cproto-4343w/board/Kconfig @@ -204,6 +204,11 @@ menu "On-chip Peripheral Drivers" endif endif + config BSP_USING_USBD + bool "Enable USB Device" + select RT_USING_USB_DEVICE + default n + menuconfig BSP_USING_RTC bool "Enable RTC" select RT_USING_RTC @@ -242,7 +247,7 @@ menu "On-chip Peripheral Drivers" bool "Enable DAC2" default n endif - + menuconfig BSP_USING_TIM bool "Enable timer" default n @@ -255,8 +260,6 @@ menu "On-chip Peripheral Drivers" bool "Enable TIM2" default n endif - - endmenu menu "Board extended module Drivers" diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/board/SConscript b/bsp/cypress/psoc6-cy8cproto-4343w/board/SConscript index d04b7b6c0922686bf3549390f0d3287531fc0594..644e51cf91cc4ade1546d76e9b95f62ba7b62938 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/board/SConscript +++ b/bsp/cypress/psoc6-cy8cproto-4343w/board/SConscript @@ -30,11 +30,15 @@ startup_path_prefix = SDK_LIB if rtconfig.PLATFORM == 'gcc': src += [startup_path_prefix + '/IFX_PSOC6_HAL/TARGET_CY8CKIT-062S2-43012/COMPONENT_CM4/TOOLCHAIN_GCC_ARM/startup_psoc6_02_cm4.S'] + src += [startup_path_prefix + + '/IFX_PSOC6_HAL/mtb-pdl-cat1/drivers/source/TOOLCHAIN_GCC_ARM/cy_syslib_gcc.S'] elif rtconfig.PLATFORM in ['armcc', 'armclang']: src += [startup_path_prefix + '/IFX_PSOC6_HAL/TARGET_CY8CKIT-062S2-43012/COMPONENT_CM4/TOOLCHAIN_ARM/startup_psoc6_02_cm4.S'] + src += [startup_path_prefix + + '/IFX_PSOC6_HAL/mtb-pdl-cat1/drivers/source/TOOLCHAIN_ARM/cy_syslib_mdk.S'] -CPPDEFINES = ['IFX_PSOC6_43012', 'CY_USING_HAL', 'COMPONENT_CAT1A', 'COMPONENT_CAT1', 'COMPONENT_BSP_DESIGN_MODUS'] +CPPDEFINES = ['CY8C624ABZI_S2D44', 'IFX_PSOC6_43012', 'CY_USING_HAL', 'COMPONENT_CAT1A', 'COMPONENT_CAT1', 'COMPONENT_BSP_DESIGN_MODUS'] group = DefineGroup('Drivers', src, depend=[''], CPPPATH=path, CPPDEFINES=CPPDEFINES) Return('group') \ No newline at end of file diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/board/board.c b/bsp/cypress/psoc6-cy8cproto-4343w/board/board.c index 42122617bf1aee515b73657db32c443b8a5724aa..98ed84a6c2973d0ea1bf2e6a896b90c7fe329b42 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/board/board.c +++ b/bsp/cypress/psoc6-cy8cproto-4343w/board/board.c @@ -9,7 +9,6 @@ */ #include "board.h" -#include "drv_uart.h" void cy_bsp_all_init(void) { diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/board/board.h b/bsp/cypress/psoc6-cy8cproto-4343w/board/board.h index 5518417fc669fbf2912d967015518a67df21f3e9..257de99ee895c63c4ec7ade3a627da278719b5fa 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/board/board.h +++ b/bsp/cypress/psoc6-cy8cproto-4343w/board/board.h @@ -16,10 +16,16 @@ #include "drv_common.h" #include "drv_gpio.h" +#include "cy_result.h" +#include "cybsp_types.h" #include "cyhal.h" #include "cybsp.h" -#include "cy_pdl.h" -#include "cy_retarget_io.h" + +#ifdef BSP_USING_USBD + #include "cy_usb_dev.h" + #include "cy_usb_dev_hid.h" + #include "cycfg_usbdev.h" +#endif /*FLASH CONFIG*/ #define IFX_FLASH_START_ADRESS ((uint32_t)0x10000000) @@ -40,6 +46,7 @@ #ifdef __ARMCC_VERSION extern int Image$$RW_IRAM1$$ZI$$Limit; #define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) + #define HEAP_END IFX_SRAM_END #elif __ICCARM__ #pragma section="HEAP" #define HEAP_BEGIN (__segment_end("HEAP")) @@ -50,8 +57,6 @@ #define HEAP_END (void*)&__HeapLimit #endif -#define HEAP_END IFX_SRAM_END - void cy_bsp_all_init(void); #endif diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/board/linker_scripts/link.ld b/bsp/cypress/psoc6-cy8cproto-4343w/board/linker_scripts/link.ld index 8425d46368125e05e37f2bf8c9b222db105c6c8f..8520b06adde252916bf305ba1c965002151b1be5 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/board/linker_scripts/link.ld +++ b/bsp/cypress/psoc6-cy8cproto-4343w/board/linker_scripts/link.ld @@ -172,12 +172,41 @@ SECTIONS *(SORT(.dtors.*)) *(.dtors) + . = ALIGN(4); /* Read-only code (constants). */ *(.rodata .rodata.* .constdata .constdata.* .conststring .conststring.*) - KEEP(*(.eh_frame*)) - } > flash + /* section information for utest */ + . = ALIGN(4); + __rt_utest_tc_tab_start = .; + KEEP(*(UtestTcTab)) + __rt_utest_tc_tab_end = .; + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for modules */ + . = ALIGN(4); + __rtmsymtab_start = .; + KEEP(*(RTMSymTab)) + __rtmsymtab_end = .; + + /* section information for initialization */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + + } > flash .ARM.extab : { @@ -213,70 +242,24 @@ SECTIONS __copy_table_end__ = .; } > flash - /* setction information for finsh shell begin */ - FSymTab : - { - . = ALIGN(4); - __fsymtab_start = .; - KEEP(*(FSymTab)) - __fsymtab_end = .; - } > flash - VSymTab : - { - . = ALIGN(4); - __vsymtab_start = .; - KEEP(*(VSymTab)) - __vsymtab_end = .; - } > flash - /* section information for utest */ - UtestTcTab : - { - . = ALIGN(4); - __rt_utest_tc_tab_start = .; - KEEP(*(UtestTcTab)) - __rt_utest_tc_tab_end = .; - } - /* section information for at server */ - RtAtCmdTab : - { - . = ALIGN(4); - __rtatcmdtab_start = .; - KEEP(*(UtestTcTab)) - __rtatcmdtab_end = .; - } - /* section information for modules */ - RTMSymTab : - { - . = ALIGN(4); - __rtmsymtab_start = .; - KEEP(*(UtestTcTab)) - __rtmsymtab_end = .; - } - /* section information for initial. */ - rti_fn : - { - . = ALIGN(4); - __rt_init_start = .; - KEEP(*(SORT(.rti_fn*))) - __rt_init_end = .; - } > flash - rti_fn : + + . = ALIGN(4); + .ctors : { - . = ALIGN(4); PROVIDE(__ctors_start__ = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) - __rt_init_end = .; PROVIDE(__ctors_end__ = .); } > flash - init_array : + + . = ALIGN(4); + .dtors : { - . = ALIGN(4); - __ctors_start__ = .; - KEEP(*(SORT(.init_array*))) - __ctors_end__ = .; - } > flash - /* setction information for finsh shell end */ + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } > flash /* To clear multiple BSS sections, * uncomment .zero.table section and, @@ -422,7 +405,6 @@ SECTIONS KEEP(*(.cy_sflash_user_data)) } > sflash_user_data - /* Supervisory Flash: Normal Access Restrictions (NAR) */ .cy_sflash_nar : { diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio1.png b/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio1.png new file mode 100644 index 0000000000000000000000000000000000000000..85c4bdc662b91321f3ad24b39fd96165e302667d Binary files /dev/null and b/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio1.png differ diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio2.png b/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio2.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce0690138b4231618d1bff0c0e70b983d1eca80 Binary files /dev/null and b/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio2.png differ diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio3-build.png b/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio3-build.png new file mode 100644 index 0000000000000000000000000000000000000000..5019c1d219392828e3ecfcdb735cf36ef820be5d Binary files /dev/null and b/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio3-build.png differ diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio4-download.png b/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio4-download.png new file mode 100644 index 0000000000000000000000000000000000000000..526e134dc7493367616e110546b36d5a24b2e07a Binary files /dev/null and b/bsp/cypress/psoc6-cy8cproto-4343w/figures/studio4-download.png differ diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/makefile.targets b/bsp/cypress/psoc6-cy8cproto-4343w/makefile.targets new file mode 100644 index 0000000000000000000000000000000000000000..a5e80b985b8acba18b516a20dccfac127430176b --- /dev/null +++ b/bsp/cypress/psoc6-cy8cproto-4343w/makefile.targets @@ -0,0 +1,6 @@ +clean2: + -$(RM) $(CC_DEPS)$(C++_DEPS)$(C_UPPER_DEPS)$(CXX_DEPS)$(SECONDARY_FLASH)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS) + -$(RM) $(OBJS) *.elf + -@echo ' ' + +*.elf: $(wildcard ../board/linker_scripts/link.ld) diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/project.uvoptx b/bsp/cypress/psoc6-cy8cproto-4343w/project.uvoptx index 667ba5455e38a16213550f7ea188f6b57ea71806..100eba6d97309fe47d54cba6bae00ccb762d285b 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/project.uvoptx +++ b/bsp/cypress/psoc6-cy8cproto-4343w/project.uvoptx @@ -73,7 +73,7 @@ 0 - 1 + 0 0 1 @@ -238,8 +238,8 @@ 0 0 0 - ..\..\..\components\libc\compilers\common\stdlib.c - stdlib.c + ..\..\..\components\libc\compilers\common\cctype.c + cctype.c 0 0 @@ -250,8 +250,56 @@ 0 0 0 - ..\..\..\components\libc\compilers\common\time.c - time.c + ..\..\..\components\libc\compilers\common\cstdio.c + cstdio.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\cstdlib.c + cstdlib.c + 0 + 0 + + + 2 + 7 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\cstring.c + cstring.c + 0 + 0 + + + 2 + 8 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\ctime.c + ctime.c + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\cwchar.c + cwchar.c 0 0 @@ -265,7 +313,7 @@ 0 3 - 6 + 10 1 0 0 @@ -277,7 +325,7 @@ 3 - 7 + 11 1 0 0 @@ -289,7 +337,7 @@ 3 - 8 + 12 1 0 0 @@ -301,7 +349,7 @@ 3 - 9 + 13 2 0 0 @@ -313,7 +361,7 @@ 3 - 10 + 14 1 0 0 @@ -333,7 +381,7 @@ 0 4 - 11 + 15 1 0 0 @@ -345,7 +393,7 @@ 4 - 12 + 16 1 0 0 @@ -357,7 +405,7 @@ 4 - 13 + 17 1 0 0 @@ -369,7 +417,7 @@ 4 - 14 + 18 1 0 0 @@ -381,7 +429,7 @@ 4 - 15 + 19 1 0 0 @@ -393,7 +441,7 @@ 4 - 16 + 20 1 0 0 @@ -405,7 +453,7 @@ 4 - 17 + 21 1 0 0 @@ -417,7 +465,7 @@ 4 - 18 + 22 1 0 0 @@ -429,7 +477,7 @@ 4 - 19 + 23 1 0 0 @@ -443,13 +491,13 @@ Drivers - 1 + 0 0 0 0 5 - 20 + 24 2 0 0 @@ -461,7 +509,19 @@ 5 - 21 + 25 + 2 + 0 + 0 + 0 + ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\TOOLCHAIN_ARM\cy_syslib_mdk.S + cy_syslib_mdk.S + 0 + 0 + + + 5 + 26 1 0 0 @@ -473,7 +533,7 @@ 5 - 22 + 27 1 0 0 @@ -485,7 +545,7 @@ 5 - 23 + 28 1 0 0 @@ -497,7 +557,7 @@ 5 - 24 + 29 1 0 0 @@ -509,62 +569,6 @@ - - Filesystem - 0 - 0 - 0 - 0 - - 6 - 25 - 1 - 0 - 0 - 0 - ..\..\..\components\dfs\src\dfs_posix.c - dfs_posix.c - 0 - 0 - - - 6 - 26 - 1 - 0 - 0 - 0 - ..\..\..\components\dfs\src\dfs_fs.c - dfs_fs.c - 0 - 0 - - - 6 - 27 - 1 - 0 - 0 - 0 - ..\..\..\components\dfs\src\dfs.c - dfs.c - 0 - 0 - - - 6 - 28 - 1 - 0 - 0 - 0 - ..\..\..\components\dfs\src\dfs_file.c - dfs_file.c - 0 - 0 - - - Finsh 0 @@ -572,8 +576,8 @@ 0 0 - 7 - 29 + 6 + 30 1 0 0 @@ -584,8 +588,8 @@ 0 - 7 - 30 + 6 + 31 1 0 0 @@ -596,20 +600,20 @@ 0 - 7 - 31 + 6 + 32 1 0 0 0 - ..\..\..\components\finsh\msh_file.c - msh_file.c + ..\..\..\components\finsh\msh_parse.c + msh_parse.c 0 0 - 7 - 32 + 6 + 33 1 0 0 @@ -628,8 +632,8 @@ 0 0 - 8 - 33 + 7 + 34 1 0 0 @@ -640,8 +644,8 @@ 0 - 8 - 34 + 7 + 35 1 0 0 @@ -652,8 +656,8 @@ 0 - 8 - 35 + 7 + 36 1 0 0 @@ -664,8 +668,8 @@ 0 - 8 - 36 + 7 + 37 1 0 0 @@ -676,8 +680,8 @@ 0 - 8 - 37 + 7 + 38 1 0 0 @@ -688,8 +692,8 @@ 0 - 8 - 38 + 7 + 39 1 0 0 @@ -700,8 +704,8 @@ 0 - 8 - 39 + 7 + 40 1 0 0 @@ -712,8 +716,8 @@ 0 - 8 - 40 + 7 + 41 1 0 0 @@ -724,8 +728,8 @@ 0 - 8 - 41 + 7 + 42 1 0 0 @@ -736,8 +740,8 @@ 0 - 8 - 42 + 7 + 43 1 0 0 @@ -748,8 +752,8 @@ 0 - 8 - 43 + 7 + 44 1 0 0 @@ -760,8 +764,8 @@ 0 - 8 - 44 + 7 + 45 1 0 0 @@ -772,8 +776,8 @@ 0 - 8 - 45 + 7 + 46 1 0 0 @@ -792,19 +796,7 @@ 0 0 - 9 - 46 - 1 - 0 - 0 - 0 - ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_02_cm0p_sleep.c - psoc6_02_cm0p_sleep.c - 0 - 0 - - - 9 + 8 47 1 0 @@ -816,7 +808,7 @@ 0 - 9 + 8 48 1 0 @@ -828,7 +820,7 @@ 0 - 9 + 8 49 1 0 @@ -840,32 +832,20 @@ 0 - 9 + 8 50 1 0 0 0 - ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_03_cm0p_sleep.c - psoc6_03_cm0p_sleep.c - 0 - 0 - - - 9 - 51 - 1 - 0 - 0 - 0 ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\cy_scb_i2c.c cy_scb_i2c.c 0 0 - 9 - 52 + 8 + 51 1 0 0 @@ -876,8 +856,8 @@ 0 - 9 - 53 + 8 + 52 1 0 0 @@ -888,8 +868,8 @@ 0 - 9 - 54 + 8 + 53 1 0 0 @@ -900,8 +880,8 @@ 0 - 9 - 55 + 8 + 54 1 0 0 @@ -912,8 +892,8 @@ 0 - 9 - 56 + 8 + 55 1 0 0 @@ -924,8 +904,8 @@ 0 - 9 - 57 + 8 + 56 1 0 0 @@ -936,8 +916,8 @@ 0 - 9 - 58 + 8 + 57 1 0 0 @@ -948,8 +928,8 @@ 0 - 9 - 59 + 8 + 58 1 0 0 @@ -960,8 +940,8 @@ 0 - 9 - 60 + 8 + 59 1 0 0 @@ -972,8 +952,8 @@ 0 - 9 - 61 + 8 + 60 1 0 0 @@ -984,20 +964,8 @@ 0 - 9 - 62 - 1 - 0 - 0 - 0 - ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_01_cm0p_sleep.c - psoc6_01_cm0p_sleep.c - 0 - 0 - - - 9 - 63 + 8 + 61 1 0 0 @@ -1008,8 +976,8 @@ 0 - 9 - 64 + 8 + 62 1 0 0 @@ -1020,8 +988,8 @@ 0 - 9 - 65 + 8 + 63 1 0 0 @@ -1032,8 +1000,8 @@ 0 - 9 - 66 + 8 + 64 1 0 0 @@ -1044,32 +1012,32 @@ 0 - 9 - 67 + 8 + 65 1 0 0 0 - ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_04_cm0p_sleep.c - psoc6_04_cm0p_sleep.c + ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\cy_ipc_drv.c + cy_ipc_drv.c 0 0 - 9 - 68 + 8 + 66 1 0 0 0 - ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\cy_ipc_drv.c - cy_ipc_drv.c + ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_02_cm0p_sleep.c + psoc6_02_cm0p_sleep.c 0 0 - 9 - 69 + 8 + 67 1 0 0 @@ -1080,8 +1048,8 @@ 0 - 9 - 70 + 8 + 68 1 0 0 @@ -1092,20 +1060,20 @@ 0 - 9 - 71 - 2 + 8 + 69 + 1 0 0 0 - ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\TOOLCHAIN_ARM\cy_syslib_mdk.s - cy_syslib_mdk.s + ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource\cycfg_system.c + cycfg_system.c 0 0 - 9 - 72 + 8 + 70 1 0 0 @@ -1116,8 +1084,8 @@ 0 - 9 - 73 + 8 + 71 1 0 0 @@ -1128,8 +1096,8 @@ 0 - 9 - 74 + 8 + 72 1 0 0 @@ -1140,8 +1108,8 @@ 0 - 9 - 75 + 8 + 73 1 0 0 @@ -1152,8 +1120,8 @@ 0 - 9 - 76 + 8 + 74 1 0 0 @@ -1164,8 +1132,8 @@ 0 - 9 - 77 + 8 + 75 1 0 0 @@ -1176,8 +1144,20 @@ 0 - 9 - 78 + 8 + 76 + 1 + 0 + 0 + 0 + ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_04_cm0p_sleep.c + psoc6_04_cm0p_sleep.c + 0 + 0 + + + 8 + 77 1 0 0 @@ -1188,8 +1168,8 @@ 0 - 9 - 79 + 8 + 78 1 0 0 @@ -1200,8 +1180,8 @@ 0 - 9 - 80 + 8 + 79 1 0 0 @@ -1212,8 +1192,8 @@ 0 - 9 - 81 + 8 + 80 1 0 0 @@ -1224,7 +1204,19 @@ 0 - 9 + 8 + 81 + 1 + 0 + 0 + 0 + ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_01_cm0p_sleep.c + psoc6_01_cm0p_sleep.c + 0 + 0 + + + 8 82 1 0 @@ -1236,7 +1228,7 @@ 0 - 9 + 8 83 1 0 @@ -1248,7 +1240,7 @@ 0 - 9 + 8 84 1 0 @@ -1260,7 +1252,7 @@ 0 - 9 + 8 85 1 0 @@ -1272,7 +1264,7 @@ 0 - 9 + 8 86 1 0 @@ -1284,7 +1276,7 @@ 0 - 9 + 8 87 4 0 @@ -1296,31 +1288,31 @@ 0 - 9 + 8 88 1 0 0 0 - ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource\cycfg_system.c - cycfg_system.c + ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource\cycfg_clocks.c + cycfg_clocks.c 0 0 - 9 + 8 89 1 0 0 0 - ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource\cycfg_clocks.c - cycfg_clocks.c + ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_03_cm0p_sleep.c + psoc6_03_cm0p_sleep.c 0 0 - 9 + 8 90 1 0 diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/project.uvprojx b/bsp/cypress/psoc6-cy8cproto-4343w/project.uvprojx index ca6485997b01ad213884ed41fd5022436421fcad..6c3b232b29137051dcd3e207abb8b7895b0a4c2b 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/project.uvprojx +++ b/bsp/cypress/psoc6-cy8cproto-4343w/project.uvprojx @@ -11,7 +11,6 @@ 0x4 ARM-ADS 6160000::V6.16::ARMCLANG - 6160000::V6.16::ARMCLANG 1 @@ -338,9 +337,9 @@ 0 - COMPONENT_CAT1A, RT_USING_LIBC, CY_USING_HAL, __CLK_TCK=RT_TICK_PER_SECOND, COMPONENT_BSP_DESIGN_MODUS, IFX_PSOC6_43012, __RTTHREAD__, COMPONENT_CAT1, RT_USING_ARM_LIBC + CY_USING_HAL, __STDC_LIMIT_MACROS, COMPONENT_CAT1A, RT_USING_LIBC, __CLK_TCK=RT_TICK_PER_SECOND, RT_USING_ARM_LIBC, IFX_PSOC6_43012, __RTTHREAD__, COMPONENT_CAT1, COMPONENT_BSP_DESIGN_MODUS, CY8C624ABZI_S2D44 - applications;..\..\..\components\libc\compilers\common;..\..\..\components\libc\compilers\common\extension;..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;board;..\libraries\HAL_Drivers;..\libraries\HAL_Drivers\config;..\..\..\components\dfs\include;..\..\..\components\finsh;.;..\..\..\include;..\libraries\IFX_PSOC6_HAL\capsense;..\libraries\IFX_PSOC6_HAL\psoc6cm0p;..\libraries\IFX_PSOC6_HAL\retarget-io;..\libraries\IFX_PSOC6_HAL\core-lib\include;..\libraries\IFX_PSOC6_HAL\mtb-hal-cat1\include;..\libraries\IFX_PSOC6_HAL\mtb-hal-cat1\include_pvt;..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\cmsis\include;..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\include;..\libraries\IFX_PSOC6_HAL\mtb-hal-cat1\COMPONENT_CAT1A\include;..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\devices\COMPONENT_CAT1A\include;..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\devices\COMPONENT_CAT1B\include;..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012;..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource;..\..\..\components\libc\posix\io\poll;..\..\..\components\libc\posix\io\stdio;..\..\..\components\libc\posix\ipc + applications;..\..\..\components\libc\compilers\common\include;..\..\..\components\libc\compilers\common\extension;..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;board;board\ports;..\libraries\HAL_Drivers;..\libraries\HAL_Drivers\config;..\..\..\components\finsh;.;..\..\..\include;..\libraries\IFX_PSOC6_HAL\capsense;..\libraries\IFX_PSOC6_HAL\psoc6cm0p;..\libraries\IFX_PSOC6_HAL\retarget-io;..\libraries\IFX_PSOC6_HAL\core-lib\include;..\libraries\IFX_PSOC6_HAL\mtb_shared\serial-flash;..\libraries\IFX_PSOC6_HAL\mtb_shared\usbdev;..\libraries\IFX_PSOC6_HAL\mtb_shared\csdidac;..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\cmsis\include;..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\include;..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\devices\COMPONENT_CAT1A\include;..\libraries\IFX_PSOC6_HAL\mtb-hal-cat1\include_pvt;..\libraries\IFX_PSOC6_HAL\mtb-hal-cat1\include;..\libraries\IFX_PSOC6_HAL\mtb-hal-cat1\COMPONENT_CAT1A\include;..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012;..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource;..\..\..\components\libc\posix\io\poll;..\..\..\components\libc\posix\io\stdio;..\..\..\components\libc\posix\ipc @@ -405,14 +404,34 @@ ..\..\..\components\libc\compilers\armlibc\syscalls.c - stdlib.c + cctype.c 1 - ..\..\..\components\libc\compilers\common\stdlib.c + ..\..\..\components\libc\compilers\common\cctype.c - time.c + cstdio.c 1 - ..\..\..\components\libc\compilers\common\time.c + ..\..\..\components\libc\compilers\common\cstdio.c + + + cstdlib.c + 1 + ..\..\..\components\libc\compilers\common\cstdlib.c + + + cstring.c + 1 + ..\..\..\components\libc\compilers\common\cstring.c + + + ctime.c + 1 + ..\..\..\components\libc\compilers\common\ctime.c + + + cwchar.c + 1 + ..\..\..\components\libc\compilers\common\cwchar.c @@ -504,6 +523,11 @@ 2 ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_CM4\TOOLCHAIN_ARM\startup_psoc6_02_cm4.S + + cy_syslib_mdk.S + 2 + ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\TOOLCHAIN_ARM\cy_syslib_mdk.S + board.c 1 @@ -526,31 +550,6 @@ - - Filesystem - - - dfs_posix.c - 1 - ..\..\..\components\dfs\src\dfs_posix.c - - - dfs_fs.c - 1 - ..\..\..\components\dfs\src\dfs_fs.c - - - dfs.c - 1 - ..\..\..\components\dfs\src\dfs.c - - - dfs_file.c - 1 - ..\..\..\components\dfs\src\dfs_file.c - - - Finsh @@ -565,9 +564,9 @@ ..\..\..\components\finsh\msh.c - msh_file.c + msh_parse.c 1 - ..\..\..\components\finsh\msh_file.c + ..\..\..\components\finsh\msh_parse.c cmd.c @@ -649,11 +648,6 @@ Libraries - - psoc6_02_cm0p_sleep.c - 1 - ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_02_cm0p_sleep.c - cy_sysint.c 1 @@ -669,11 +663,6 @@ 1 ..\libraries\IFX_PSOC6_HAL\retarget-io\cy_retarget_io.c - - psoc6_03_cm0p_sleep.c - 1 - ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_03_cm0p_sleep.c - cy_scb_i2c.c 1 @@ -729,11 +718,6 @@ 1 ..\libraries\IFX_PSOC6_HAL\mtb-hal-cat1\source\cyhal_gpio.c - - psoc6_01_cm0p_sleep.c - 1 - ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_01_cm0p_sleep.c - cyhal_system.c 1 @@ -755,14 +739,14 @@ ..\libraries\IFX_PSOC6_HAL\mtb-hal-cat1\source\cyhal_utils.c - psoc6_04_cm0p_sleep.c + cy_ipc_drv.c 1 - ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_04_cm0p_sleep.c + ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\cy_ipc_drv.c - cy_ipc_drv.c + psoc6_02_cm0p_sleep.c 1 - ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\cy_ipc_drv.c + ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_02_cm0p_sleep.c cyhal_hwmgr.c @@ -775,9 +759,9 @@ ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\cy_syslib.c - cy_syslib_mdk.s - 2 - ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\TOOLCHAIN_ARM\cy_syslib_mdk.s + cycfg_system.c + 1 + ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource\cycfg_system.c cycfg_peripherals.c @@ -809,6 +793,11 @@ 1 ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\cy_sysclk.c + + psoc6_04_cm0p_sleep.c + 1 + ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_04_cm0p_sleep.c + cyhal_syspm.c 1 @@ -829,6 +818,11 @@ 1 ..\libraries\IFX_PSOC6_HAL\mtb-pdl-cat1\drivers\source\cy_systick.c + + psoc6_01_cm0p_sleep.c + 1 + ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_01_cm0p_sleep.c + cycfg.c 1 @@ -860,14 +854,14 @@ ..\libraries\IFX_PSOC6_HAL\lib\cy_capsense.lib - cycfg_system.c + cycfg_clocks.c 1 - ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource\cycfg_system.c + ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource\cycfg_clocks.c - cycfg_clocks.c + psoc6_03_cm0p_sleep.c 1 - ..\libraries\IFX_PSOC6_HAL\TARGET_CY8CKIT-062S2-43012\COMPONENT_BSP_DESIGN_MODUS\GeneratedSource\cycfg_clocks.c + ..\libraries\IFX_PSOC6_HAL\psoc6cm0p\COMPONENT_CM0P_SLEEP\psoc6_03_cm0p_sleep.c cy_ipc_pipe.c diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/rtconfig.h b/bsp/cypress/psoc6-cy8cproto-4343w/rtconfig.h index aa0983442216f9e80d458d73d00a857e883c5d13..f61cc01e85031fcab1f9c6fb6b88846c07e909ed 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/rtconfig.h +++ b/bsp/cypress/psoc6-cy8cproto-4343w/rtconfig.h @@ -46,7 +46,7 @@ #define RT_USING_DEVICE #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 -#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_CONSOLE_DEVICE_NAME "uart5" #define RT_VER_NUM 0x40101 #define ARCH_ARM #define RT_USING_CPU_FFS @@ -72,12 +72,6 @@ #define MSH_USING_BUILT_IN_COMMANDS #define FINSH_USING_DESCRIPTION #define FINSH_ARG_MAX 10 -#define RT_USING_DFS -#define DFS_USING_POSIX -#define DFS_USING_WORKDIR -#define DFS_FILESYSTEMS_MAX 4 -#define DFS_FILESYSTEM_TYPES_MAX 4 -#define DFS_FD_MAX 16 /* Device Drivers */ @@ -198,7 +192,7 @@ #define BSP_USING_GPIO #define BSP_USING_UART -#define BSP_USING_UART1 +#define BSP_USING_UART5 /* Board extended module Drivers */ diff --git a/bsp/cypress/psoc6-cy8cproto-4343w/rtconfig.py b/bsp/cypress/psoc6-cy8cproto-4343w/rtconfig.py index 37ee59f9b76dfd3f9834aa4dd48d866b514610a3..f751080417bd0ce65d044d0b76dbe1d5fee2f9e4 100644 --- a/bsp/cypress/psoc6-cy8cproto-4343w/rtconfig.py +++ b/bsp/cypress/psoc6-cy8cproto-4343w/rtconfig.py @@ -46,7 +46,7 @@ if PLATFORM == 'gcc': DEVICE = ' -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections' CFLAGS = DEVICE + ' -Dgcc' AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.ld' CPATH = '' LPATH = '' diff --git a/bsp/cypress/tools/sdk_dist.py b/bsp/cypress/tools/sdk_dist.py new file mode 100644 index 0000000000000000000000000000000000000000..5c14af7adb2bdb393469fade585c16cee8a66e8d --- /dev/null +++ b/bsp/cypress/tools/sdk_dist.py @@ -0,0 +1,22 @@ +import os +import sys +import shutil + +cwd_path = os.getcwd() +sys.path.append(os.path.join(os.path.dirname(cwd_path), 'rt-thread', 'tools')) + + +# BSP dist function +def dist_do_building(BSP_ROOT, dist_dir): + from mkdist import bsp_copy_files + import rtconfig + + print("=> copy ifx bsp library") + library_dir = os.path.join(dist_dir, 'libraries') + library_path = os.path.join(os.path.dirname(BSP_ROOT), 'libraries') + bsp_copy_files(os.path.join(library_path, rtconfig.BSP_LIBRARY_TYPE), + os.path.join(library_dir, rtconfig.BSP_LIBRARY_TYPE)) + + print("=> copy bsp drivers") + bsp_copy_files(os.path.join(library_path, 'HAL_Drivers'), os.path.join(library_dir, 'HAL_Drivers')) + shutil.copyfile(os.path.join(library_path, 'Kconfig'), os.path.join(library_dir, 'Kconfig')) diff --git a/bsp/cypress/tools/upgrade.py b/bsp/cypress/tools/upgrade.py new file mode 100644 index 0000000000000000000000000000000000000000..c7e35466d22a8accc092bdfde317210ccce8a1c7 --- /dev/null +++ b/bsp/cypress/tools/upgrade.py @@ -0,0 +1,143 @@ +# +# File : upgrade.py +# This file is part of RT-Thread RTOS +# COPYRIGHT (C) 2006 - 2021, RT-Thread Development Team +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Change Logs: +# Date Author Notes +# 2021-10-11 Meco Man First version +# + +# 本文件用于在HAL库更新之后 +# 1.对gcc的汇编启动文件中main替换为entry函数 +# 2.将启动文件heap降为0(Keil IAR) +# 3.将GCC的堆大小扩展到0x400,与Keil IAR保持一致 + + +#使用方法:运行脚本,将bsp/stm32的绝对路径传给脚本即可,如:C:\Users\92036\Desktop\rt-thread\bsp\stm32 + +import os +import re + +#将'bl main' 替换为 'bl entry' +def main2entry(path): + oldline = '' + newline = '' + + for root, dirs, files in os.walk(path): #递归扫描里面的所有文件 + for file in files: + if os.path.splitext(file)[1] == '.s': #找.s文件 + file_path = os.path.join(root,file) + flag_need_replace = False + with open(file_path,'r+',) as f: + while True: + line = f.readline() + if line == '': + break + elif ('bl' in line) and ('main' in line): #发现'bl main' + oldline = line # bl main + newline = line.replace('main', 'entry') #将main替换为entry,形成新的字符串 + flag_need_replace = True #标记该文件需要做entry替换 + break + + if (flag_need_replace == True): #若该文件需要将main替换为entry + f.seek(0) + content = f.read() + f.seek(0) + f.truncate() + newcontent = content.replace(oldline, newline) + f.write(newcontent) + +#将启动文件的heap降为0 +def heap2zero(path): + oldline = '' + newline = '' + for root, dirs, files in os.walk(path): #递归扫描里面的所有文件 + for file in files: + file_path = os.path.join(root,file) + if os.path.splitext(file)[1] == '.s': #找.s文件 + with open(file_path,'r+',) as f: + flag_need_replace = False + while True: + line = f.readline() + if line == '': + break + + re_result = re.match('\s*Heap_Size\s+EQU\s+0[xX][0-9a-fA-F]+', line) #MDK的表示方法 + if re_result != None: + oldline = line + newline = re.sub('0[xX][0-9a-fA-F]+','0x00000000', oldline) + flag_need_replace = True + break + + if flag_need_replace == True: + f.seek(0) + content = f.read() + f.seek(0) + f.truncate() + newcontent = content.replace(oldline, newline) + f.write(newcontent) + + elif os.path.splitext(file)[1] == '.icf': #找.icf文件(IAR) + with open(file_path,'r+',) as f: + flag_need_replace = False + while True: + line = f.readline() + if line == '': + break + + re_result = re.match('\s*define\s+symbol\s+__ICFEDIT_size_heap__\s*=\s*0[xX][0-9a-fA-F]+', line) #IAR的表示方法 + if re_result != None: + oldline = line + newline = re.sub('0[xX][0-9a-fA-F]+','0x000', oldline) + flag_need_replace = True + break + + if flag_need_replace == True: + f.seek(0) + content = f.read() + f.seek(0) + f.truncate() + newcontent = content.replace(oldline, newline) + f.write(newcontent) + + elif os.path.splitext(file)[1] == '.lds': #找.lds文件(GCC) + with open(file_path,'r+',) as f: + flag_need_replace = False + while True: + line = f.readline() + if line == '': + break + + re_result = re.match('\s*_system_stack_size\s*=\s*0[xX][0-9a-fA-F]+', line) #GCC的表示方法, 将默认的栈大小增加到0x400 + if re_result != None: + oldline = line + newline = re.sub('0[xX][0-9a-fA-F]+','0x400', oldline) + flag_need_replace = True + break + + if flag_need_replace == True: + f.seek(0) + content = f.read() + f.seek(0) + f.truncate() + newcontent = content.replace(oldline, newline) + f.write(newcontent) + +folder_path = input('please input path:') +main2entry(folder_path) +heap2zero(folder_path)