ME11B Sample Code in Maxim Integrated Team

Dependencies:   BMI160 max32630hsp3 MemoryLCD USBDevice

Fork of Host_Software_MAX32664GWEB_HR_EXTENDED by Seyhmus Cacina

Committer:
seyhmus.cacina
Date:
Mon Mar 18 10:21:53 2019 +0300
Revision:
0:ac4dea3e2894
ME11B Sample Code First Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
seyhmus.cacina 0:ac4dea3e2894 1 /*******************************************************************************
seyhmus.cacina 0:ac4dea3e2894 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
seyhmus.cacina 0:ac4dea3e2894 3 *
seyhmus.cacina 0:ac4dea3e2894 4 * Permission is hereby granted, free of charge, to any person obtaining a
seyhmus.cacina 0:ac4dea3e2894 5 * copy of this software and associated documentation files (the "Software"),
seyhmus.cacina 0:ac4dea3e2894 6 * to deal in the Software without restriction, including without limitation
seyhmus.cacina 0:ac4dea3e2894 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
seyhmus.cacina 0:ac4dea3e2894 8 * and/or sell copies of the Software, and to permit persons to whom the
seyhmus.cacina 0:ac4dea3e2894 9 * Software is furnished to do so, subject to the following conditions:
seyhmus.cacina 0:ac4dea3e2894 10 *
seyhmus.cacina 0:ac4dea3e2894 11 * The above copyright notice and this permission notice shall be included
seyhmus.cacina 0:ac4dea3e2894 12 * in all copies or substantial portions of the Software.
seyhmus.cacina 0:ac4dea3e2894 13 *
seyhmus.cacina 0:ac4dea3e2894 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
seyhmus.cacina 0:ac4dea3e2894 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
seyhmus.cacina 0:ac4dea3e2894 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
seyhmus.cacina 0:ac4dea3e2894 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
seyhmus.cacina 0:ac4dea3e2894 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
seyhmus.cacina 0:ac4dea3e2894 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
seyhmus.cacina 0:ac4dea3e2894 20 * OTHER DEALINGS IN THE SOFTWARE.
seyhmus.cacina 0:ac4dea3e2894 21 *
seyhmus.cacina 0:ac4dea3e2894 22 * Except as contained in this notice, the name of Maxim Integrated
seyhmus.cacina 0:ac4dea3e2894 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
seyhmus.cacina 0:ac4dea3e2894 24 * Products, Inc. Branding Policy.
seyhmus.cacina 0:ac4dea3e2894 25 *
seyhmus.cacina 0:ac4dea3e2894 26 * The mere transfer of this software does not imply any licenses
seyhmus.cacina 0:ac4dea3e2894 27 * of trade secrets, proprietary technology, copyrights, patents,
seyhmus.cacina 0:ac4dea3e2894 28 * trademarks, maskwork rights, or any other form of intellectual
seyhmus.cacina 0:ac4dea3e2894 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
seyhmus.cacina 0:ac4dea3e2894 30 * ownership rights.
seyhmus.cacina 0:ac4dea3e2894 31 *******************************************************************************
seyhmus.cacina 0:ac4dea3e2894 32 */
seyhmus.cacina 0:ac4dea3e2894 33
seyhmus.cacina 0:ac4dea3e2894 34 #if defined(TARGET_Maxim)
seyhmus.cacina 0:ac4dea3e2894 35
seyhmus.cacina 0:ac4dea3e2894 36 #include "USBHAL.h"
seyhmus.cacina 0:ac4dea3e2894 37 #include "usb_regs.h"
seyhmus.cacina 0:ac4dea3e2894 38 #include "clkman_regs.h"
seyhmus.cacina 0:ac4dea3e2894 39
seyhmus.cacina 0:ac4dea3e2894 40 #if defined(TARGET_MAX32625) || defined(TARGET_MAX32630)
seyhmus.cacina 0:ac4dea3e2894 41 #include "pwrman_regs.h"
seyhmus.cacina 0:ac4dea3e2894 42 #endif
seyhmus.cacina 0:ac4dea3e2894 43
seyhmus.cacina 0:ac4dea3e2894 44 #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)
seyhmus.cacina 0:ac4dea3e2894 45
seyhmus.cacina 0:ac4dea3e2894 46 USBHAL *USBHAL::instance;
seyhmus.cacina 0:ac4dea3e2894 47
seyhmus.cacina 0:ac4dea3e2894 48 typedef struct {
seyhmus.cacina 0:ac4dea3e2894 49 volatile uint32_t buf0_desc;
seyhmus.cacina 0:ac4dea3e2894 50 volatile uint32_t buf0_address;
seyhmus.cacina 0:ac4dea3e2894 51 volatile uint32_t buf1_desc;
seyhmus.cacina 0:ac4dea3e2894 52 volatile uint32_t buf1_address;
seyhmus.cacina 0:ac4dea3e2894 53 } ep_buffer_t;
seyhmus.cacina 0:ac4dea3e2894 54
seyhmus.cacina 0:ac4dea3e2894 55 typedef struct {
seyhmus.cacina 0:ac4dea3e2894 56 ep_buffer_t out_buffer;
seyhmus.cacina 0:ac4dea3e2894 57 ep_buffer_t in_buffer;
seyhmus.cacina 0:ac4dea3e2894 58 } ep0_buffer_t;
seyhmus.cacina 0:ac4dea3e2894 59
seyhmus.cacina 0:ac4dea3e2894 60 typedef struct {
seyhmus.cacina 0:ac4dea3e2894 61 ep0_buffer_t ep0;
seyhmus.cacina 0:ac4dea3e2894 62 ep_buffer_t ep[MXC_USB_NUM_EP - 1];
seyhmus.cacina 0:ac4dea3e2894 63 } ep_buffer_descriptor_t;
seyhmus.cacina 0:ac4dea3e2894 64
seyhmus.cacina 0:ac4dea3e2894 65 // Static storage for endpoint buffer descriptor table. Must be 512 byte aligned for DMA.
seyhmus.cacina 0:ac4dea3e2894 66 #ifdef __IAR_SYSTEMS_ICC__
seyhmus.cacina 0:ac4dea3e2894 67 #pragma data_alignment = 512
seyhmus.cacina 0:ac4dea3e2894 68 #else
seyhmus.cacina 0:ac4dea3e2894 69 __attribute__ ((aligned (512)))
seyhmus.cacina 0:ac4dea3e2894 70 #endif
seyhmus.cacina 0:ac4dea3e2894 71 ep_buffer_descriptor_t ep_buffer_descriptor;
seyhmus.cacina 0:ac4dea3e2894 72
seyhmus.cacina 0:ac4dea3e2894 73 // static storage for temporary data buffers. Must be 32 byte aligned.
seyhmus.cacina 0:ac4dea3e2894 74 #ifdef __IAR_SYSTEMS_ICC__
seyhmus.cacina 0:ac4dea3e2894 75 #pragma data_alignment = 4
seyhmus.cacina 0:ac4dea3e2894 76 #else
seyhmus.cacina 0:ac4dea3e2894 77 __attribute__ ((aligned (4)))
seyhmus.cacina 0:ac4dea3e2894 78 #endif
seyhmus.cacina 0:ac4dea3e2894 79 static uint8_t aligned_buffer[NUMBER_OF_LOGICAL_ENDPOINTS][MXC_USB_MAX_PACKET];
seyhmus.cacina 0:ac4dea3e2894 80
seyhmus.cacina 0:ac4dea3e2894 81 // control packet state
seyhmus.cacina 0:ac4dea3e2894 82 static enum {
seyhmus.cacina 0:ac4dea3e2894 83 CTRL_NONE = 0,
seyhmus.cacina 0:ac4dea3e2894 84 CTRL_SETUP,
seyhmus.cacina 0:ac4dea3e2894 85 CTRL_OUT,
seyhmus.cacina 0:ac4dea3e2894 86 CTRL_IN,
seyhmus.cacina 0:ac4dea3e2894 87 } control_state;
seyhmus.cacina 0:ac4dea3e2894 88
seyhmus.cacina 0:ac4dea3e2894 89 USBHAL::USBHAL(void)
seyhmus.cacina 0:ac4dea3e2894 90 {
seyhmus.cacina 0:ac4dea3e2894 91 NVIC_DisableIRQ(USB_IRQn);
seyhmus.cacina 0:ac4dea3e2894 92
seyhmus.cacina 0:ac4dea3e2894 93 #if defined(TARGET_MAX32600)
seyhmus.cacina 0:ac4dea3e2894 94 // The PLL must be enabled for USB
seyhmus.cacina 0:ac4dea3e2894 95 MBED_ASSERT(MXC_CLKMAN->clk_config & MXC_F_CLKMAN_CLK_CONFIG_PLL_ENABLE);
seyhmus.cacina 0:ac4dea3e2894 96
seyhmus.cacina 0:ac4dea3e2894 97 // Enable the USB clock
seyhmus.cacina 0:ac4dea3e2894 98 MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_GATE_N;
seyhmus.cacina 0:ac4dea3e2894 99 #elif defined(TARGET_MAX32620)
seyhmus.cacina 0:ac4dea3e2894 100 // Enable the USB clock
seyhmus.cacina 0:ac4dea3e2894 101 MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE;
seyhmus.cacina 0:ac4dea3e2894 102 #elif defined(TARGET_MAX32625) || defined(TARGET_MAX32630)
seyhmus.cacina 0:ac4dea3e2894 103 MXC_PWRMAN->pwr_rst_ctrl |= MXC_F_PWRMAN_PWR_RST_CTRL_USB_POWERED;
seyhmus.cacina 0:ac4dea3e2894 104 MXC_CLKMAN->clk_ctrl |= MXC_F_CLKMAN_CLK_CTRL_USB_CLOCK_ENABLE;
seyhmus.cacina 0:ac4dea3e2894 105 #endif
seyhmus.cacina 0:ac4dea3e2894 106
seyhmus.cacina 0:ac4dea3e2894 107 // reset the device
seyhmus.cacina 0:ac4dea3e2894 108 MXC_USB->cn = 0;
seyhmus.cacina 0:ac4dea3e2894 109 MXC_USB->cn = MXC_F_USB_CN_USB_EN;
seyhmus.cacina 0:ac4dea3e2894 110 MXC_USB->dev_inten = 0;
seyhmus.cacina 0:ac4dea3e2894 111 MXC_USB->dev_cn = 0;
seyhmus.cacina 0:ac4dea3e2894 112 MXC_USB->dev_cn = MXC_F_USB_DEV_CN_URST;
seyhmus.cacina 0:ac4dea3e2894 113 MXC_USB->dev_cn = 0;
seyhmus.cacina 0:ac4dea3e2894 114
seyhmus.cacina 0:ac4dea3e2894 115 // fill in callback arrays
seyhmus.cacina 0:ac4dea3e2894 116 epCallback[EP0OUT] = NULL;
seyhmus.cacina 0:ac4dea3e2894 117 epCallback[EP0IN] = NULL;
seyhmus.cacina 0:ac4dea3e2894 118 epCallback[EP1OUT] = &USBHAL::EP1_OUT_callback;
seyhmus.cacina 0:ac4dea3e2894 119 epCallback[EP1IN ] = &USBHAL::EP1_IN_callback;
seyhmus.cacina 0:ac4dea3e2894 120 epCallback[EP2OUT] = &USBHAL::EP2_OUT_callback;
seyhmus.cacina 0:ac4dea3e2894 121 epCallback[EP2IN ] = &USBHAL::EP2_IN_callback;
seyhmus.cacina 0:ac4dea3e2894 122 epCallback[EP3OUT] = &USBHAL::EP3_OUT_callback;
seyhmus.cacina 0:ac4dea3e2894 123 epCallback[EP3IN ] = &USBHAL::EP3_IN_callback;
seyhmus.cacina 0:ac4dea3e2894 124 epCallback[EP4OUT] = &USBHAL::EP4_OUT_callback;
seyhmus.cacina 0:ac4dea3e2894 125 epCallback[EP4IN ] = &USBHAL::EP4_IN_callback;
seyhmus.cacina 0:ac4dea3e2894 126 epCallback[EP5OUT] = &USBHAL::EP5_OUT_callback;
seyhmus.cacina 0:ac4dea3e2894 127 epCallback[EP5IN ] = &USBHAL::EP5_IN_callback;
seyhmus.cacina 0:ac4dea3e2894 128 epCallback[EP6OUT] = &USBHAL::EP6_OUT_callback;
seyhmus.cacina 0:ac4dea3e2894 129 epCallback[EP6IN ] = &USBHAL::EP6_IN_callback;
seyhmus.cacina 0:ac4dea3e2894 130 epCallback[EP7OUT] = &USBHAL::EP7_OUT_callback;
seyhmus.cacina 0:ac4dea3e2894 131 epCallback[EP7IN ] = &USBHAL::EP7_IN_callback;
seyhmus.cacina 0:ac4dea3e2894 132
seyhmus.cacina 0:ac4dea3e2894 133 // clear driver state
seyhmus.cacina 0:ac4dea3e2894 134 control_state = CTRL_NONE;
seyhmus.cacina 0:ac4dea3e2894 135
seyhmus.cacina 0:ac4dea3e2894 136 // set the descriptor location
seyhmus.cacina 0:ac4dea3e2894 137 MXC_USB->ep_base = (uint32_t)&ep_buffer_descriptor;
seyhmus.cacina 0:ac4dea3e2894 138
seyhmus.cacina 0:ac4dea3e2894 139 // enable VBUS interrupts
seyhmus.cacina 0:ac4dea3e2894 140 MXC_USB->dev_inten = MXC_F_USB_DEV_INTEN_NO_VBUS | MXC_F_USB_DEV_INTEN_VBUS;
seyhmus.cacina 0:ac4dea3e2894 141
seyhmus.cacina 0:ac4dea3e2894 142 // attach IRQ handler and enable interrupts
seyhmus.cacina 0:ac4dea3e2894 143 instance = this;
seyhmus.cacina 0:ac4dea3e2894 144 NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
seyhmus.cacina 0:ac4dea3e2894 145 NVIC_EnableIRQ(USB_IRQn);
seyhmus.cacina 0:ac4dea3e2894 146 }
seyhmus.cacina 0:ac4dea3e2894 147
seyhmus.cacina 0:ac4dea3e2894 148 USBHAL::~USBHAL(void)
seyhmus.cacina 0:ac4dea3e2894 149 {
seyhmus.cacina 0:ac4dea3e2894 150 MXC_USB->dev_cn = MXC_F_USB_DEV_CN_URST;
seyhmus.cacina 0:ac4dea3e2894 151 MXC_USB->dev_cn = 0;
seyhmus.cacina 0:ac4dea3e2894 152 MXC_USB->cn = 0;
seyhmus.cacina 0:ac4dea3e2894 153 }
seyhmus.cacina 0:ac4dea3e2894 154
seyhmus.cacina 0:ac4dea3e2894 155 void USBHAL::connect(void)
seyhmus.cacina 0:ac4dea3e2894 156 {
seyhmus.cacina 0:ac4dea3e2894 157 // enable interrupts
seyhmus.cacina 0:ac4dea3e2894 158 MXC_USB->dev_inten |= CONNECT_INTS;
seyhmus.cacina 0:ac4dea3e2894 159
seyhmus.cacina 0:ac4dea3e2894 160 // allow interrupts on ep0
seyhmus.cacina 0:ac4dea3e2894 161 MXC_USB->ep[0] |= MXC_F_USB_EP_INT_EN;
seyhmus.cacina 0:ac4dea3e2894 162
seyhmus.cacina 0:ac4dea3e2894 163 // pullup enable
seyhmus.cacina 0:ac4dea3e2894 164 MXC_USB->dev_cn |= (MXC_F_USB_DEV_CN_CONNECT | MXC_F_USB_DEV_CN_FIFO_MODE);
seyhmus.cacina 0:ac4dea3e2894 165 }
seyhmus.cacina 0:ac4dea3e2894 166
seyhmus.cacina 0:ac4dea3e2894 167 void USBHAL::disconnect(void)
seyhmus.cacina 0:ac4dea3e2894 168 {
seyhmus.cacina 0:ac4dea3e2894 169 // disable interrupts
seyhmus.cacina 0:ac4dea3e2894 170 MXC_USB->dev_inten &= ~CONNECT_INTS;
seyhmus.cacina 0:ac4dea3e2894 171
seyhmus.cacina 0:ac4dea3e2894 172 // disable pullup
seyhmus.cacina 0:ac4dea3e2894 173 MXC_USB->dev_cn &= ~MXC_F_USB_DEV_CN_CONNECT;
seyhmus.cacina 0:ac4dea3e2894 174 }
seyhmus.cacina 0:ac4dea3e2894 175
seyhmus.cacina 0:ac4dea3e2894 176 void USBHAL::configureDevice(void)
seyhmus.cacina 0:ac4dea3e2894 177 {
seyhmus.cacina 0:ac4dea3e2894 178 // do nothing
seyhmus.cacina 0:ac4dea3e2894 179 }
seyhmus.cacina 0:ac4dea3e2894 180
seyhmus.cacina 0:ac4dea3e2894 181 void USBHAL::unconfigureDevice(void)
seyhmus.cacina 0:ac4dea3e2894 182 {
seyhmus.cacina 0:ac4dea3e2894 183 // reset endpoints
seyhmus.cacina 0:ac4dea3e2894 184 for (int i = 0; i < MXC_USB_NUM_EP; i++) {
seyhmus.cacina 0:ac4dea3e2894 185 // Disable endpoint and clear the data toggle
seyhmus.cacina 0:ac4dea3e2894 186 MXC_USB->ep[i] &= ~MXC_F_USB_EP_DIR;
seyhmus.cacina 0:ac4dea3e2894 187 MXC_USB->ep[i] |= MXC_F_USB_EP_DT;
seyhmus.cacina 0:ac4dea3e2894 188 }
seyhmus.cacina 0:ac4dea3e2894 189 }
seyhmus.cacina 0:ac4dea3e2894 190
seyhmus.cacina 0:ac4dea3e2894 191 void USBHAL::setAddress(uint8_t address)
seyhmus.cacina 0:ac4dea3e2894 192 {
seyhmus.cacina 0:ac4dea3e2894 193 // do nothing
seyhmus.cacina 0:ac4dea3e2894 194 }
seyhmus.cacina 0:ac4dea3e2894 195
seyhmus.cacina 0:ac4dea3e2894 196 void USBHAL::remoteWakeup(void)
seyhmus.cacina 0:ac4dea3e2894 197 {
seyhmus.cacina 0:ac4dea3e2894 198 // do nothing
seyhmus.cacina 0:ac4dea3e2894 199 }
seyhmus.cacina 0:ac4dea3e2894 200
seyhmus.cacina 0:ac4dea3e2894 201 static ep_buffer_t *get_desc(uint8_t endpoint)
seyhmus.cacina 0:ac4dea3e2894 202 {
seyhmus.cacina 0:ac4dea3e2894 203 uint8_t epnum = EP_NUM(endpoint);
seyhmus.cacina 0:ac4dea3e2894 204 ep_buffer_t *desc;
seyhmus.cacina 0:ac4dea3e2894 205
seyhmus.cacina 0:ac4dea3e2894 206 if (epnum == 0) {
seyhmus.cacina 0:ac4dea3e2894 207 if (IN_EP(endpoint)) {
seyhmus.cacina 0:ac4dea3e2894 208 desc = &ep_buffer_descriptor.ep0.in_buffer;
seyhmus.cacina 0:ac4dea3e2894 209 } else {
seyhmus.cacina 0:ac4dea3e2894 210 desc = &ep_buffer_descriptor.ep0.out_buffer;
seyhmus.cacina 0:ac4dea3e2894 211 }
seyhmus.cacina 0:ac4dea3e2894 212 } else {
seyhmus.cacina 0:ac4dea3e2894 213 desc = &ep_buffer_descriptor.ep[epnum - 1];
seyhmus.cacina 0:ac4dea3e2894 214 }
seyhmus.cacina 0:ac4dea3e2894 215
seyhmus.cacina 0:ac4dea3e2894 216 return desc;
seyhmus.cacina 0:ac4dea3e2894 217 }
seyhmus.cacina 0:ac4dea3e2894 218
seyhmus.cacina 0:ac4dea3e2894 219 void USBHAL::EP0setup(uint8_t *buffer)
seyhmus.cacina 0:ac4dea3e2894 220 {
seyhmus.cacina 0:ac4dea3e2894 221 // Setup packet is fixed at 8 bytes
seyhmus.cacina 0:ac4dea3e2894 222 // Setup registers cannot be read in byte mode
seyhmus.cacina 0:ac4dea3e2894 223 uint32_t *ptr32 = (uint32_t*)buffer;
seyhmus.cacina 0:ac4dea3e2894 224 ptr32[0] = (uint32_t)MXC_USB->setup0;
seyhmus.cacina 0:ac4dea3e2894 225 ptr32[1] = (uint32_t)MXC_USB->setup1;
seyhmus.cacina 0:ac4dea3e2894 226 }
seyhmus.cacina 0:ac4dea3e2894 227
seyhmus.cacina 0:ac4dea3e2894 228 void USBHAL::EP0read(void)
seyhmus.cacina 0:ac4dea3e2894 229 {
seyhmus.cacina 0:ac4dea3e2894 230 if (control_state == CTRL_IN) {
seyhmus.cacina 0:ac4dea3e2894 231 // This is the status stage. ACK.
seyhmus.cacina 0:ac4dea3e2894 232 MXC_USB->ep[0] |= MXC_F_USB_EP_ST_ACK;
seyhmus.cacina 0:ac4dea3e2894 233 control_state = CTRL_NONE;
seyhmus.cacina 0:ac4dea3e2894 234 return;
seyhmus.cacina 0:ac4dea3e2894 235 }
seyhmus.cacina 0:ac4dea3e2894 236
seyhmus.cacina 0:ac4dea3e2894 237 control_state = CTRL_OUT;
seyhmus.cacina 0:ac4dea3e2894 238
seyhmus.cacina 0:ac4dea3e2894 239 endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
seyhmus.cacina 0:ac4dea3e2894 240 }
seyhmus.cacina 0:ac4dea3e2894 241
seyhmus.cacina 0:ac4dea3e2894 242 void USBHAL::EP0readStage(void)
seyhmus.cacina 0:ac4dea3e2894 243 {
seyhmus.cacina 0:ac4dea3e2894 244 // do nothing
seyhmus.cacina 0:ac4dea3e2894 245 }
seyhmus.cacina 0:ac4dea3e2894 246
seyhmus.cacina 0:ac4dea3e2894 247 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
seyhmus.cacina 0:ac4dea3e2894 248 {
seyhmus.cacina 0:ac4dea3e2894 249 uint32_t size;
seyhmus.cacina 0:ac4dea3e2894 250
seyhmus.cacina 0:ac4dea3e2894 251 if (MXC_USB->out_owner & 1) {
seyhmus.cacina 0:ac4dea3e2894 252 return 0;
seyhmus.cacina 0:ac4dea3e2894 253 }
seyhmus.cacina 0:ac4dea3e2894 254
seyhmus.cacina 0:ac4dea3e2894 255 // get the packet length and contents
seyhmus.cacina 0:ac4dea3e2894 256 ep_buffer_t *desc = get_desc(EP0OUT);
seyhmus.cacina 0:ac4dea3e2894 257 size = desc->buf0_desc;
seyhmus.cacina 0:ac4dea3e2894 258 memcpy(buffer, aligned_buffer[0], size);
seyhmus.cacina 0:ac4dea3e2894 259
seyhmus.cacina 0:ac4dea3e2894 260 return size;
seyhmus.cacina 0:ac4dea3e2894 261 }
seyhmus.cacina 0:ac4dea3e2894 262
seyhmus.cacina 0:ac4dea3e2894 263 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
seyhmus.cacina 0:ac4dea3e2894 264 {
seyhmus.cacina 0:ac4dea3e2894 265 if ((size == 0) && (control_state != CTRL_IN)) {
seyhmus.cacina 0:ac4dea3e2894 266 // This is a status stage ACK. Handle in hardware.
seyhmus.cacina 0:ac4dea3e2894 267 MXC_USB->ep[0] |= MXC_F_USB_EP_ST_ACK;
seyhmus.cacina 0:ac4dea3e2894 268 control_state = CTRL_NONE;
seyhmus.cacina 0:ac4dea3e2894 269 return;
seyhmus.cacina 0:ac4dea3e2894 270 }
seyhmus.cacina 0:ac4dea3e2894 271
seyhmus.cacina 0:ac4dea3e2894 272 control_state = CTRL_IN;
seyhmus.cacina 0:ac4dea3e2894 273
seyhmus.cacina 0:ac4dea3e2894 274 endpointWrite(EP0IN, buffer, size);
seyhmus.cacina 0:ac4dea3e2894 275 }
seyhmus.cacina 0:ac4dea3e2894 276
seyhmus.cacina 0:ac4dea3e2894 277 void USBHAL::EP0stall(void)
seyhmus.cacina 0:ac4dea3e2894 278 {
seyhmus.cacina 0:ac4dea3e2894 279 stallEndpoint(0);
seyhmus.cacina 0:ac4dea3e2894 280 }
seyhmus.cacina 0:ac4dea3e2894 281
seyhmus.cacina 0:ac4dea3e2894 282 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
seyhmus.cacina 0:ac4dea3e2894 283 {
seyhmus.cacina 0:ac4dea3e2894 284 uint8_t epnum = EP_NUM(endpoint);
seyhmus.cacina 0:ac4dea3e2894 285
seyhmus.cacina 0:ac4dea3e2894 286 if ((endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS) || IN_EP(endpoint)) {
seyhmus.cacina 0:ac4dea3e2894 287 return EP_INVALID;
seyhmus.cacina 0:ac4dea3e2894 288 }
seyhmus.cacina 0:ac4dea3e2894 289
seyhmus.cacina 0:ac4dea3e2894 290 if (maximumSize > MXC_USB_MAX_PACKET) {
seyhmus.cacina 0:ac4dea3e2894 291 return EP_INVALID;
seyhmus.cacina 0:ac4dea3e2894 292 }
seyhmus.cacina 0:ac4dea3e2894 293
seyhmus.cacina 0:ac4dea3e2894 294 uint32_t mask = (1 << epnum);
seyhmus.cacina 0:ac4dea3e2894 295 if (MXC_USB->out_owner & mask) {
seyhmus.cacina 0:ac4dea3e2894 296 return EP_INVALID;
seyhmus.cacina 0:ac4dea3e2894 297 }
seyhmus.cacina 0:ac4dea3e2894 298
seyhmus.cacina 0:ac4dea3e2894 299 ep_buffer_t *desc = get_desc(endpoint);
seyhmus.cacina 0:ac4dea3e2894 300 desc->buf0_desc = maximumSize;
seyhmus.cacina 0:ac4dea3e2894 301 desc->buf0_address = (uint32_t)aligned_buffer[epnum];
seyhmus.cacina 0:ac4dea3e2894 302
seyhmus.cacina 0:ac4dea3e2894 303 MXC_USB->out_owner = mask;
seyhmus.cacina 0:ac4dea3e2894 304
seyhmus.cacina 0:ac4dea3e2894 305 return EP_PENDING;
seyhmus.cacina 0:ac4dea3e2894 306 }
seyhmus.cacina 0:ac4dea3e2894 307
seyhmus.cacina 0:ac4dea3e2894 308 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead)
seyhmus.cacina 0:ac4dea3e2894 309 {
seyhmus.cacina 0:ac4dea3e2894 310 if ((endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS) || IN_EP(endpoint)) {
seyhmus.cacina 0:ac4dea3e2894 311 return EP_INVALID;
seyhmus.cacina 0:ac4dea3e2894 312 }
seyhmus.cacina 0:ac4dea3e2894 313
seyhmus.cacina 0:ac4dea3e2894 314 uint32_t mask = (1 << EP_NUM(endpoint));
seyhmus.cacina 0:ac4dea3e2894 315 if (MXC_USB->out_owner & mask) {
seyhmus.cacina 0:ac4dea3e2894 316 return EP_PENDING;
seyhmus.cacina 0:ac4dea3e2894 317 }
seyhmus.cacina 0:ac4dea3e2894 318
seyhmus.cacina 0:ac4dea3e2894 319 // get the packet length and contents
seyhmus.cacina 0:ac4dea3e2894 320 ep_buffer_t *desc = get_desc(endpoint);
seyhmus.cacina 0:ac4dea3e2894 321 *bytesRead = desc->buf0_desc;
seyhmus.cacina 0:ac4dea3e2894 322 memcpy(data, aligned_buffer[EP_NUM(endpoint)], *bytesRead);
seyhmus.cacina 0:ac4dea3e2894 323
seyhmus.cacina 0:ac4dea3e2894 324 return EP_COMPLETED;
seyhmus.cacina 0:ac4dea3e2894 325 }
seyhmus.cacina 0:ac4dea3e2894 326
seyhmus.cacina 0:ac4dea3e2894 327 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
seyhmus.cacina 0:ac4dea3e2894 328 {
seyhmus.cacina 0:ac4dea3e2894 329 uint8_t epnum = EP_NUM(endpoint);
seyhmus.cacina 0:ac4dea3e2894 330
seyhmus.cacina 0:ac4dea3e2894 331 if ((endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS) || OUT_EP(endpoint)) {
seyhmus.cacina 0:ac4dea3e2894 332 return EP_INVALID;
seyhmus.cacina 0:ac4dea3e2894 333 }
seyhmus.cacina 0:ac4dea3e2894 334
seyhmus.cacina 0:ac4dea3e2894 335 if (size > MXC_USB_MAX_PACKET) {
seyhmus.cacina 0:ac4dea3e2894 336 return EP_INVALID;
seyhmus.cacina 0:ac4dea3e2894 337 }
seyhmus.cacina 0:ac4dea3e2894 338
seyhmus.cacina 0:ac4dea3e2894 339 uint32_t mask = (1 << epnum);
seyhmus.cacina 0:ac4dea3e2894 340 if (MXC_USB->in_owner & mask) {
seyhmus.cacina 0:ac4dea3e2894 341 return EP_INVALID;
seyhmus.cacina 0:ac4dea3e2894 342 }
seyhmus.cacina 0:ac4dea3e2894 343
seyhmus.cacina 0:ac4dea3e2894 344 memcpy(aligned_buffer[epnum], data, size);
seyhmus.cacina 0:ac4dea3e2894 345
seyhmus.cacina 0:ac4dea3e2894 346 ep_buffer_t *desc = get_desc(endpoint);
seyhmus.cacina 0:ac4dea3e2894 347 desc->buf0_desc = size;
seyhmus.cacina 0:ac4dea3e2894 348 desc->buf0_address = (uint32_t)aligned_buffer[epnum];
seyhmus.cacina 0:ac4dea3e2894 349
seyhmus.cacina 0:ac4dea3e2894 350 // start the DMA
seyhmus.cacina 0:ac4dea3e2894 351 MXC_USB->in_owner = mask;
seyhmus.cacina 0:ac4dea3e2894 352
seyhmus.cacina 0:ac4dea3e2894 353 return EP_PENDING;
seyhmus.cacina 0:ac4dea3e2894 354 }
seyhmus.cacina 0:ac4dea3e2894 355
seyhmus.cacina 0:ac4dea3e2894 356 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
seyhmus.cacina 0:ac4dea3e2894 357 {
seyhmus.cacina 0:ac4dea3e2894 358 uint32_t mask = (1 << EP_NUM(endpoint));
seyhmus.cacina 0:ac4dea3e2894 359 if (MXC_USB->in_owner & mask) {
seyhmus.cacina 0:ac4dea3e2894 360 return EP_PENDING;
seyhmus.cacina 0:ac4dea3e2894 361 }
seyhmus.cacina 0:ac4dea3e2894 362
seyhmus.cacina 0:ac4dea3e2894 363 return EP_COMPLETED;
seyhmus.cacina 0:ac4dea3e2894 364 }
seyhmus.cacina 0:ac4dea3e2894 365
seyhmus.cacina 0:ac4dea3e2894 366 void USBHAL::stallEndpoint(uint8_t endpoint)
seyhmus.cacina 0:ac4dea3e2894 367 {
seyhmus.cacina 0:ac4dea3e2894 368 uint8_t epnum = EP_NUM(endpoint);
seyhmus.cacina 0:ac4dea3e2894 369
seyhmus.cacina 0:ac4dea3e2894 370 if (epnum == 0) {
seyhmus.cacina 0:ac4dea3e2894 371 MXC_USB->ep[epnum] |= MXC_F_USB_EP_ST_STALL;
seyhmus.cacina 0:ac4dea3e2894 372 }
seyhmus.cacina 0:ac4dea3e2894 373
seyhmus.cacina 0:ac4dea3e2894 374 MXC_USB->ep[epnum] |= MXC_F_USB_EP_STALL;
seyhmus.cacina 0:ac4dea3e2894 375 }
seyhmus.cacina 0:ac4dea3e2894 376
seyhmus.cacina 0:ac4dea3e2894 377 void USBHAL::unstallEndpoint(uint8_t endpoint)
seyhmus.cacina 0:ac4dea3e2894 378 {
seyhmus.cacina 0:ac4dea3e2894 379 MXC_USB->ep[EP_NUM(endpoint)] &= ~MXC_F_USB_EP_STALL;
seyhmus.cacina 0:ac4dea3e2894 380 }
seyhmus.cacina 0:ac4dea3e2894 381
seyhmus.cacina 0:ac4dea3e2894 382 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options)
seyhmus.cacina 0:ac4dea3e2894 383 {
seyhmus.cacina 0:ac4dea3e2894 384 uint8_t epnum = EP_NUM(endpoint);
seyhmus.cacina 0:ac4dea3e2894 385 uint32_t ep_ctrl;
seyhmus.cacina 0:ac4dea3e2894 386
seyhmus.cacina 0:ac4dea3e2894 387 if (epnum >= NUMBER_OF_PHYSICAL_ENDPOINTS) {
seyhmus.cacina 0:ac4dea3e2894 388 return false;
seyhmus.cacina 0:ac4dea3e2894 389 }
seyhmus.cacina 0:ac4dea3e2894 390
seyhmus.cacina 0:ac4dea3e2894 391 if (IN_EP(endpoint)) {
seyhmus.cacina 0:ac4dea3e2894 392 ep_ctrl = (MXC_V_USB_EP_DIR_IN << MXC_F_USB_EP_DIR_POS);
seyhmus.cacina 0:ac4dea3e2894 393 } else {
seyhmus.cacina 0:ac4dea3e2894 394 ep_ctrl = (MXC_S_USB_EP_DIR_OUT << MXC_F_USB_EP_DIR_POS);
seyhmus.cacina 0:ac4dea3e2894 395 }
seyhmus.cacina 0:ac4dea3e2894 396
seyhmus.cacina 0:ac4dea3e2894 397 ep_ctrl |= (MXC_F_USB_EP_DT | MXC_F_USB_EP_INT_EN);
seyhmus.cacina 0:ac4dea3e2894 398
seyhmus.cacina 0:ac4dea3e2894 399 MXC_USB->ep[epnum] = ep_ctrl;
seyhmus.cacina 0:ac4dea3e2894 400
seyhmus.cacina 0:ac4dea3e2894 401 return true;
seyhmus.cacina 0:ac4dea3e2894 402 }
seyhmus.cacina 0:ac4dea3e2894 403
seyhmus.cacina 0:ac4dea3e2894 404 bool USBHAL::getEndpointStallState(unsigned char endpoint)
seyhmus.cacina 0:ac4dea3e2894 405 {
seyhmus.cacina 0:ac4dea3e2894 406 return !!(MXC_USB->ep[endpoint] & MXC_F_USB_EP_STALL);
seyhmus.cacina 0:ac4dea3e2894 407 }
seyhmus.cacina 0:ac4dea3e2894 408
seyhmus.cacina 0:ac4dea3e2894 409 void USBHAL::_usbisr(void)
seyhmus.cacina 0:ac4dea3e2894 410 {
seyhmus.cacina 0:ac4dea3e2894 411 instance->usbisr();
seyhmus.cacina 0:ac4dea3e2894 412 }
seyhmus.cacina 0:ac4dea3e2894 413
seyhmus.cacina 0:ac4dea3e2894 414 void USBHAL::usbisr(void)
seyhmus.cacina 0:ac4dea3e2894 415 {
seyhmus.cacina 0:ac4dea3e2894 416 // get and clear irqs
seyhmus.cacina 0:ac4dea3e2894 417 uint32_t irq_flags = MXC_USB->dev_intfl;
seyhmus.cacina 0:ac4dea3e2894 418 MXC_USB->dev_intfl = irq_flags;
seyhmus.cacina 0:ac4dea3e2894 419
seyhmus.cacina 0:ac4dea3e2894 420 // process only enabled interrupts
seyhmus.cacina 0:ac4dea3e2894 421 irq_flags &= MXC_USB->dev_inten;
seyhmus.cacina 0:ac4dea3e2894 422
seyhmus.cacina 0:ac4dea3e2894 423 // suspend
seyhmus.cacina 0:ac4dea3e2894 424 if (irq_flags & MXC_F_USB_DEV_INTFL_SUSP) {
seyhmus.cacina 0:ac4dea3e2894 425 suspendStateChanged(1);
seyhmus.cacina 0:ac4dea3e2894 426 }
seyhmus.cacina 0:ac4dea3e2894 427
seyhmus.cacina 0:ac4dea3e2894 428 // bus reset
seyhmus.cacina 0:ac4dea3e2894 429 if (irq_flags & MXC_F_USB_DEV_INTFL_BRST) {
seyhmus.cacina 0:ac4dea3e2894 430
seyhmus.cacina 0:ac4dea3e2894 431 // reset endpoints
seyhmus.cacina 0:ac4dea3e2894 432 for (int i = 0; i < MXC_USB_NUM_EP; i++) {
seyhmus.cacina 0:ac4dea3e2894 433 // Disable endpoint and clear the data toggle
seyhmus.cacina 0:ac4dea3e2894 434 MXC_USB->ep[i] &= ~MXC_F_USB_EP_DIR;
seyhmus.cacina 0:ac4dea3e2894 435 MXC_USB->ep[i] |= MXC_F_USB_EP_DT;
seyhmus.cacina 0:ac4dea3e2894 436 }
seyhmus.cacina 0:ac4dea3e2894 437
seyhmus.cacina 0:ac4dea3e2894 438 // clear driver state
seyhmus.cacina 0:ac4dea3e2894 439 control_state = CTRL_NONE;
seyhmus.cacina 0:ac4dea3e2894 440
seyhmus.cacina 0:ac4dea3e2894 441 busReset();
seyhmus.cacina 0:ac4dea3e2894 442
seyhmus.cacina 0:ac4dea3e2894 443 // no need to process events after reset
seyhmus.cacina 0:ac4dea3e2894 444 return;
seyhmus.cacina 0:ac4dea3e2894 445 }
seyhmus.cacina 0:ac4dea3e2894 446
seyhmus.cacina 0:ac4dea3e2894 447 // Setup packet
seyhmus.cacina 0:ac4dea3e2894 448 if (irq_flags & MXC_F_USB_DEV_INTFL_SETUP) {
seyhmus.cacina 0:ac4dea3e2894 449 control_state = CTRL_SETUP;
seyhmus.cacina 0:ac4dea3e2894 450 EP0setupCallback();
seyhmus.cacina 0:ac4dea3e2894 451 }
seyhmus.cacina 0:ac4dea3e2894 452
seyhmus.cacina 0:ac4dea3e2894 453 // IN packets
seyhmus.cacina 0:ac4dea3e2894 454 if (irq_flags & MXC_F_USB_DEV_INTFL_EP_IN) {
seyhmus.cacina 0:ac4dea3e2894 455 // get and clear IN irqs
seyhmus.cacina 0:ac4dea3e2894 456 uint32_t in_irqs = MXC_USB->in_int;
seyhmus.cacina 0:ac4dea3e2894 457 MXC_USB->in_int = in_irqs;
seyhmus.cacina 0:ac4dea3e2894 458
seyhmus.cacina 0:ac4dea3e2894 459 if (in_irqs & 1) {
seyhmus.cacina 0:ac4dea3e2894 460 EP0in();
seyhmus.cacina 0:ac4dea3e2894 461 }
seyhmus.cacina 0:ac4dea3e2894 462
seyhmus.cacina 0:ac4dea3e2894 463 for (uint8_t epnum = 1; epnum < NUMBER_OF_LOGICAL_ENDPOINTS; epnum++) {
seyhmus.cacina 0:ac4dea3e2894 464 uint32_t irq_mask = (1 << epnum);
seyhmus.cacina 0:ac4dea3e2894 465 if (in_irqs & irq_mask) {
seyhmus.cacina 0:ac4dea3e2894 466 uint8_t endpoint = (epnum << 1) | DIR_IN;
seyhmus.cacina 0:ac4dea3e2894 467 (instance->*(epCallback[endpoint]))();
seyhmus.cacina 0:ac4dea3e2894 468 }
seyhmus.cacina 0:ac4dea3e2894 469 }
seyhmus.cacina 0:ac4dea3e2894 470 }
seyhmus.cacina 0:ac4dea3e2894 471
seyhmus.cacina 0:ac4dea3e2894 472 // OUT packets
seyhmus.cacina 0:ac4dea3e2894 473 if (irq_flags & MXC_F_USB_DEV_INTFL_EP_OUT) {
seyhmus.cacina 0:ac4dea3e2894 474 // get and clear OUT irqs
seyhmus.cacina 0:ac4dea3e2894 475 uint32_t out_irqs = MXC_USB->out_int;
seyhmus.cacina 0:ac4dea3e2894 476 MXC_USB->out_int = out_irqs;
seyhmus.cacina 0:ac4dea3e2894 477
seyhmus.cacina 0:ac4dea3e2894 478 if (out_irqs & 1) {
seyhmus.cacina 0:ac4dea3e2894 479 EP0out();
seyhmus.cacina 0:ac4dea3e2894 480 }
seyhmus.cacina 0:ac4dea3e2894 481
seyhmus.cacina 0:ac4dea3e2894 482 for (uint8_t epnum = 1; epnum < NUMBER_OF_LOGICAL_ENDPOINTS; epnum++) {
seyhmus.cacina 0:ac4dea3e2894 483 uint32_t irq_mask = (1 << epnum);
seyhmus.cacina 0:ac4dea3e2894 484 if (out_irqs & irq_mask) {
seyhmus.cacina 0:ac4dea3e2894 485 uint8_t endpoint = (epnum << 1) | DIR_OUT;
seyhmus.cacina 0:ac4dea3e2894 486 (instance->*(epCallback[endpoint]))();
seyhmus.cacina 0:ac4dea3e2894 487 }
seyhmus.cacina 0:ac4dea3e2894 488 }
seyhmus.cacina 0:ac4dea3e2894 489 }
seyhmus.cacina 0:ac4dea3e2894 490 }
seyhmus.cacina 0:ac4dea3e2894 491
seyhmus.cacina 0:ac4dea3e2894 492 #endif