Commit 8ad3aa32 authored by schneider's avatar schneider
Browse files

add usb example as base for bootloader

parent 6002c36a
file build/max32665.elf
target remote localhost:3333
################################################################################
# Copyright (C) 2017 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.
#
# $Date: 2018-08-10 21:35:48 +0000 (Fri, 10 Aug 2018) $
# $Revision: 36863 $
#
###############################################################################
# This is the name of the build output file
ifeq "$(PROJECT)" ""
PROJECT=max32665
endif
# Specify the target processor
ifeq "$(TARGET)" ""
TARGET=MAX32665
endif
# Create Target name variables
TARGET_UC:=$(shell echo $(TARGET) | tr a-z A-Z)
TARGET_LC:=$(shell echo $(TARGET) | tr A-Z a-z)
# Select 'GCC' or 'IAR' compiler
COMPILER=GCC
# Specify the board used
ifeq "$(BOARD)" ""
BOARD=EvKit_V1
endif
# This is the path to the CMSIS root directory
ifeq "$(MAXIM_PATH)" ""
LIBS_DIR=../sdk/Libraries
else
LIBS_DIR=/$(subst \,/,$(subst :,,$(MAXIM_PATH))/Firmware/$(TARGET_UC)/Libraries)
endif
CMSIS_ROOT=$(LIBS_DIR)/CMSIS
# Source files for this test (add path to VPATH below)
SRCS = main.c
SRCS += mscmem.c
# Where to find source files for this test
VPATH = .
# Where to find header files for this test
IPATH = .
# Enable assertion checking for development
PROJ_CFLAGS+=-DMXC_ASSERT_ENABLE
# Specify the target revision to override default
# "A2" in ASCII
# TARGET_REV=0x4132
# Use this variables to specify and alternate tool path
#TOOL_DIR=/opt/gcc-arm-none-eabi-4_8-2013q4/bin
# Use these variables to add project specific tool options
#PROJ_CFLAGS+=--specs=nano.specs
#PROJ_LDFLAGS+=--specs=nano.specs
# Point this variable to a startup file to override the default file
#STARTUPFILE=start.S
# Set MXC_OPTIMIZE to override the default optimization level
#MXC_OPTIMIZE_CFLAGS=-Og
# Point this variable to a linker file to override the default file
# LINKERFILE=$(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source/GCC/$(TARGET_LC).ld
################################################################################
# Include external library makefiles here
# Include the BSP
BOARD_DIR=$(LIBS_DIR)/Boards/$(BOARD)
include $(BOARD_DIR)/board.mk
# Include the peripheral driver
PERIPH_DRIVER_DIR=$(LIBS_DIR)/$(TARGET_UC)PeriphDriver
include $(PERIPH_DRIVER_DIR)/periphdriver.mk
MAXUSB_DIR=$(LIBS_DIR)/MAXUSB
include $(MAXUSB_DIR)/maxusb.mk
################################################################################
# Include the rules for building for this target. All other makefiles should be
# included before this one.
include $(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source/$(COMPILER)/$(TARGET_LC).mk
# The rule to clean out all the build products.
distclean: clean
$(MAKE) -C ${PERIPH_DRIVER_DIR} clean
/*******************************************************************************
* Copyright (C) 2017 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.
*
* Description: Communications Device Class ACM (Serial Port) over USB
* $Id: descriptors.h 31172 2017-10-05 19:05:57Z zach.metzinger $
*
*******************************************************************************
*/
#ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_
#include <stdint.h>
#include "usb.h"
#include "hid_kbd.h"
usb_device_descriptor_t __attribute__((aligned(4))) device_descriptor = {
0x12, /* bLength = 18 */
0x01, /* bDescriptorType = Device */
0x0110, /* bcdUSB USB spec rev (BCD) */
0x00, /* bDeviceClass = mass storage (0) */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize0 is 64 bytes */
0x0B6A, /* idVendor (Maxim Integrated) */
0x4402, /* idProduct */
0x0100, /* bcdDevice */
0x01, /* iManufacturer Descriptor ID */
0x02, /* iProduct Descriptor ID */
0x03, /* iSerialNumber = (0) No string */
0x01 /* bNumConfigurations */
};
__attribute__((aligned(4)))
struct __attribute__((packed)) {
usb_configuration_descriptor_t config_descriptor;
usb_interface_descriptor_t msc_interface_descriptor;
usb_endpoint_descriptor_t endpoint_descriptor_1;
usb_endpoint_descriptor_t endpoint_descriptor_2;
} config_descriptor =
{
{
0x09, /* bLength = 9 */
0x02, /* bDescriptorType = Config (2) */
0x0020, /* wTotalLength(L/H) */
0x01, /* bNumInterfaces */
0x01, /* bConfigValue */
0x00, /* iConfiguration */
0xC0, /* bmAttributes (self-powered, no remote wakeup) */
0x01, /* MaxPower is 2ma (units are 2ma/bit) */
},
{ /* First Interface Descriptor For MSC Interface */
0x09, /* bLength = 9 */
0x04, /* bDescriptorType = Interface (4) */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints (one for INm one for OUT) */
0x08, /* bInterfaceClass = Mass Storage (8) */
0x06, /* bInterfaceSubClass = SCSI Transparent Command Set */
0x50, /* bInterfaceProtocol = Bulk-Only Transport */
0x00, /* iInterface */
},
{ /* OUT Endpoint 1 (Descriptor #1) */
0x07, /* bLength */
0x05, /* bDescriptorType (Endpoint) */
0x01, /* bEndpointAddress (EP1-OUT) */
0x02, /* bmAttributes (bulk) */
0x0040, /* wMaxPacketSize */
0x00, /* bInterval (N/A) */
},
{ /* IN Endpoint 2 (Descriptor #2) */
0x07, /* bLength */
0x05, /* bDescriptorType (Endpoint) */
0x82, /* bEndpointAddress (EP2-IN) */
0x02, /* bmAttributes (bulk) */
0x0040, /* wMaxPacketSize */
0x00 /* bInterval (N/A) */
}
};
__attribute__((aligned(4)))
uint8_t lang_id_desc[] = {
0x04, /* bLength */
0x03, /* bDescriptorType */
0x09, 0x04 /* bString = wLANGID (see usb_20.pdf 9.6.7 String) */
};
__attribute__((aligned(4)))
uint8_t mfg_id_desc[] = {
0x22, /* bLength */
0x03, /* bDescriptorType */
'M', 0,
'a', 0,
'x', 0,
'i', 0,
'm', 0,
' ', 0,
'I', 0,
'n', 0,
't', 0,
'e', 0,
'g', 0,
'r', 0,
'a', 0,
't', 0,
'e', 0,
'd', 0,
};
__attribute__((aligned(4)))
uint8_t prod_id_desc[] = {
0x38, /* bLength */
0x03, /* bDescriptorType */
'M', 0,
'A', 0,
'X', 0,
'U', 0,
'S', 0,
'B', 0,
' ', 0,
'M', 0,
'a', 0,
's', 0,
's', 0,
' ', 0,
'S', 0,
't', 0,
'o', 0,
'r', 0,
'a', 0,
'g', 0,
'e', 0,
' ', 0,
'E', 0,
'x', 0,
'a', 0,
'm', 0,
'p', 0,
'l', 0,
'e', 0,
};
/* Not currently used (see device descriptor), but could be enabled if desired */
__attribute__((aligned(4)))
uint8_t serial_id_desc[] = {
26, /* bLength */
0x03, /* bDescriptorType */
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'0',0,
'1',0
};
#endif /* _DESCRIPTORS_H_ */
/*******************************************************************************
* Copyright (C) 2016 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.
*
* $Id: main.c 31505 2017-10-20 21:16:29Z zach.metzinger $
*
*******************************************************************************
*/
/**
* @file main.c
* @brief USB Mass Storage Class example
* @details This project creates a mass storage device using either on-board RAM or
* external SPI flash memory. Load the project, connect a cable from the PC
* to the USB connector. A new external drive should appear than can be read
* and written.
*/
#include <stdio.h>
#include <stddef.h>
#include "mxc_config.h"
#include "mxc_sys.h"
#include "mxc_delay.h"
#include "board.h"
#include "led.h"
#include "usb.h"
#include "usb_event.h"
#include "enumerate.h"
#include "msc.h"
#include "descriptors.h"
#include "mscmem.h"
/***** Definitions *****/
#define EVENT_ENUM_COMP MAXUSB_NUM_EVENTS
#define EVENT_REMOTE_WAKE (EVENT_ENUM_COMP + 1)
#define BUFFER_SIZE 64
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
/***** Global Data *****/
volatile int configured;
volatile int suspended;
volatile unsigned int event_flags;
int remote_wake_en;
/***** Function Prototypes *****/
static int setconfig_callback(usb_setup_pkt *sud, void *cbdata);
static int setfeature_callback(usb_setup_pkt *sud, void *cbdata);
static int clrfeature_callback(usb_setup_pkt *sud, void *cbdata);
static int event_callback(maxusb_event_t evt, void *data);
static void usb_app_sleep(void);
static void usb_app_wakeup(void);
/***** File Scope Variables *****/
/* This EP assignment must match the Configuration Descriptor */
static const msc_cfg_t msc_cfg = {
1, /* EP OUT */
MXC_USBHS_MAX_PACKET, /* OUT max packet size */
2, /* EP IN */
MXC_USBHS_MAX_PACKET, /* IN max packet size */
};
static const msc_idstrings_t ids = {
"MAXIM", /* Vendor string. Maximum of 8 bytes */
"MSC Example", /* Product string. Maximum of 16 bytes */
"1.0" /* Version string. Maximum of 4 bytes */
};
/* Functions to control "disk" memory. See msc.h for definitions. */
static const msc_mem_t mem = {
mscmem_init,
mscmem_start,
mscmem_stop,
mscmem_ready,
mscmem_size,
mscmem_read,
mscmem_write,
};
/* This callback is used to allow the driver to call part specific initialization functions. */
int usb_startup_cb()
{
const sys_cfg_usbhs_t sys_usbhs_cfg = NULL;
return SYS_USBHS_Init(&sys_usbhs_cfg);
}
int usb_shutdown_cb()
{
return SYS_USBHS_Shutdown();
}
/* User-supplied function to delay usec micro-seconds */
void delay_us(unsigned int usec)
{
/* mxc_delay() takes unsigned long, so can't use it directly */
mxc_delay(usec);
}
/******************************************************************************/
int main(void)
{
maxusb_cfg_options_t usb_opts;
printf("\n\n***** " TOSTRING(TARGET) " USB Mass Storage Example *****\n");
printf("Waiting for VBUS...\n");
/* Initialize state */
configured = 0;
suspended = 0;
event_flags = 0;
remote_wake_en = 0;
/* Start out in full speed */
usb_opts.enable_hs = 0;
usb_opts.delay_us = delay_us; /* Function which will be used for delays */
usb_opts.init_callback = usb_startup_cb;
usb_opts.shutdown_callback = usb_shutdown_cb;
/* Initialize the usb module */
if (usb_init(&usb_opts) != 0) {
printf("usb_init() failed\n");
while (1);
}
/* Initialize the enumeration module */
if (enum_init() != 0) {
printf("enum_init() failed\n");
while (1);
}
/* Register enumeration data */
enum_register_descriptor(ENUM_DESC_DEVICE, (uint8_t*)&device_descriptor, 0);
enum_register_descriptor(ENUM_DESC_CONFIG, (uint8_t*)&config_descriptor, 0);
enum_register_descriptor(ENUM_DESC_STRING, lang_id_desc, 0);
enum_register_descriptor(ENUM_DESC_STRING, mfg_id_desc, 1);
enum_register_descriptor(ENUM_DESC_STRING, prod_id_desc, 2);
enum_register_descriptor(ENUM_DESC_STRING, serial_id_desc, 3);
/* Handle configuration */
enum_register_callback(ENUM_SETCONFIG, setconfig_callback, NULL);
/* Handle feature set/clear */
enum_register_callback(ENUM_SETFEATURE, setfeature_callback, NULL);
enum_register_callback(ENUM_CLRFEATURE, clrfeature_callback, NULL);
/* Initialize the class driver */
if (msc_init(&config_descriptor.msc_interface_descriptor, &ids, &mem) != 0) {
printf("msc_init() failed\n");
while (1);
}
/* Register callbacks */
usb_event_enable(MAXUSB_EVENT_NOVBUS, event_callback, NULL);
usb_event_enable(MAXUSB_EVENT_VBUS, event_callback, NULL);
/* Start with USB in low power mode */
usb_app_sleep();
NVIC_EnableIRQ(USB_IRQn);
/* Wait for events */
while (1) {
if (suspended || !configured) {
LED_Off(0);
} else {
LED_On(0);
}
if (event_flags) {
/* Display events */
if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_NOVBUS)) {
MXC_CLRBIT(&event_flags, MAXUSB_EVENT_NOVBUS);
printf("VBUS Disconnect\n");
} else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_VBUS)) {
MXC_CLRBIT(&event_flags, MAXUSB_EVENT_VBUS);
printf("VBUS Connect\n");
} else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_BRST)) {
MXC_CLRBIT(&event_flags, MAXUSB_EVENT_BRST);
printf("Bus Reset\n");
} else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_SUSP)) {
MXC_CLRBIT(&event_flags, MAXUSB_EVENT_SUSP);
printf("Suspended\n");
} else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_DPACT)) {
MXC_CLRBIT(&event_flags, MAXUSB_EVENT_DPACT);
printf("Resume\n");
} else if (MXC_GETBIT(&event_flags, EVENT_ENUM_COMP)) {
MXC_CLRBIT(&event_flags, EVENT_ENUM_COMP);
printf("Enumeration complete.\n");
} else if (MXC_GETBIT(&event_flags, EVENT_REMOTE_WAKE)) {
MXC_CLRBIT(&event_flags, EVENT_REMOTE_WAKE);
printf("Remote Wakeup\n");
}
}
}
}
/******************************************************************************/
static int setconfig_callback(usb_setup_pkt *sud, void *cbdata)
{
/* Confirm the configuration value */
if (sud->wValue == config_descriptor.config_descriptor.bConfigurationValue) {
configured = 1;
MXC_SETBIT(&event_flags, EVENT_ENUM_COMP);
return msc_configure(&msc_cfg); /* Configure the device class */
} else if (sud->wValue == 0) {
configured = 0;
return msc_deconfigure();
}
return -1;
}
/******************************************************************************/
static int setfeature_callback(usb_setup_pkt *sud, void *cbdata)
{
if(sud->wValue == FEAT_REMOTE_WAKE) {
remote_wake_en = 1;
} else {
// Unknown callback
return -1;
}
return 0;
}
/******************************************************************************/
static int clrfeature_callback(usb_setup_pkt *sud, void *cbdata)
{
if(sud->wValue == FEAT_REMOTE_WAKE) {
remote_wake_en = 0;
} else {
// Unknown callback
return -1;
}
return 0;
}
/******************************************************************************/
static void usb_app_sleep(void)
{
/* TODO: Place low-power code here */
suspended = 1;
}
/******************************************************************************/
static void usb_app_wakeup(void)
{
/* TODO: Place low-power code here */
suspended = 0;
}
/******************************************************************************/
static int event_callback(maxusb_event_t evt, void *data)
{
/* Set event flag */
MXC_SETBIT(&event_flags, evt);
switch (evt) {
case MAXUSB_EVENT_NOVBUS:
usb_event_disable(MAXUSB_EVENT_BRST);
usb_event_disable(MAXUSB_EVENT_SUSP);
usb_event_disable(MAXUSB_EVENT_DPACT);
usb_disconnect();
configured = 0;
enum_clearconfig();
msc_deconfigure();
usb_app_sleep();
break;
case MAXUSB_EVENT_VBUS:
usb_event_clear(MAXUSB_EVENT_BRST);
usb_event_enable(MAXUSB_EVENT_BRST, event_callback, NULL);
usb_event_clear(MAXUSB_EVENT_SUSP);
usb_event_enable(MAXUSB_EVENT_SUSP, event_callback, NULL);
usb_connect();
usb_app_sleep();
break;
case MAXUSB_EVENT_BRST:
usb_app_wakeup();
enum_clearconfig();
msc_deconfigure();
configured = 0;
suspended = 0;
break;
case MAXUSB_EVENT_SUSP: