add a factory test for metro m7
This commit is contained in:
parent
07ea898bf8
commit
f57642d673
6 changed files with 745 additions and 0 deletions
22
ports/mimxrt10xx/apps/factory_test/Makefile
Normal file
22
ports/mimxrt10xx/apps/factory_test/Makefile
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
OUTNAME = factory_test-$(BOARD)
|
||||
|
||||
SRC_C += \
|
||||
$(PORT_DIR)/boards.c \
|
||||
$(CURRENT_PATH)/main.c \
|
||||
$(CURRENT_PATH)/arduino.c \
|
||||
$(CURRENT_PATH)/usb_descriptors.c \
|
||||
|
||||
INC += \
|
||||
$(TOP)/$(CURRENT_PATH) \
|
||||
$(TOP)/src
|
||||
|
||||
ifeq ($(BOARD),metro_m7_1011)
|
||||
include ../app.mk
|
||||
|
||||
else
|
||||
|
||||
all:
|
||||
@echo This board does not have ESP32 co-processor
|
||||
|
||||
endif
|
||||
|
||||
139
ports/mimxrt10xx/apps/factory_test/arduino.c
Normal file
139
ports/mimxrt10xx/apps/factory_test/arduino.c
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#include "arduino.h"
|
||||
|
||||
pinmap pinmapping[] = {
|
||||
{.num=0, .port=GPIO1, .pin=9, .mux={IOMUXC_GPIO_09_GPIOMUX_IO09}},
|
||||
{.num=1, .port=GPIO1, .pin=10, .mux={IOMUXC_GPIO_10_GPIOMUX_IO10}},
|
||||
{.num=2, .port=GPIO1, .pin=13, .mux={IOMUXC_GPIO_13_GPIOMUX_IO13}},
|
||||
{.num=3, .port=GPIO1, .pin=12, .mux={IOMUXC_GPIO_12_GPIOMUX_IO12}},
|
||||
|
||||
{.num=4, .port=GPIO2, .pin=0, .mux={IOMUXC_GPIO_SD_00_GPIO2_IO00}},
|
||||
{.num=5, .port=GPIO2, .pin=1, .mux={IOMUXC_GPIO_SD_01_GPIO2_IO01}},
|
||||
{.num=6, .port=GPIO2, .pin=2, .mux={IOMUXC_GPIO_SD_02_GPIO2_IO02}},
|
||||
{.num=7, .port=GPIO1, .pin=11, .mux={IOMUXC_GPIO_11_GPIOMUX_IO11}},
|
||||
|
||||
{.num=8, .port=GPIO1, .pin=8, .mux={IOMUXC_GPIO_08_GPIOMUX_IO08}},
|
||||
{.num=9, .port=GPIO1, .pin=7, .mux={IOMUXC_GPIO_07_GPIOMUX_IO07}},
|
||||
{.num=10, .port=GPIO1, .pin=6, .mux={IOMUXC_GPIO_06_GPIOMUX_IO06}},
|
||||
{.num=11, .port=GPIO1, .pin=5, .mux={IOMUXC_GPIO_05_GPIOMUX_IO05}},
|
||||
{.num=12, .port=GPIO1, .pin=4, .mux={IOMUXC_GPIO_04_GPIOMUX_IO04}},
|
||||
{.num=13, .port=GPIO1, .pin=3, .mux={IOMUXC_GPIO_03_GPIOMUX_IO03}},
|
||||
|
||||
{.num=14, .port=GPIO1, .pin=16, .mux={IOMUXC_GPIO_AD_02_GPIOMUX_IO16}, .adc=ADC1}, // AD0
|
||||
{.num=15, .port=GPIO1, .pin=15, .mux={IOMUXC_GPIO_AD_01_GPIOMUX_IO15}, .adc=ADC1}, // AD1
|
||||
{.num=16, .port=GPIO1, .pin=14, .mux={IOMUXC_GPIO_AD_00_GPIOMUX_IO14}, .adc=ADC1}, // AD2
|
||||
{.num=17, .port=GPIO1, .pin=19, .mux={IOMUXC_GPIO_AD_05_GPIOMUX_IO19}, .adc=ADC1}, // AD3
|
||||
{.num=18, .port=GPIO1, .pin=24, .mux={IOMUXC_GPIO_AD_10_GPIOMUX_IO24}, .adc=ADC1}, // AD4
|
||||
{.num=19, .port=GPIO1, .pin=22, .mux={IOMUXC_GPIO_AD_08_GPIOMUX_IO22}, .adc=ADC1}, // AD5
|
||||
|
||||
{.num=PIN_SDA, .port=GPIO1, .pin=1, .mux={IOMUXC_GPIO_01_GPIOMUX_IO01}},
|
||||
{.num=PIN_SCL, .port=GPIO1, .pin=2, .mux={IOMUXC_GPIO_02_GPIOMUX_IO02}},
|
||||
};
|
||||
|
||||
static volatile uint32_t _millis = 0;
|
||||
|
||||
void Serial_printf(const char format[], ...) {
|
||||
char buf[256];
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(buf, sizeof(buf), format, ap);
|
||||
tud_cdc_write(buf, strlen(buf));
|
||||
va_end(ap);
|
||||
tud_cdc_write_flush();
|
||||
}
|
||||
|
||||
|
||||
void board_timer_handler(void) {
|
||||
_millis++;
|
||||
}
|
||||
|
||||
uint32_t millis(void) {
|
||||
return _millis;
|
||||
}
|
||||
|
||||
void delay(uint32_t ms) {
|
||||
board_timer_start(1);
|
||||
uint32_t timestamp = millis();
|
||||
while ((timestamp+ms) > millis()) {
|
||||
// Serial_printf("delay %d\n\r", millis());
|
||||
tud_task();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static pinmap *getMapping(uint32_t pinnum) {
|
||||
pinmap *pindeets = NULL;
|
||||
|
||||
for (uint32_t i=0; i<sizeof(pinmapping) / sizeof(pinmap); i++) {
|
||||
pindeets = &pinmapping[i];
|
||||
//Serial_printf("pin %d -> port %x, pin %d\n\r", pindeets->num, pindeets->port, pindeets->pin);
|
||||
if (pinnum == pindeets->num) {
|
||||
//Serial_printf("found!\n\r");
|
||||
return pindeets;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void digitalWrite(uint32_t pinnum, bool value) {
|
||||
pinmap *pindeets = getMapping(pinnum);
|
||||
if (! pindeets) return;
|
||||
|
||||
GPIO_PinWrite(pindeets->port, pindeets->pin, value);
|
||||
}
|
||||
|
||||
bool digitalRead(uint32_t pinnum) {
|
||||
pinmap *pindeets = getMapping(pinnum);
|
||||
if (! pindeets) return 0;
|
||||
|
||||
|
||||
return GPIO_PinRead(pindeets->port, pindeets->pin);
|
||||
}
|
||||
|
||||
void pinMode(uint32_t pinnum, uint8_t state) {
|
||||
pinmap *pindeets = getMapping(pinnum);
|
||||
if (! pindeets) return;
|
||||
|
||||
IOMUXC_SetPinMux(pindeets->mux.muxReg, pindeets->mux.muxMode,
|
||||
pindeets->mux.inputReg, pindeets->mux.idaisy,
|
||||
pindeets->mux.configReg, 0U);
|
||||
IOMUXC_SetPinConfig(pindeets->mux.muxReg, pindeets->mux.muxMode,
|
||||
pindeets->mux.inputReg, pindeets->mux.idaisy,
|
||||
pindeets->mux.configReg, 0x10B0U);
|
||||
|
||||
if (state == OUTPUT) {
|
||||
gpio_pin_config_t pin_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode };
|
||||
GPIO_PinInit(pindeets->port, pindeets->pin, &pin_config);
|
||||
} else {
|
||||
gpio_pin_config_t pin_config = { kGPIO_DigitalInput, 0, kGPIO_NoIntmode };
|
||||
GPIO_PinInit(pindeets->port, pindeets->pin, &pin_config);
|
||||
|
||||
if (state == INPUT_PULLUP) {
|
||||
IOMUXC_SetPinConfig(pindeets->mux.muxReg, pindeets->mux.muxMode,
|
||||
pindeets->mux.inputReg, pindeets->mux.idaisy,
|
||||
pindeets->mux.configReg, 0xB0B0U);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t analogRead(uint32_t pinnum) {
|
||||
pinmap *pindeets = getMapping(pinnum);
|
||||
if (! pindeets) return -1;
|
||||
if (! pindeets->adc) return -1;
|
||||
/*
|
||||
adc_config_t config = {0};
|
||||
|
||||
ADC_GetDefaultConfig(&config);
|
||||
|
||||
config.enableLongSample = true;
|
||||
config.samplePeriodMode = kADC_SamplePeriod8or24Clocks;
|
||||
|
||||
ADC_Init(pindeets->adc, &config);
|
||||
ADC_SetHardwareAverageConfig(pindeets->adc, kADC_HardwareAverageCount32);
|
||||
ADC_DoAutoCalibration(pindeets->adc);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
57
ports/mimxrt10xx/apps/factory_test/arduino.h
Normal file
57
ports/mimxrt10xx/apps/factory_test/arduino.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
#include "fsl_lpuart.h"
|
||||
//#include "fsl_adc12.h"
|
||||
|
||||
#include "board_api.h"
|
||||
#include "tusb.h"
|
||||
|
||||
#define INPUT 0
|
||||
#define OUTPUT 1
|
||||
#define INPUT_PULLUP 2
|
||||
#define LOW 0
|
||||
#define HIGH 1
|
||||
|
||||
|
||||
#define PIN_SDA 30
|
||||
#define PIN_SCL 31
|
||||
#define PIN_MOSI 32
|
||||
#define PIN_MISO 33
|
||||
#define PIN_SCK 34
|
||||
#define AD0 14
|
||||
#define AD1 15
|
||||
#define AD2 16
|
||||
#define AD3 17
|
||||
#define AD4 18
|
||||
#define AD5 19
|
||||
|
||||
|
||||
typedef struct _pinmux {
|
||||
uint32_t muxReg;
|
||||
uint8_t muxMode;
|
||||
uint8_t inputReg;
|
||||
uint8_t idaisy;
|
||||
uint32_t configReg;
|
||||
} pinmux;
|
||||
|
||||
typedef struct _pinmapping {
|
||||
uint8_t num;
|
||||
GPIO_Type *port;
|
||||
uint32_t pin;
|
||||
pinmux mux;
|
||||
ADC_Type *adc;
|
||||
} pinmap;
|
||||
|
||||
void Serial_printf(const char format[], ...) __attribute__ ((format (printf, 1, 0)));
|
||||
uint32_t millis(void);
|
||||
void delay(uint32_t ms);
|
||||
void digitalWrite(uint32_t pinnum, bool value);
|
||||
bool digitalRead(uint32_t pinnum);
|
||||
void pinMode(uint32_t pinnum, uint8_t state);
|
||||
243
ports/mimxrt10xx/apps/factory_test/main.c
Normal file
243
ports/mimxrt10xx/apps/factory_test/main.c
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Ha Thach (tinyusb.org) for Adafruit Industries
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
#include "fsl_lpuart.h"
|
||||
|
||||
#include "board_api.h"
|
||||
#include "tusb.h"
|
||||
#include "arduino.h"
|
||||
|
||||
uint8_t all_pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, PIN_SDA, PIN_SCL};
|
||||
|
||||
bool testpins(uint8_t a, uint8_t b, uint8_t *allpins, uint8_t num_allpins);
|
||||
|
||||
/* This is an application to test Metro M7
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// optional API, not included in board_api.h
|
||||
int board_uart_read(uint8_t* buf, int len);
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
board_uart_init(115200);
|
||||
|
||||
board_timer_start(1);
|
||||
|
||||
board_usb_init();
|
||||
tusb_init();
|
||||
|
||||
uint8_t rgb[3] = { 20, 20, 0 };
|
||||
board_rgb_write(rgb);
|
||||
|
||||
pinMode(13, OUTPUT);
|
||||
|
||||
while(1)
|
||||
{
|
||||
Serial_printf("\n\r\n\rHello Metro M7 iMX RT1011 Test! %d\n\r", millis());
|
||||
digitalWrite(13, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(13, LOW);
|
||||
|
||||
if ( !testpins(0, 2, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(1, 3, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(4, 6, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(5, 7, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(8, 10, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(9, 11, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(12, PIN_SDA, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(13, PIN_SCL, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(PIN_MOSI, PIN_MISO, all_pins, sizeof(all_pins))) continue;
|
||||
if ( !testpins(PIN_SCK, AD5, all_pins, sizeof(all_pins))) continue;
|
||||
|
||||
Serial_printf("*** TEST OK! ***\n\r");
|
||||
delay(100);
|
||||
|
||||
|
||||
/*
|
||||
// USB -> UART
|
||||
while( tud_cdc_available() )
|
||||
{
|
||||
count = tud_cdc_read(serial_buf, sizeof(serial_buf));
|
||||
board_uart_write(serial_buf, count);
|
||||
|
||||
uint8_t rgb[3] = { 10, 0, 0 };
|
||||
board_rgb_write(rgb);
|
||||
}
|
||||
|
||||
// UART -> USB
|
||||
count = board_uart_read(serial_buf, sizeof(serial_buf));
|
||||
if (count)
|
||||
{
|
||||
tud_cdc_write(serial_buf, count);
|
||||
tud_cdc_write_flush();
|
||||
|
||||
uint8_t rgb[3] = { 0, 0, 10 };
|
||||
board_rgb_write(rgb);
|
||||
}
|
||||
*/
|
||||
tud_task();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Logger newlib retarget
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Enable only with LOG is enabled (Note: ESP32-S2 has built-in support already)
|
||||
#if TUF2_LOG // && (CFG_TUSB_MCU != OPT_MCU_ESP32S2)
|
||||
|
||||
#if defined(LOGGER_RTT)
|
||||
#include "SEGGER_RTT.h"
|
||||
#endif
|
||||
|
||||
__attribute__ ((used)) int _write (int fhdl, const void *buf, size_t count)
|
||||
{
|
||||
(void) fhdl;
|
||||
|
||||
#if defined(LOGGER_RTT)
|
||||
SEGGER_RTT_Write(0, (char*) buf, (int) count);
|
||||
return count;
|
||||
#else
|
||||
return board_uart_write(buf, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool testpins(uint8_t a, uint8_t b, uint8_t *allpins, uint8_t num_allpins) {
|
||||
bool ok = false;
|
||||
|
||||
Serial_printf("\tTesting %d and %d\n\r", a, b);
|
||||
|
||||
// set both to inputs
|
||||
pinMode(b, INPUT);
|
||||
// turn on 'a' pullup
|
||||
pinMode(a, INPUT_PULLUP);
|
||||
delay(1);
|
||||
|
||||
// verify neither are grounded
|
||||
if (!digitalRead(a) || !digitalRead(b)) {
|
||||
Serial_printf("Ground test 1 fail: both pins should not be grounded");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int retry=0; retry<3 && !ok; retry++) {
|
||||
// turn off both pullups
|
||||
pinMode(a, INPUT);
|
||||
pinMode(b, INPUT);
|
||||
|
||||
// make a an output
|
||||
pinMode(a, OUTPUT);
|
||||
digitalWrite(a, LOW);
|
||||
delay(1);
|
||||
|
||||
int ar = digitalRead(a);
|
||||
int br = digitalRead(b);
|
||||
delay(5);
|
||||
|
||||
// make sure both are low
|
||||
if (ar || br) {
|
||||
Serial_printf("Low test fail on pin #");
|
||||
if (ar) Serial_printf("%d\n\r", a);
|
||||
if (br) Serial_printf("%d\n\r", b);
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
ok = true;
|
||||
}
|
||||
if (!ok) return false;
|
||||
|
||||
ok = false;
|
||||
for (int retry=0; retry<3 && !ok; retry++) {
|
||||
//theSerial->println("OK!");
|
||||
// a is an input, b is an output
|
||||
pinMode(a, INPUT);
|
||||
pinMode(b, OUTPUT);
|
||||
digitalWrite(b, HIGH);
|
||||
delay(10);
|
||||
|
||||
// verify neither are grounded
|
||||
if (!digitalRead(a)|| !digitalRead(b)) {
|
||||
Serial_printf("Ground test 2 fail: both pins should not be grounded");
|
||||
delay(100);
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
ok = true;
|
||||
}
|
||||
if (!ok) return false;
|
||||
|
||||
// make sure no pins are shorted to pin a or b
|
||||
for (uint8_t i = 0; i < num_allpins; i++) {
|
||||
pinMode(allpins[i], INPUT_PULLUP);
|
||||
}
|
||||
|
||||
pinMode(a, OUTPUT);
|
||||
digitalWrite(a, LOW);
|
||||
pinMode(b, OUTPUT);
|
||||
digitalWrite(b, LOW);
|
||||
delay(1);
|
||||
|
||||
for (uint8_t i = 0; i < num_allpins; i++) {
|
||||
if ((allpins[i] == a) || (allpins[i] == b)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// theSerial->print("Pin #"); theSerial->print(allpins[i]);
|
||||
// theSerial->print(" -> ");
|
||||
// theSerial->println(digitalRead(allpins[i]));
|
||||
if (!digitalRead(allpins[i])) {
|
||||
Serial_printf("%d is shorted?\n\r", allpins[i]);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pinMode(a, INPUT);
|
||||
pinMode(b, INPUT);
|
||||
|
||||
delay(10);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
89
ports/mimxrt10xx/apps/factory_test/tusb_config.h
Normal file
89
ports/mimxrt10xx/apps/factory_test/tusb_config.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// COMMON CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#error CFG_TUSB_MCU must be defined in board.mk
|
||||
#endif
|
||||
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
|
||||
// can be defined by compiler in DEBUG build
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||
* into those specific section.
|
||||
* e.g
|
||||
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||
*/
|
||||
#ifndef CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUSB_MEM_SECTION
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// DEVICE CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_CDC 1
|
||||
#define CFG_TUD_MSC 0
|
||||
#define CFG_TUD_HID 0
|
||||
#define CFG_TUD_MIDI 0
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
||||
// CDC FIFO size of TX and RX
|
||||
#define CFG_TUD_CDC_RX_BUFSIZE 1024
|
||||
#define CFG_TUD_CDC_TX_BUFSIZE 1024
|
||||
|
||||
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
||||
195
ports/mimxrt10xx/apps/factory_test/usb_descriptors.c
Normal file
195
ports/mimxrt10xx/apps/factory_test/usb_descriptors.c
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "board_api.h"
|
||||
#include "tusb.h"
|
||||
|
||||
// String Descriptor Index
|
||||
enum
|
||||
{
|
||||
STRID_LANGID = 0,
|
||||
STRID_MANUFACTURER,
|
||||
STRID_PRODUCT,
|
||||
STRID_SERIAL,
|
||||
STRID_CDC
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ITF_NUM_CDC,
|
||||
ITF_NUM_CDC_DATA,
|
||||
ITF_NUM_TOTAL
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Device Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_desc_device_t const desc_device =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
.bcdUSB = 0x0200,
|
||||
|
||||
// Use Interface Association Descriptor (IAD) for CDC
|
||||
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
|
||||
.bDeviceClass = TUSB_CLASS_MISC,
|
||||
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
|
||||
.idVendor = USB_VID,
|
||||
.idProduct = 0x8000 | USB_PID, // application PID
|
||||
.bcdDevice = 0x0100,
|
||||
|
||||
.iManufacturer = STRID_MANUFACTURER,
|
||||
.iProduct = STRID_PRODUCT,
|
||||
.iSerialNumber = STRID_SERIAL,
|
||||
|
||||
.bNumConfigurations = 0x01
|
||||
};
|
||||
|
||||
// Invoked when received GET DEVICE DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
uint8_t const * tud_descriptor_device_cb(void)
|
||||
{
|
||||
return (uint8_t const *) &desc_device;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Configuration Descriptor
|
||||
//--------------------------------------------------------------------+
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
|
||||
|
||||
#define EPNUM_CDC_NOTIF 0x81
|
||||
#define EPNUM_CDC_DATA 0x02
|
||||
|
||||
uint8_t const desc_fs_configuration[] =
|
||||
{
|
||||
// Config number, interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_DATA, 0x80 | EPNUM_CDC_DATA, 64)
|
||||
};
|
||||
|
||||
uint8_t const desc_hs_configuration[] =
|
||||
{
|
||||
// Config number, interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, STRID_CDC, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_DATA, 0x80 | EPNUM_CDC_DATA, 512)
|
||||
};
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
// Application return pointer to descriptor
|
||||
// Descriptor contents must exist long enough for transfer to complete
|
||||
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
||||
{
|
||||
(void) index; // for multiple configurations
|
||||
|
||||
// Although we are highspeed, host may be fullspeed.
|
||||
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// String Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Serial is 64-bit DeviceID -> 16 chars len
|
||||
static char desc_str_serial[1+16] = { 0 };
|
||||
|
||||
// array of pointer to string descriptors
|
||||
char const* string_desc_arr [] =
|
||||
{
|
||||
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
||||
USB_MANUFACTURER, // 1: Manufacturer
|
||||
USB_PRODUCT, // 2: Product
|
||||
desc_str_serial, // 3: Serials, use default MAC address
|
||||
"USB to UART", // 4: CDC Interface
|
||||
};
|
||||
|
||||
static uint16_t _desc_str[32+1];
|
||||
|
||||
// Invoked when received GET STRING DESCRIPTOR request
|
||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
|
||||
{
|
||||
(void) langid;
|
||||
|
||||
uint8_t chr_count;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case STRID_LANGID:
|
||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||
chr_count = 1;
|
||||
break;
|
||||
|
||||
case STRID_SERIAL:
|
||||
{
|
||||
uint8_t serial_id[16];
|
||||
uint8_t serial_len;
|
||||
|
||||
serial_len = board_usb_get_serial(serial_id);
|
||||
chr_count = 2*serial_len;
|
||||
|
||||
for ( uint8_t i = 0; i < serial_len; i++ )
|
||||
{
|
||||
for ( uint8_t j = 0; j < 2; j++ )
|
||||
{
|
||||
const char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
uint8_t nibble = (serial_id[i] >> (j * 4)) & 0xf;
|
||||
_desc_str[1 + i * 2 + (1 - j)] = nibble_to_hex[nibble]; // UTF-16-LE
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// Convert ASCII string into UTF-16
|
||||
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
|
||||
|
||||
const char* str = string_desc_arr[index];
|
||||
|
||||
// Cap at max char
|
||||
chr_count = strlen(str);
|
||||
if ( chr_count > 31 ) chr_count = 31;
|
||||
|
||||
for(uint8_t i=0; i<chr_count; i++)
|
||||
{
|
||||
_desc_str[1+i] = str[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// first byte is length (including header), second byte is string type
|
||||
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
|
||||
|
||||
return _desc_str;
|
||||
}
|
||||
Loading…
Reference in a new issue