From c63a9b7ff88f664397be50b8305125c57cb622ec Mon Sep 17 00:00:00 2001 From: Ahmet Alincak Date: Fri, 18 Dec 2020 18:59:54 +0300 Subject: [PATCH 1/3] Maxim targets; Add USB stack implementation --- targets/TARGET_Maxim/CMakeLists.txt | 5 + targets/TARGET_Maxim/USBEndpoints_Maxim.h | 108 +++++ targets/TARGET_Maxim/USBPhyHw.h | 67 +++ targets/TARGET_Maxim/USBPhy_Maxim.cpp | 526 ++++++++++++++++++++++ targets/targets.json | 1 + 5 files changed, 707 insertions(+) create mode 100644 targets/TARGET_Maxim/USBEndpoints_Maxim.h create mode 100644 targets/TARGET_Maxim/USBPhyHw.h create mode 100644 targets/TARGET_Maxim/USBPhy_Maxim.cpp diff --git a/targets/TARGET_Maxim/CMakeLists.txt b/targets/TARGET_Maxim/CMakeLists.txt index ef47ec85d8..62a98905d1 100644 --- a/targets/TARGET_Maxim/CMakeLists.txt +++ b/targets/TARGET_Maxim/CMakeLists.txt @@ -13,3 +13,8 @@ target_include_directories(mbed-core INTERFACE . ) + +target_sources(mbed-core + INTERFACE + USBPhy_Maxim.cpp +) diff --git a/targets/TARGET_Maxim/USBEndpoints_Maxim.h b/targets/TARGET_Maxim/USBEndpoints_Maxim.h new file mode 100644 index 0000000000..ad8cf83e19 --- /dev/null +++ b/targets/TARGET_Maxim/USBEndpoints_Maxim.h @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#ifndef USBENDPOINTS_H +#define USBENDPOINTS_H + +/* SETUP packet size */ +#define SETUP_PACKET_SIZE (8) + +/* Options flags for configuring endpoints */ +#define DEFAULT_OPTIONS (0) +#define SINGLE_BUFFERED (1U << 0) +#define ISOCHRONOUS (1U << 1) +#define RATE_FEEDBACK_MODE (1U << 2) /* Interrupt endpoints only */ + +#define NUMBER_OF_LOGICAL_ENDPOINTS (8) +#define NUMBER_OF_PHYSICAL_ENDPOINTS (NUMBER_OF_LOGICAL_ENDPOINTS * 2) + +#define EP_TO_INDEX(endpoint) (((endpoint & 0xf) << 1) | (endpoint & 0x80 ? 1 : 0)) + +#define DIR_OUT 0x00 +#define DIR_IN 0x80 +#define EP_NUM(ep) (ep & 0x0F) +#define IN_EP(ep) (ep & DIR_IN) +#define OUT_EP(ep) (!(ep & DIR_IN)) + +/* Define physical endpoint numbers */ + +/* Endpoint No. */ +/* ---------------- */ +#define EP0OUT ((0 << 1) | DIR_OUT) +#define EP0IN ((0 << 1) | DIR_IN) +#define EP1OUT ((1 << 1) | DIR_OUT) +#define EP1IN ((1 << 1) | DIR_IN) +#define EP2OUT ((2 << 1) | DIR_OUT) +#define EP2IN ((2 << 1) | DIR_IN) +#define EP3OUT ((3 << 1) | DIR_OUT) +#define EP3IN ((3 << 1) | DIR_IN) +#define EP4OUT ((4 << 1) | DIR_OUT) +#define EP4IN ((4 << 1) | DIR_IN) +#define EP5OUT ((5 << 1) | DIR_OUT) +#define EP5IN ((5 << 1) | DIR_IN) +#define EP6OUT ((6 << 1) | DIR_OUT) +#define EP6IN ((6 << 1) | DIR_IN) +#define EP7OUT ((7 << 1) | DIR_OUT) +#define EP7IN ((7 << 1) | DIR_IN) + +/* Maximum Packet sizes */ + +#define MAX_PACKET_SIZE_EP0 (64) +#define MAX_PACKET_SIZE_EP1 (64) +#define MAX_PACKET_SIZE_EP2 (64) +#define MAX_PACKET_SIZE_EP3 (64) +#define MAX_PACKET_SIZE_EP4 (64) +#define MAX_PACKET_SIZE_EP5 (64) +#define MAX_PACKET_SIZE_EP6 (64) +#define MAX_PACKET_SIZE_EP7 (64) + +/* Generic endpoints - intended to be portable accross devices */ +/* and be suitable for simple USB devices. */ + +/* Bulk endpoints */ +#define EPBULK_OUT (EP1OUT) +#define EPBULK_IN (EP2IN) + +/* Interrupt endpoints */ +#define EPINT_OUT (EP3OUT) +#define EPINT_IN (EP4IN) + +/* Isochronous endpoints */ +/* NOT SUPPORTED - use invalid endpoint number to prevent built errors */ +#define EPISO_OUT (EP0OUT) +#define EPISO_IN (EP0IN) + +#define MAX_PACKET_SIZE_EPBULK (64) +#define MAX_PACKET_SIZE_EPINT (64) + +#endif diff --git a/targets/TARGET_Maxim/USBPhyHw.h b/targets/TARGET_Maxim/USBPhyHw.h new file mode 100644 index 0000000000..1476fa797f --- /dev/null +++ b/targets/TARGET_Maxim/USBPhyHw.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018-2019, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef USBPHYHW_H +#define USBPHYHW_H + +#include "mbed.h" +#include "USBPhy.h" + + +class USBPhyHw : public USBPhy { +public: + USBPhyHw(); + virtual ~USBPhyHw(); + virtual void init(USBPhyEvents *events); + virtual void deinit(); + virtual bool powered(); + virtual void connect(); + virtual void disconnect(); + virtual void configure(); + virtual void unconfigure(); + virtual void sof_enable(); + virtual void sof_disable(); + virtual void set_address(uint8_t address); + virtual void remote_wakeup(); + virtual const usb_ep_table_t *endpoint_table(); + + virtual uint32_t ep0_set_max_packet(uint32_t max_packet); + virtual void ep0_setup_read_result(uint8_t *buffer, uint32_t size); + virtual void ep0_read(uint8_t *data, uint32_t size); + virtual uint32_t ep0_read_result(); + virtual void ep0_write(uint8_t *buffer, uint32_t size); + virtual void ep0_stall(); + + virtual bool endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type); + virtual void endpoint_remove(usb_ep_t endpoint); + virtual void endpoint_stall(usb_ep_t endpoint); + virtual void endpoint_unstall(usb_ep_t endpoint); + + virtual bool endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size); + virtual uint32_t endpoint_read_result(usb_ep_t endpoint); + virtual bool endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size); + virtual void endpoint_abort(usb_ep_t endpoint); + + virtual void process(); + +private: + USBPhyEvents *events; + + static void _usbisr(void); +}; + +#endif diff --git a/targets/TARGET_Maxim/USBPhy_Maxim.cpp b/targets/TARGET_Maxim/USBPhy_Maxim.cpp new file mode 100644 index 0000000000..be1f8da95b --- /dev/null +++ b/targets/TARGET_Maxim/USBPhy_Maxim.cpp @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2018-2019, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(DEVICE_USBDEVICE) && (DEVICE_USBDEVICE) && \ + (defined(TARGET_MAX32620) || defined(TARGET_MAX32625) || defined(TARGET_MAX32630)) + +#include "USBPhyHw.h" +#include "usb_phy_api.h" +#include "USBEndpoints_Maxim.h" + +#include "usb_regs.h" +#include "clkman_regs.h" + +#if defined(TARGET_MAX32625) || defined(TARGET_MAX32630) +#include "pwrman_regs.h" +#endif + +#define CONNECT_INTS (MXC_F_USB_DEV_INTEN_BRST | MXC_F_USB_DEV_INTEN_SETUP | MXC_F_USB_DEV_INTEN_EP_IN | MXC_F_USB_DEV_INTEN_EP_OUT | MXC_F_USB_DEV_INTEN_DMA_ERR) + +typedef struct { + volatile uint32_t buf0_desc; + volatile uint32_t buf0_address; + volatile uint32_t buf1_desc; + volatile uint32_t buf1_address; +} ep_buffer_t; + +typedef struct { + ep_buffer_t out_buffer; + ep_buffer_t in_buffer; +} ep0_buffer_t; + +typedef struct { + ep0_buffer_t ep0; + ep_buffer_t ep[MXC_USB_NUM_EP - 1]; +} ep_buffer_descriptor_t; + +// control packet state +static enum { + CTRL_NONE = 0, + CTRL_SETUP, + CTRL_OUT, + CTRL_IN, +} control_state; + +// Static storage for endpoint buffer descriptor table. Must be 512 byte aligned for DMA. +#ifdef __IAR_SYSTEMS_ICC__ +#pragma data_alignment = 512 +#else +__attribute__ ((aligned (512))) +#endif +ep_buffer_descriptor_t ep_buffer_descriptor; + +// static storage for temporary data buffers. Must be 32 byte aligned. +#ifdef __IAR_SYSTEMS_ICC__ +#pragma data_alignment = 4 +#else +__attribute__ ((aligned (4))) +#endif +static uint8_t aligned_buffer[NUMBER_OF_LOGICAL_ENDPOINTS][MXC_USB_MAX_PACKET]; + +static uint8_t* read_buf_addr[NUMBER_OF_LOGICAL_ENDPOINTS]; + +static USBPhyHw *instance; + +static ep_buffer_t *get_desc(uint8_t endpoint) +{ + uint8_t epnum = EP_NUM(endpoint); + ep_buffer_t *desc; + + if (epnum == 0) { + if (IN_EP(endpoint)) { + desc = &ep_buffer_descriptor.ep0.in_buffer; + } else { + desc = &ep_buffer_descriptor.ep0.out_buffer; + } + } else { + desc = &ep_buffer_descriptor.ep[epnum - 1]; + } + + return desc; +} + +USBPhy *get_usb_phy() +{ + static USBPhyHw usbphy; + return &usbphy; +} + +USBPhyHw::USBPhyHw(): events(NULL) +{ + +} + +USBPhyHw::~USBPhyHw() +{ + +} + +void USBPhyHw::init(USBPhyEvents *events) +{ + this->events = events; + + // Disable IRQ + NVIC_DisableIRQ(USB_IRQn); + + // Enable the USB clock +#if defined(TARGET_MAX32620) + MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE; +#elif defined(TARGET_MAX32625) || defined(TARGET_MAX32630) + MXC_PWRMAN->pwr_rst_ctrl |= MXC_F_PWRMAN_PWR_RST_CTRL_USB_POWERED; + MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE; +#endif + + // reset the device + MXC_USB->cn = 0; + MXC_USB->cn = MXC_F_USB_CN_USB_EN; + MXC_USB->dev_inten = 0; + MXC_USB->dev_cn = 0; + MXC_USB->dev_cn = MXC_F_USB_DEV_CN_URST; + MXC_USB->dev_cn = 0; + + // clear driver state + control_state = CTRL_NONE; + + // set the descriptor location + MXC_USB->ep_base = (uint32_t)&ep_buffer_descriptor; + + // enable VBUS interrupts + MXC_USB->dev_inten = MXC_F_USB_DEV_INTEN_NO_VBUS | MXC_F_USB_DEV_INTEN_VBUS; + + // Attach IRQ handler and Enable IRQ + instance = this; + NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr); + NVIC_EnableIRQ(USB_IRQn); +} + +void USBPhyHw::deinit() +{ + // Disconnect and disable interrupt + MXC_USB->dev_cn = MXC_F_USB_DEV_CN_URST; + MXC_USB->dev_cn = 0; + MXC_USB->cn = 0; + disconnect(); + NVIC_DisableIRQ(USB_IRQn); +} + +bool USBPhyHw::powered() +{ + return true; +} + +void USBPhyHw::connect() +{ + // enable interrupts + MXC_USB->dev_inten |= CONNECT_INTS; + + // allow interrupts on ep0 + MXC_USB->ep[0] |= MXC_F_USB_EP_INT_EN; + + // pullup enable + MXC_USB->dev_cn |= (MXC_F_USB_DEV_CN_CONNECT | MXC_F_USB_DEV_CN_FIFO_MODE); +} + +void USBPhyHw::disconnect() +{ + // disable interrupts + MXC_USB->dev_inten &= ~CONNECT_INTS; + + // disable pullup + MXC_USB->dev_cn &= ~MXC_F_USB_DEV_CN_CONNECT; +} + +void USBPhyHw::configure() +{ + // Do nothing +} + +void USBPhyHw::unconfigure() +{ + // reset endpoints + for (int i = 0; i < MXC_USB_NUM_EP; i++) { + // Disable endpoint and clear the data toggle + MXC_USB->ep[i] &= ~MXC_F_USB_EP_DIR; + MXC_USB->ep[i] |= MXC_F_USB_EP_DT; + } +} + +void USBPhyHw::sof_enable() +{ + // Do nothing +} + +void USBPhyHw::sof_disable() +{ + // Do nothing +} + +void USBPhyHw::set_address(uint8_t address) +{ + // Do nothing +} + +void USBPhyHw::remote_wakeup() +{ + // Do nothing +} + +const usb_ep_table_t *USBPhyHw::endpoint_table() +{ + static const usb_ep_table_t endpoint_table = { + 4096 - 32 * 4, // 32 words for endpoint buffers + // +3 based added to interrupt and isochronous to ensure enough + // space for 4 byte alignment + { + {USB_EP_ATTR_ALLOW_CTRL | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0}, + {USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_DIR_OUT, 0, 0}, + {USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_DIR_IN, 0, 0}, + {USB_EP_ATTR_ALLOW_INT | USB_EP_ATTR_DIR_OUT, 0, 0}, + {USB_EP_ATTR_ALLOW_INT | USB_EP_ATTR_DIR_IN, 0, 0}, + {USB_EP_ATTR_ALLOW_INT | USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0}, + {USB_EP_ATTR_ALLOW_INT | USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0}, + {USB_EP_ATTR_ALLOW_INT | USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0}, + } + }; + return &endpoint_table; +} + +uint32_t USBPhyHw::ep0_set_max_packet(uint32_t max_packet) +{ + return MAX_PACKET_SIZE_EP0; +} + +void USBPhyHw::ep0_setup_read_result(uint8_t *buffer, uint32_t size) +{ + uint32_t *ptr32 = (uint32_t*)buffer; + + // read setup packet + ptr32[0] = (uint32_t)MXC_USB->setup0; + ptr32[1] = (uint32_t)MXC_USB->setup1; +} + +void USBPhyHw::ep0_read(uint8_t *data, uint32_t size) +{ + // Setup data buffer to receive next endpoint 0 OUT packet + if (control_state == CTRL_IN) { + // This is the status stage. ACK. + MXC_USB->ep[0] |= MXC_F_USB_EP_ST_ACK; + control_state = CTRL_NONE; + return; + } + + control_state = CTRL_OUT; + + endpoint_read(EP0OUT, data, size); +} + +uint32_t USBPhyHw::ep0_read_result() +{ + // Return the size of the last OUT packet received on endpoint 0 + return endpoint_read_result(EP0OUT); +} + +void USBPhyHw::ep0_write(uint8_t *buffer, uint32_t size) +{ + // Start transferring buffer on endpoint 0 IN + if ((size == 0) && (control_state != CTRL_IN)) { + // This is a status stage ACK. Handle in hardware. + MXC_USB->ep[0] |= MXC_F_USB_EP_ST_ACK; + control_state = CTRL_NONE; + return; + } + + control_state = CTRL_IN; + + endpoint_write(EP0IN, buffer, size); +} + +void USBPhyHw::ep0_stall() +{ + endpoint_stall(EP0OUT); +} + +bool USBPhyHw::endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type) +{ + uint8_t epnum = EP_NUM(endpoint); + uint32_t ep_ctrl = 0; + + if (epnum >= NUMBER_OF_PHYSICAL_ENDPOINTS) { + return false; + } + + if (IN_EP(endpoint)) { + ep_ctrl = MXC_S_USB_EP_DIR_IN; + } else { + ep_ctrl = MXC_S_USB_EP_DIR_OUT; + } + + ep_ctrl |= (MXC_F_USB_EP_DT | MXC_F_USB_EP_INT_EN); + + MXC_USB->ep[epnum] = ep_ctrl; + + return true; +} + +void USBPhyHw::endpoint_remove(usb_ep_t endpoint) +{ + uint8_t epnum = EP_NUM(endpoint); + // Disable and remove this endpoint + MXC_USB->ep[epnum] &= ~MXC_F_USB_EP_DIR; + MXC_USB->ep[epnum] |= MXC_F_USB_EP_DT; +} + +void USBPhyHw::endpoint_stall(usb_ep_t endpoint) +{ + // Stall this endpoint until it is explicitly cleared + uint8_t epnum = EP_NUM(endpoint); + + if (epnum == 0) { + MXC_USB->ep[epnum] |= MXC_F_USB_EP_ST_STALL; + } + + MXC_USB->ep[epnum] |= MXC_F_USB_EP_STALL; +} + +void USBPhyHw::endpoint_unstall(usb_ep_t endpoint) +{ + // Unstall this endpoint + MXC_USB->ep[EP_NUM(endpoint)] &= ~MXC_F_USB_EP_STALL; +} + +bool USBPhyHw::endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size) +{ + // Setup data buffer to receive next endpoint OUT packet and return true if successful + uint8_t epnum = EP_NUM(endpoint); + + if ((epnum >= NUMBER_OF_PHYSICAL_ENDPOINTS) || + IN_EP(endpoint) || + (size > MAX_PACKET_SIZE_EP0)) { + return false; + } + + uint32_t mask = (1 << epnum); + if (MXC_USB->out_owner & mask) { + return false; + } + + read_buf_addr[epnum] = data; + + ep_buffer_t *desc = get_desc(endpoint); + desc->buf0_desc = size; + desc->buf0_address = (uint32_t)aligned_buffer[epnum]; + + MXC_USB->out_owner = mask; + + return true; +} + +uint32_t USBPhyHw::endpoint_read_result(usb_ep_t endpoint) +{ + uint32_t size = 0; + uint8_t epnum = EP_NUM(endpoint); + + if ((epnum >= NUMBER_OF_PHYSICAL_ENDPOINTS) || IN_EP(endpoint)) { + return 0; + } + + uint32_t mask = (1 << epnum); + if (MXC_USB->out_owner & mask) { + return 0; + } + + // get the packet length and contents + ep_buffer_t *desc = get_desc(endpoint); + size = desc->buf0_desc; + memcpy(read_buf_addr[epnum], aligned_buffer[epnum], size); + + return size; +} + +bool USBPhyHw::endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size) +{ + // Start transferring buffer on endpoint IN + uint8_t epnum = EP_NUM(endpoint); + + if ((epnum >= NUMBER_OF_PHYSICAL_ENDPOINTS) || + OUT_EP(endpoint) || + (size > MAX_PACKET_SIZE_EP0)) { + return false; + } + + uint32_t mask = (1 << epnum); + if (MXC_USB->in_owner & mask) { + return false; + } + + memcpy(aligned_buffer[epnum], data, size); + + ep_buffer_t *desc = get_desc(endpoint); + desc->buf0_desc = size; + desc->buf0_address = (uint32_t)aligned_buffer[epnum]; + + // start the DMA + MXC_USB->in_owner = mask; + + return true; +} + +void USBPhyHw::endpoint_abort(usb_ep_t endpoint) +{ + // Stop the current transfer on this endpoint and don't call the IN or OUT callback + ep_buffer_t *desc = get_desc(endpoint); + desc->buf0_desc = 0; + desc->buf0_address = 0; +} + +void USBPhyHw::process() +{ + // get and clear irqs + uint32_t irq_flags = MXC_USB->dev_intfl; + MXC_USB->dev_intfl = irq_flags; + + // process only enabled interrupts + irq_flags &= MXC_USB->dev_inten; + + // suspend + if (irq_flags & MXC_F_USB_DEV_INTFL_SUSP) { + events->suspend(true); + } + + // bus reset + if (irq_flags & MXC_F_USB_DEV_INTFL_BRST) { + + // reset endpoints + for (int i = 0; i < NUMBER_OF_LOGICAL_ENDPOINTS; i++) { + // Disable endpoint and clear the data toggle + MXC_USB->ep[i] &= ~MXC_F_USB_EP_DIR; + MXC_USB->ep[i] |= MXC_F_USB_EP_DT; + } + + events->reset(); + + // clear driver state + control_state = CTRL_NONE; + + } + + // power applied + if (irq_flags & MXC_F_USB_DEV_INTFL_VBUS) { + events->power(true); + } + + // power lost + if (irq_flags & MXC_F_USB_DEV_INTFL_NO_VBUS) { + events->power(false); + } + + // Setup packet + if (irq_flags & MXC_F_USB_DEV_INTFL_SETUP) { + events->ep0_setup(); + } + + // IN packets + if (irq_flags & MXC_F_USB_DEV_INTFL_EP_IN) { + // get and clear IN irqs + uint32_t in_irqs = MXC_USB->in_int; + MXC_USB->in_int = in_irqs; + + if (in_irqs & 1) { + events->ep0_in(); + } + + for (uint8_t epnum = 1; epnum < NUMBER_OF_LOGICAL_ENDPOINTS; epnum++) { + uint32_t irq_mask = (1 << epnum); + if (in_irqs & irq_mask) { + uint8_t endpoint = epnum | DIR_IN; + events->in(endpoint); + } + } + } + + // OUT packets + if (irq_flags & MXC_F_USB_DEV_INTFL_EP_OUT) { + // get and clear OUT irqs + uint32_t out_irqs = MXC_USB->out_int; + MXC_USB->out_int = out_irqs; + + if (out_irqs & 1) { + events->ep0_out(); + } + + for (uint8_t epnum = 1; epnum < NUMBER_OF_LOGICAL_ENDPOINTS; epnum++) { + uint32_t irq_mask = (1 << epnum); + if (out_irqs & irq_mask) { + uint8_t endpoint = epnum | DIR_OUT; + events->out(endpoint); + } + } + } + + // Re-enable interrupt + NVIC_ClearPendingIRQ(USB_IRQn); + NVIC_EnableIRQ(USB_IRQn); +} + +void USBPhyHw::_usbisr(void) +{ + NVIC_DisableIRQ(USB_IRQn); + // Handle interrupts + instance->events->start_process(); +} + +#endif diff --git a/targets/targets.json b/targets/targets.json index 42ef9fb304..835ab3284b 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -5095,6 +5095,7 @@ "USTICKER", "MPU", "SLEEP" + "USBDEVICE" ], "release_versions": [ "5" From 1fd7de0eee23b568d8614ca805383d1f2e32fa5f Mon Sep 17 00:00:00 2001 From: Ahmet Alincak Date: Thu, 7 Jan 2021 09:24:38 +0300 Subject: [PATCH 2/3] Update header file to include SPDX identifier --- targets/TARGET_Maxim/USBEndpoints_Maxim.h | 40 +++++++---------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/targets/TARGET_Maxim/USBEndpoints_Maxim.h b/targets/TARGET_Maxim/USBEndpoints_Maxim.h index ad8cf83e19..d011651389 100644 --- a/targets/TARGET_Maxim/USBEndpoints_Maxim.h +++ b/targets/TARGET_Maxim/USBEndpoints_Maxim.h @@ -1,34 +1,18 @@ -/******************************************************************************* - * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved. +/* mbed Microcontroller Library + * Copyright (c) 2018-2020 ARM Limited + * SPDX-License-Identifier: Apache-2.0 * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. + * http://www.apache.org/licenses/LICENSE-2.0 * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of Maxim Integrated - * Products, Inc. shall not be used except as stated in the Maxim Integrated - * Products, Inc. Branding Policy. - * - * The mere transfer of this software does not imply any licenses - * of trade secrets, proprietary technology, copyrights, patents, - * trademarks, maskwork rights, or any other form of intellectual - * property whatsoever. Maxim Integrated Products, Inc. retains all - * ownership rights. - ******************************************************************************* + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ #ifndef USBENDPOINTS_H From 2ca990eb5397b51074fcd4919b3b2ecba8d54fe3 Mon Sep 17 00:00:00 2001 From: Ahmet Alincak Date: Mon, 11 Jan 2021 15:08:14 +0300 Subject: [PATCH 3/3] Use MBED_ALIGN and remove mbed.h from header --- targets/TARGET_Maxim/USBPhyHw.h | 1 - targets/TARGET_Maxim/USBPhy_Maxim.cpp | 13 +++---------- targets/targets.json | 2 +- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/targets/TARGET_Maxim/USBPhyHw.h b/targets/TARGET_Maxim/USBPhyHw.h index 1476fa797f..15a71f412e 100644 --- a/targets/TARGET_Maxim/USBPhyHw.h +++ b/targets/TARGET_Maxim/USBPhyHw.h @@ -18,7 +18,6 @@ #ifndef USBPHYHW_H #define USBPHYHW_H -#include "mbed.h" #include "USBPhy.h" diff --git a/targets/TARGET_Maxim/USBPhy_Maxim.cpp b/targets/TARGET_Maxim/USBPhy_Maxim.cpp index be1f8da95b..e2fbd79c3d 100644 --- a/targets/TARGET_Maxim/USBPhy_Maxim.cpp +++ b/targets/TARGET_Maxim/USBPhy_Maxim.cpp @@ -18,6 +18,7 @@ #if defined(DEVICE_USBDEVICE) && (DEVICE_USBDEVICE) && \ (defined(TARGET_MAX32620) || defined(TARGET_MAX32625) || defined(TARGET_MAX32630)) +#include "mbed.h" #include "USBPhyHw.h" #include "usb_phy_api.h" #include "USBEndpoints_Maxim.h" @@ -57,19 +58,11 @@ static enum { } control_state; // Static storage for endpoint buffer descriptor table. Must be 512 byte aligned for DMA. -#ifdef __IAR_SYSTEMS_ICC__ -#pragma data_alignment = 512 -#else -__attribute__ ((aligned (512))) -#endif +MBED_ALIGN(512) ep_buffer_descriptor_t ep_buffer_descriptor; // static storage for temporary data buffers. Must be 32 byte aligned. -#ifdef __IAR_SYSTEMS_ICC__ -#pragma data_alignment = 4 -#else -__attribute__ ((aligned (4))) -#endif +MBED_ALIGN(4) static uint8_t aligned_buffer[NUMBER_OF_LOGICAL_ENDPOINTS][MXC_USB_MAX_PACKET]; static uint8_t* read_buf_addr[NUMBER_OF_LOGICAL_ENDPOINTS]; diff --git a/targets/targets.json b/targets/targets.json index 835ab3284b..81c4b8d2fe 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -5094,7 +5094,7 @@ "STDIO_MESSAGES", "USTICKER", "MPU", - "SLEEP" + "SLEEP", "USBDEVICE" ], "release_versions": [