forked from mirrors/qmk_userspace
Move USB Host Shield and Arduino core to lib/
(#13973)
This commit is contained in:
parent
cf5e40c251
commit
b16091659c
182 changed files with 6 additions and 6 deletions
|
@ -0,0 +1,64 @@
|
|||
#
|
||||
# These are set for a mega 1280 + quadram plus my serial patch.
|
||||
# If you lack quadram, or want to disable LFN, just change _FS_TINY=1 _USE_LFN=0
|
||||
#
|
||||
# If your board is a mega 2560 comment out the following two lines
|
||||
BOARD = mega
|
||||
|
||||
BOARD_SUB = mega.menu.cpu.atmega1280
|
||||
PROGRAMMER = arduino
|
||||
|
||||
# ...and then uncomment out the following two lines
|
||||
#BOARD_SUB = mega.menu.cpu.atmega2560
|
||||
#PROGRAMMER = wiring
|
||||
|
||||
#BOARD = teensypp2
|
||||
#BOARD = teensy3
|
||||
#BOARD = teensy31
|
||||
|
||||
# set your Arduino tty port here
|
||||
PORT = /dev/ttyUSB0
|
||||
|
||||
EXTRA_FLAGS = -D _USE_LFN=3
|
||||
|
||||
# change to 0 if you have quadram to take advantage of caching FAT
|
||||
EXTRA_FLAGS += -D _FS_TINY=1
|
||||
|
||||
|
||||
EXTRA_FLAGS += -D _MAX_SS=512
|
||||
|
||||
|
||||
# Don't worry if you don't have external RAM, xmem2 detects this situation.
|
||||
# You *WILL* be wanting to get some kind of external ram on your mega in order to
|
||||
# do anything that is intense.
|
||||
EXTRA_FLAGS += -D EXT_RAM_STACK=1
|
||||
EXTRA_FLAGS += -D EXT_RAM_HEAP=1
|
||||
|
||||
|
||||
# These are no longer needed for the demo to work.
|
||||
# In the event you need more ram, uncomment these 3 lines.
|
||||
#EXTRA_FLAGS += -D DISABLE_SERIAL1
|
||||
#EXTRA_FLAGS += -D DISABLE_SERIAL2
|
||||
#EXTRA_FLAGS += -D DISABLE_SERIAL3
|
||||
|
||||
#
|
||||
# Advanced debug on Serial3
|
||||
#
|
||||
|
||||
# uncomment the next two to enable debug on Serial3
|
||||
EXTRA_FLAGS += -D USB_HOST_SERIAL=Serial3
|
||||
#EXTRA_FLAGS += -D DEBUG_USB_HOST
|
||||
|
||||
# The following are the libraries used.
|
||||
LIB_DIRS += ../../
|
||||
LIB_DIRS += ../testusbhostFAT/xmem2
|
||||
LIB_DIRS += ../testusbhostFAT/generic_storage
|
||||
LIB_DIRS += ../testusbhostFAT/RTClib
|
||||
LIB_DIRS += $(ARD_HOME)/libraries/Wire
|
||||
LIB_DIRS += $(ARD_HOME)/libraries/Wire/utility
|
||||
LIB_DIRS += $(ARD_HOME)/hardware/arduino/$(BUILD_ARCH)/libraries/Wire
|
||||
LIB_DIRS += $(ARD_HOME)/hardware/arduino/$(BUILD_ARCH)/libraries/Wire/utility
|
||||
LIB_DIRS += $(ARD_HOME)/hardware/arduino/$(BUILD_ARCH)/libraries/SPI
|
||||
|
||||
# And finally, the part that brings everything together for you.
|
||||
include Arduino_Makefile_master/_Makefile.master
|
|
@ -0,0 +1,29 @@
|
|||
This small sketch tests the USB host shield mass storage library.
|
||||
|
||||
__Note:__ This will not run a Arduino Uno due to the limited ram available in the ATmega328p.
|
||||
|
||||
The Arduino Mega (ATmega1280) and the Arduino Mega 2560 (ATmega2560) are confirmed to work with this test code.
|
||||
|
||||
To compile this example you will need the following libraries as well:
|
||||
|
||||
* [xmem2](https://github.com/xxxajk/xmem2)
|
||||
* [generic_storage FATfs](https://github.com/xxxajk/generic_storage)
|
||||
* [RTClib](https://github.com/xxxajk/RTClib)
|
||||
|
||||
The following shield is recommended for larger projects: <https://www.rugged-circuits.com/new-products/quadram>.
|
||||
|
||||
You may use the bundled [Makefile](Makefile) to compile the code instead of the Arduino IDE if you have problems or want a smaller binary. The master makefile is bundled as a submodule, but can also be downloaded manually at the following link: <https://github.com/xxxajk/Arduino_Makefile_master>.
|
||||
|
||||
To download the USB Host library and all the needed libraries for this test.
|
||||
|
||||
Run the following command in a terminal application:
|
||||
|
||||
```
|
||||
git clone --recursive https://github.com/felis/USB_Host_Shield_2.0
|
||||
```
|
||||
|
||||
If you want to update all the submodules run:
|
||||
|
||||
```
|
||||
git submodule foreach --recursive git pull origin master
|
||||
```
|
|
@ -0,0 +1,736 @@
|
|||
/*
|
||||
* Mega + USB storage + optional DS1307 + optional expansion RAM + funky status LED,
|
||||
* Includes interactive debug level setting, and supports hot-plug.
|
||||
*
|
||||
* IMPORTANT! PLEASE USE Arduino 1.0.5 or better!
|
||||
* Older versions HAVE MAJOR BUGS AND WILL NOT WORK AT ALL!
|
||||
* Use of gcc-avr and lib-c that is newer than the Arduino version is even better.
|
||||
* If you experience random crashes, use make.
|
||||
* The options that the IDE use can generate bad code and cause the AVR to crash.
|
||||
*
|
||||
* This sketch requires the following libraries:
|
||||
* https://github.com/felis/USB_Host_Shield_2.0 Install as 'USB_Host_Shield_2_0'
|
||||
* https://github.com/xxxajk/xmem2 Install as 'xmem', provides memory services.
|
||||
* https://github.com/xxxajk/generic_storage provides access to FAT file system.
|
||||
* https://github.com/xxxajk/RTClib provides access to DS1307, or fake clock.
|
||||
*
|
||||
* Optional, to use the Makefile (Recommended! See above!):
|
||||
* https://github.com/xxxajk/Arduino_Makefile_master
|
||||
*
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Please Note: //
|
||||
// This section is for info with the Arduino IDE ONLY. //
|
||||
// Unfortunately due to short sightedness of the Arduino //
|
||||
// code team, that you must set the following in the //
|
||||
// respective libraries. //
|
||||
// Changing them here will have _NO_ effect! //
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
// Uncomment to enable debugging
|
||||
//#define DEBUG_USB_HOST
|
||||
// This is where stderr/USB debugging goes to
|
||||
//#define USB_HOST_SERIAL Serial3
|
||||
|
||||
// If you have external memory, setting this to 0 enables FAT table caches.
|
||||
// The 0 setting is recommended only if you have external memory.
|
||||
//#define _FS_TINY 1
|
||||
|
||||
//#define _USE_LFN 3
|
||||
//#define _MAX_SS 512
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// End of Arduino IDE specific information //
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
// You can set this to 0 if you are not using a USB hub.
|
||||
// It will save a little bit of flash and RAM.
|
||||
// Set to 1 if you want to use a hub.
|
||||
#define WANT_HUB_TEST 1
|
||||
|
||||
// this is for XMEM2
|
||||
#define EXT_RAM_STACK 1
|
||||
#define EXT_RAM_HEAP 1
|
||||
#define LOAD_XMEM
|
||||
|
||||
#if defined(CORE_TEENSY) && !defined(_AVR_)
|
||||
#include <xmem.h>
|
||||
#include <spi4teensy3.h>
|
||||
#endif
|
||||
|
||||
#if defined(__AVR__)
|
||||
#include <xmem.h>
|
||||
#include <SPI.h>
|
||||
#elif defined(ARDUINO_ARCH_SAM)
|
||||
#include <SPI.h>
|
||||
#endif
|
||||
|
||||
#if WANT_HUB_TEST
|
||||
#include <usbhub.h>
|
||||
#endif
|
||||
#include <Wire.h>
|
||||
#define LOAD_RTCLIB
|
||||
#include <RTClib.h>
|
||||
#include <masstorage.h>
|
||||
#include <Storage.h>
|
||||
#include <PCpartition/PCPartition.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <FAT/FAT.h>
|
||||
#include <stdio.h>
|
||||
#if defined(__AVR__)
|
||||
static FILE tty_stdio;
|
||||
static FILE tty_stderr;
|
||||
volatile uint32_t LEDnext_time; // fade timeout
|
||||
volatile uint32_t HEAPnext_time; // when to print out next heap report
|
||||
volatile int brightness = 0; // how bright the LED is
|
||||
volatile int fadeAmount = 80; // how many points to fade the LED by
|
||||
#endif
|
||||
|
||||
USB Usb;
|
||||
|
||||
volatile uint8_t current_state = 1;
|
||||
volatile uint8_t last_state = 0;
|
||||
volatile bool fatready = false;
|
||||
volatile bool partsready = false;
|
||||
volatile bool notified = false;
|
||||
volatile bool runtest = false;
|
||||
volatile bool usbon = false;
|
||||
volatile uint32_t usbon_time;
|
||||
volatile bool change = false;
|
||||
volatile bool reportlvl = false;
|
||||
int cpart = 0;
|
||||
PCPartition *PT;
|
||||
|
||||
#if WANT_HUB_TEST
|
||||
#define MAX_HUBS 1
|
||||
USBHub *Hubs[MAX_HUBS];
|
||||
#endif
|
||||
|
||||
static PFAT *Fats[_VOLUMES];
|
||||
static part_t parts[_VOLUMES];
|
||||
static storage_t sto[_VOLUMES];
|
||||
|
||||
/*make sure this is a power of two. */
|
||||
#define mbxs 128
|
||||
static uint8_t My_Buff_x[mbxs]; /* File read buffer */
|
||||
|
||||
#if defined(__AVR__)
|
||||
|
||||
#define prescale1 ((1 << WGM12) | (1 << CS10))
|
||||
#define prescale8 ((1 << WGM12) | (1 << CS11))
|
||||
#define prescale64 ((1 << WGM12) | (1 << CS10) | (1 << CS11))
|
||||
#define prescale256 ((1 << WGM12) | (1 << CS12))
|
||||
#define prescale1024 ((1 << WGM12) | (1 << CS12) | (1 << CS10))
|
||||
|
||||
extern "C" {
|
||||
extern unsigned int freeHeap();
|
||||
}
|
||||
static int tty_stderr_putc(char c, FILE *t) {
|
||||
USB_HOST_SERIAL.write(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __attribute__((unused)) tty_stderr_flush(FILE *t) {
|
||||
USB_HOST_SERIAL.flush();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tty_std_putc(char c, FILE *t) {
|
||||
Serial.write(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tty_std_getc(FILE *t) {
|
||||
while(!Serial.available());
|
||||
return Serial.read();
|
||||
}
|
||||
|
||||
static int __attribute__((unused)) tty_std_flush(FILE *t) {
|
||||
Serial.flush();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
// Supposedly the DUE has stdio already pointing to serial...
|
||||
#if !defined(ARDUINO_ARCH_SAM)
|
||||
// But newlib needs this...
|
||||
extern "C" {
|
||||
int _write(int fd, const char *ptr, int len) {
|
||||
int j;
|
||||
for(j = 0; j < len; j++) {
|
||||
if(fd == 1)
|
||||
Serial.write(*ptr++);
|
||||
else if(fd == 2)
|
||||
USB_HOST_SERIAL.write(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int _read(int fd, char *ptr, int len) {
|
||||
if(len > 0 && fd == 0) {
|
||||
while(!Serial.available());
|
||||
*ptr = Serial.read();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
int _fstat(int fd, struct stat *st) {
|
||||
memset(st, 0, sizeof (*st));
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_blksize = 1024;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int fd) {
|
||||
return (fd < 3) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
#endif // !defined(ARDUINO_ARCH_SAM)
|
||||
#endif
|
||||
|
||||
void setup() {
|
||||
bool serr = false;
|
||||
for(int i = 0; i < _VOLUMES; i++) {
|
||||
Fats[i] = NULL;
|
||||
sto[i].private_data = new pvt_t;
|
||||
((pvt_t *)sto[i].private_data)->B = 255; // impossible
|
||||
}
|
||||
// Set this to higher values to enable more debug information
|
||||
// minimum 0x00, maximum 0xff
|
||||
UsbDEBUGlvl = 0x81;
|
||||
|
||||
#if !defined(CORE_TEENSY) && defined(__AVR__)
|
||||
// make LED pin as an output:
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
pinMode(2, OUTPUT);
|
||||
// Ensure TX is off
|
||||
_SFR_BYTE(UCSR0B) &= ~_BV(TXEN0);
|
||||
// Initialize 'debug' serial port
|
||||
USB_HOST_SERIAL.begin(115200);
|
||||
// Do not start primary Serial port if already started.
|
||||
if(bit_is_clear(UCSR0B, TXEN0)) {
|
||||
Serial.begin(115200);
|
||||
serr = true;
|
||||
}
|
||||
|
||||
|
||||
// Blink LED
|
||||
delay(500);
|
||||
analogWrite(LED_BUILTIN, 255);
|
||||
delay(500);
|
||||
analogWrite(LED_BUILTIN, 0);
|
||||
delay(500);
|
||||
#else
|
||||
while(!Serial);
|
||||
Serial.begin(115200); // On the Teensy 3.x we get a delay at least!
|
||||
#endif
|
||||
#if defined(__AVR__)
|
||||
// Set up stdio/stderr
|
||||
tty_stdio.put = tty_std_putc;
|
||||
tty_stdio.get = tty_std_getc;
|
||||
tty_stdio.flags = _FDEV_SETUP_RW;
|
||||
tty_stdio.udata = 0;
|
||||
|
||||
tty_stderr.put = tty_stderr_putc;
|
||||
tty_stderr.get = NULL;
|
||||
tty_stderr.flags = _FDEV_SETUP_WRITE;
|
||||
tty_stderr.udata = 0;
|
||||
|
||||
stdout = &tty_stdio;
|
||||
stdin = &tty_stdio;
|
||||
stderr = &tty_stderr;
|
||||
#endif
|
||||
printf_P(PSTR("\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nStart\r\n"));
|
||||
printf_P(PSTR("Current UsbDEBUGlvl %02x\r\n"), UsbDEBUGlvl);
|
||||
printf_P(PSTR("'+' and '-' increase/decrease by 0x01\r\n"));
|
||||
printf_P(PSTR("'.' and ',' increase/decrease by 0x10\r\n"));
|
||||
printf_P(PSTR("'t' will run a 10MB write/read test and print out the time it took.\r\n"));
|
||||
printf_P(PSTR("'e' will toggle vbus off for a few moments.\r\n\r\n"));
|
||||
printf_P(PSTR("Long filename support: "
|
||||
#if _USE_LFN
|
||||
"Enabled"
|
||||
#else
|
||||
"Disabled"
|
||||
#endif
|
||||
"\r\n"));
|
||||
if(serr) {
|
||||
fprintf_P(stderr, PSTR("\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nStart\r\n"));
|
||||
fprintf_P(stderr, PSTR("Current UsbDEBUGlvl %02x\r\n"), UsbDEBUGlvl);
|
||||
fprintf_P(stderr, PSTR("Long filename support: "
|
||||
#if _USE_LFN
|
||||
"Enabled"
|
||||
#else
|
||||
"Disabled"
|
||||
#endif
|
||||
"\r\n"));
|
||||
}
|
||||
|
||||
#if !defined(CORE_TEENSY) && defined(__AVR__)
|
||||
analogWrite(LED_BUILTIN, 255);
|
||||
delay(500);
|
||||
analogWrite(LED_BUILTIN, 0);
|
||||
delay(500);
|
||||
analogWrite(LED_BUILTIN, 255);
|
||||
delay(500);
|
||||
analogWrite(LED_BUILTIN, 0);
|
||||
delay(500);
|
||||
analogWrite(LED_BUILTIN, 255);
|
||||
delay(500);
|
||||
analogWrite(LED_BUILTIN, 0);
|
||||
delay(500);
|
||||
|
||||
LEDnext_time = millis() + 1;
|
||||
#if EXT_RAM
|
||||
printf_P(PSTR("Total EXT RAM banks %i\r\n"), xmem::getTotalBanks());
|
||||
#endif
|
||||
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
||||
printf_P(PSTR("SP %x\r\n"), (uint8_t *)(SP));
|
||||
#endif
|
||||
|
||||
// Even though I'm not going to actually be deleting,
|
||||
// I want to be able to have slightly more control.
|
||||
// Besides, it is easier to initialize stuff...
|
||||
#if WANT_HUB_TEST
|
||||
for(int i = 0; i < MAX_HUBS; i++) {
|
||||
Hubs[i] = new USBHub(&Usb);
|
||||
#if defined(__AVR__)
|
||||
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
// Initialize generic storage. This must be done before USB starts.
|
||||
Init_Generic_Storage();
|
||||
|
||||
while(Usb.Init(1000) == -1) {
|
||||
printf_P(PSTR("No USB HOST Shield?\r\n"));
|
||||
Notify(PSTR("OSC did not start."), 0x40);
|
||||
}
|
||||
|
||||
#if !defined(CORE_TEENSY) && defined(__AVR__)
|
||||
cli();
|
||||
TCCR3A = 0;
|
||||
TCCR3B = 0;
|
||||
// (0.01/(1/((16 *(10^6)) / 8))) - 1 = 19999
|
||||
OCR3A = 19999;
|
||||
TCCR3B |= prescale8;
|
||||
TIMSK3 |= (1 << OCIE1A);
|
||||
sei();
|
||||
|
||||
HEAPnext_time = millis() + 10000;
|
||||
#endif
|
||||
#if defined(__AVR__)
|
||||
HEAPnext_time = millis() + 10000;
|
||||
#endif
|
||||
}
|
||||
|
||||
void serialEvent() {
|
||||
// Adjust UsbDEBUGlvl level on-the-fly.
|
||||
// + to increase, - to decrease, * to display current level.
|
||||
// . to increase by 16, , to decrease by 16
|
||||
// e to flick VBUS
|
||||
// * to report debug level
|
||||
if(Serial.available()) {
|
||||
int inByte = Serial.read();
|
||||
switch(inByte) {
|
||||
case '+':
|
||||
if(UsbDEBUGlvl < 0xff) UsbDEBUGlvl++;
|
||||
reportlvl = true;
|
||||
break;
|
||||
case '-':
|
||||
if(UsbDEBUGlvl > 0x00) UsbDEBUGlvl--;
|
||||
reportlvl = true;
|
||||
break;
|
||||
case '.':
|
||||
if(UsbDEBUGlvl < 0xf0) UsbDEBUGlvl += 16;
|
||||
reportlvl = true;
|
||||
break;
|
||||
case ',':
|
||||
if(UsbDEBUGlvl > 0x0f) UsbDEBUGlvl -= 16;
|
||||
reportlvl = true;
|
||||
break;
|
||||
case '*':
|
||||
reportlvl = true;
|
||||
break;
|
||||
case 't':
|
||||
runtest = true;
|
||||
break;
|
||||
case 'e':
|
||||
change = true;
|
||||
usbon = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CORE_TEENSY) && defined(__AVR__)
|
||||
// ALL teensy versions LACK PWM ON LED
|
||||
|
||||
ISR(TIMER3_COMPA_vect) {
|
||||
if((long)(millis() - LEDnext_time) >= 0L) {
|
||||
LEDnext_time = millis() + 30;
|
||||
|
||||
// set the brightness of LED
|
||||
analogWrite(LED_BUILTIN, brightness);
|
||||
|
||||
// change the brightness for next time through the loop:
|
||||
brightness = brightness + fadeAmount;
|
||||
|
||||
// reverse the direction of the fading at the ends of the fade:
|
||||
if(brightness <= 0) {
|
||||
brightness = 0;
|
||||
fadeAmount = -fadeAmount;
|
||||
}
|
||||
if(brightness >= 255) {
|
||||
brightness = 255;
|
||||
fadeAmount = -fadeAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isfat(uint8_t t) {
|
||||
return (t == 0x01 || t == 0x04 || t == 0x06 || t == 0x0b || t == 0x0c || t == 0x0e || t == 0x1);
|
||||
}
|
||||
|
||||
void die(FRESULT rc) {
|
||||
printf_P(PSTR("Failed with rc=%u.\r\n"), rc);
|
||||
//for (;;);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
FIL My_File_Object_x; /* File object */
|
||||
|
||||
#if defined(__AVR__)
|
||||
// Print a heap status report about every 10 seconds.
|
||||
if((long)(millis() - HEAPnext_time) >= 0L) {
|
||||
if(UsbDEBUGlvl > 0x50) {
|
||||
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
||||
}
|
||||
HEAPnext_time = millis() + 10000;
|
||||
}
|
||||
TCCR3B = 0;
|
||||
#endif
|
||||
#if defined(CORE_TEENSY)
|
||||
// Teensy suffers here, oh well...
|
||||
serialEvent();
|
||||
#endif
|
||||
// Horrid! This sort of thing really belongs in an ISR, not here!
|
||||
// We also will be needing to test each hub port, we don't do this yet!
|
||||
if(!change && !usbon && (long)(millis() - usbon_time) >= 0L) {
|
||||
change = true;
|
||||
usbon = true;
|
||||
}
|
||||
|
||||
if(change) {
|
||||
change = false;
|
||||
if(usbon) {
|
||||
Usb.vbusPower(vbus_on);
|
||||
printf_P(PSTR("VBUS on\r\n"));
|
||||
} else {
|
||||
Usb.vbusPower(vbus_off);
|
||||
usbon_time = millis() + 2000;
|
||||
}
|
||||
}
|
||||
Usb.Task();
|
||||
current_state = Usb.getUsbTaskState();
|
||||
if(current_state != last_state) {
|
||||
if(UsbDEBUGlvl > 0x50)
|
||||
printf_P(PSTR("USB state = %x\r\n"), current_state);
|
||||
#if !defined(CORE_TEENSY) && defined(__AVR__)
|
||||
if(current_state == USB_STATE_RUNNING) {
|
||||
fadeAmount = 30;
|
||||
}
|
||||
#endif
|
||||
if(current_state == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
|
||||
#if !defined(CORE_TEENSY) && defined(__AVR__)
|
||||
fadeAmount = 80;
|
||||
#endif
|
||||
partsready = false;
|
||||
for(int i = 0; i < cpart; i++) {
|
||||
if(Fats[i] != NULL)
|
||||
delete Fats[i];
|
||||
Fats[i] = NULL;
|
||||
}
|
||||
fatready = false;
|
||||
notified = false;
|
||||
cpart = 0;
|
||||
}
|
||||
last_state = current_state;
|
||||
}
|
||||
|
||||
// only do any of this if usb is on
|
||||
if(usbon) {
|
||||
if(partsready && !fatready) {
|
||||
if(cpart > 0) fatready = true;
|
||||
}
|
||||
// This is horrible, and needs to be moved elsewhere!
|
||||
for(int B = 0; B < MAX_USB_MS_DRIVERS; B++) {
|
||||
if((!partsready) && (UHS_USB_BulkOnly[B]->GetAddress())) {
|
||||
|
||||
// Build a list.
|
||||
int ML = UHS_USB_BulkOnly[B]->GetbMaxLUN();
|
||||
//printf("MAXLUN = %i\r\n", ML);
|
||||
ML++;
|
||||
for(int i = 0; i < ML; i++) {
|
||||
if(UHS_USB_BulkOnly[B]->LUNIsGood(i)) {
|
||||
partsready = true;
|
||||
((pvt_t *)(sto[i].private_data))->lun = i;
|
||||
((pvt_t *)(sto[i].private_data))->B = B;
|
||||
sto[i].Reads = *UHS_USB_BulkOnly_Read;
|
||||
sto[i].Writes = *UHS_USB_BulkOnly_Write;
|
||||
sto[i].Status = *UHS_USB_BulkOnly_Status;
|
||||
sto[i].Initialize = *UHS_USB_BulkOnly_Initialize;
|
||||
sto[i].Commit = *UHS_USB_BulkOnly_Commit;
|
||||
sto[i].TotalSectors = UHS_USB_BulkOnly[B]->GetCapacity(i);
|
||||
sto[i].SectorSize = UHS_USB_BulkOnly[B]->GetSectorSize(i);
|
||||
printf_P(PSTR("LUN:\t\t%u\r\n"), i);
|
||||
printf_P(PSTR("Total Sectors:\t%08lx\t%lu\r\n"), sto[i].TotalSectors, sto[i].TotalSectors);
|
||||
printf_P(PSTR("Sector Size:\t%04x\t\t%u\r\n"), sto[i].SectorSize, sto[i].SectorSize);
|
||||
// get the partition data...
|
||||
PT = new PCPartition;
|
||||
|
||||
if(!PT->Init(&sto[i])) {
|
||||
part_t *apart;
|
||||
for(int j = 0; j < 4; j++) {
|
||||
apart = PT->GetPart(j);
|
||||
if(apart != NULL && apart->type != 0x00) {
|
||||
memcpy(&(parts[cpart]), apart, sizeof (part_t));
|
||||
printf_P(PSTR("Partition %u type %#02x\r\n"), j, parts[cpart].type);
|
||||
// for now
|
||||
if(isfat(parts[cpart].type)) {
|
||||
Fats[cpart] = new PFAT(&sto[i], cpart, parts[cpart].firstSector);
|
||||
//int r = Fats[cpart]->Good();
|
||||
if(Fats[cpart]->MountStatus()) {
|
||||
delete Fats[cpart];
|
||||
Fats[cpart] = NULL;
|
||||
} else cpart++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// try superblock
|
||||
Fats[cpart] = new PFAT(&sto[i], cpart, 0);
|
||||
//int r = Fats[cpart]->Good();
|
||||
if(Fats[cpart]->MountStatus()) {
|
||||
//printf_P(PSTR("Superblock error %x\r\n"), r);
|
||||
delete Fats[cpart];
|
||||
Fats[cpart] = NULL;
|
||||
} else cpart++;
|
||||
|
||||
}
|
||||
delete PT;
|
||||
} else {
|
||||
sto[i].Writes = NULL;
|
||||
sto[i].Reads = NULL;
|
||||
sto[i].Initialize = NULL;
|
||||
sto[i].TotalSectors = 0UL;
|
||||
sto[i].SectorSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(fatready) {
|
||||
if(Fats[0] != NULL) {
|
||||
struct Pvt * p;
|
||||
p = ((struct Pvt *)(Fats[0]->storage->private_data));
|
||||
if(!UHS_USB_BulkOnly[p->B]->LUNIsGood(p->lun)) {
|
||||
// media change
|
||||
#if !defined(CORE_TEENSY) && defined(__AVR__)
|
||||
fadeAmount = 80;
|
||||
#endif
|
||||
partsready = false;
|
||||
for(int i = 0; i < cpart; i++) {
|
||||
if(Fats[i] != NULL)
|
||||
delete Fats[i];
|
||||
Fats[cpart] = NULL;
|
||||
}
|
||||
fatready = false;
|
||||
notified = false;
|
||||
cpart = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if(fatready) {
|
||||
FRESULT rc; /* Result code */
|
||||
UINT bw, br, i;
|
||||
if(!notified) {
|
||||
#if !defined(CORE_TEENSY) && defined(__AVR__)
|
||||
fadeAmount = 5;
|
||||
#endif
|
||||
notified = true;
|
||||
FATFS *fs = NULL;
|
||||
for(int zz = 0; zz < _VOLUMES; zz++) {
|
||||
if(Fats[zz]->volmap == 0) fs = Fats[zz]->ffs;
|
||||
}
|
||||
printf_P(PSTR("\r\nOpen an existing file (message.txt).\r\n"));
|
||||
rc = f_open(&My_File_Object_x, "0:/MESSAGE.TXT", FA_READ);
|
||||
if(rc) printf_P(PSTR("Error %i, message.txt not found.\r\n"), rc);
|
||||
else {
|
||||
printf_P(PSTR("\r\nType the file content.\r\n"));
|
||||
for(;;) {
|
||||
rc = f_read(&My_File_Object_x, My_Buff_x, mbxs, &br); /* Read a chunk of file */
|
||||
if(rc || !br) break; /* Error or end of file */
|
||||
for(i = 0; i < br; i++) {
|
||||
/* Type the data */
|
||||
if(My_Buff_x[i] == '\n')
|
||||
Serial.write('\r');
|
||||
if(My_Buff_x[i] != '\r')
|
||||
Serial.write(My_Buff_x[i]);
|
||||
Serial.flush();
|
||||
}
|
||||
}
|
||||
if(rc) {
|
||||
f_close(&My_File_Object_x);
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf_P(PSTR("\r\nClose the file.\r\n"));
|
||||
rc = f_close(&My_File_Object_x);
|
||||
if(rc) goto out;
|
||||
}
|
||||
printf_P(PSTR("\r\nCreate a new file (hello.txt).\r\n"));
|
||||
rc = f_open(&My_File_Object_x, "0:/Hello.TxT", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if(rc) {
|
||||
die(rc);
|
||||
goto outdir;
|
||||
}
|
||||
printf_P(PSTR("\r\nWrite a text data. (Hello world!)\r\n"));
|
||||
rc = f_write(&My_File_Object_x, "Hello world!\r\n", 14, &bw);
|
||||
if(rc) {
|
||||
goto out;
|
||||
}
|
||||
printf_P(PSTR("%u bytes written.\r\n"), bw);
|
||||
|
||||
printf_P(PSTR("\r\nClose the file.\r\n"));
|
||||
rc = f_close(&My_File_Object_x);
|
||||
if(rc) {
|
||||
die(rc);
|
||||
goto out;
|
||||
}
|
||||
outdir:{
|
||||
#if _USE_LFN
|
||||
char lfn[_MAX_LFN + 1];
|
||||
FILINFO My_File_Info_Object_x; /* File information object */
|
||||
My_File_Info_Object_x.lfname = lfn;
|
||||
#endif
|
||||
DIR My_Dir_Object_x; /* Directory object */
|
||||
printf_P(PSTR("\r\nOpen root directory.\r\n"));
|
||||
rc = f_opendir(&My_Dir_Object_x, "0:/");
|
||||
if(rc) {
|
||||
die(rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf_P(PSTR("\r\nDirectory listing...\r\n"));
|
||||
#if defined(__AVR__)
|
||||
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
|
||||
#endif
|
||||
for(;;) {
|
||||
#if _USE_LFN
|
||||
My_File_Info_Object_x.lfsize = _MAX_LFN;
|
||||
#endif
|
||||
|
||||
rc = f_readdir(&My_Dir_Object_x, &My_File_Info_Object_x); /* Read a directory item */
|
||||
if(rc || !My_File_Info_Object_x.fname[0]) break; /* Error or end of dir */
|
||||
|
||||
if(My_File_Info_Object_x.fattrib & AM_DIR) {
|
||||
Serial.write('d');
|
||||
} else {
|
||||
Serial.write('-');
|
||||
}
|
||||
Serial.write('r');
|
||||
|
||||
if(My_File_Info_Object_x.fattrib & AM_RDO) {
|
||||
Serial.write('-');
|
||||
} else {
|
||||
Serial.write('w');
|
||||
}
|
||||
if(My_File_Info_Object_x.fattrib & AM_HID) {
|
||||
Serial.write('h');
|
||||
} else {
|
||||
Serial.write('-');
|
||||
}
|
||||
|
||||
if(My_File_Info_Object_x.fattrib & AM_SYS) {
|
||||
Serial.write('s');
|
||||
} else {
|
||||
Serial.write('-');
|
||||
}
|
||||
|
||||
if(My_File_Info_Object_x.fattrib & AM_ARC) {
|
||||
Serial.write('a');
|
||||
} else {
|
||||
Serial.write('-');
|
||||
}
|
||||
|
||||
#if _USE_LFN
|
||||
if(*My_File_Info_Object_x.lfname)
|
||||
printf_P(PSTR(" %8lu %s (%s)\r\n"), My_File_Info_Object_x.fsize, My_File_Info_Object_x.fname, My_File_Info_Object_x.lfname);
|
||||
else
|
||||
#endif
|
||||
printf_P(PSTR(" %8lu %s\r\n"), My_File_Info_Object_x.fsize, &(My_File_Info_Object_x.fname[0]));
|
||||
}
|
||||
}
|
||||
out:
|
||||
if(rc) die(rc);
|
||||
|
||||
DISK_IOCTL(fs->drv, CTRL_COMMIT, 0);
|
||||
printf_P(PSTR("\r\nTest completed.\r\n"));
|
||||
|
||||
}
|
||||
|
||||
if(runtest) {
|
||||
ULONG ii, wt, rt, start, end;
|
||||
FATFS *fs = NULL;
|
||||
for(int zz = 0; zz < _VOLUMES; zz++) {
|
||||
if(Fats[zz]->volmap == 0) fs = Fats[zz]->ffs;
|
||||
}
|
||||
runtest = false;
|
||||
f_unlink("0:/10MB.bin");
|
||||
printf_P(PSTR("\r\nCreate a new 10MB test file (10MB.bin).\r\n"));
|
||||
rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if(rc) goto failed;
|
||||
for(bw = 0; bw < mbxs; bw++) My_Buff_x[bw] = bw & 0xff;
|
||||
fflush(stdout);
|
||||
start = millis();
|
||||
while(start == millis());
|
||||
for(ii = 10485760LU / mbxs; ii > 0LU; ii--) {
|
||||
rc = f_write(&My_File_Object_x, My_Buff_x, mbxs, &bw);
|
||||
if(rc || !bw) goto failed;
|
||||
}
|
||||
rc = f_close(&My_File_Object_x);
|
||||
if(rc) goto failed;
|
||||
end = millis();
|
||||
wt = (end - start) - 1;
|
||||
printf_P(PSTR("Time to write 10485760 bytes: %lu ms (%lu sec) \r\n"), wt, (500 + wt) / 1000UL);
|
||||
rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_READ);
|
||||
fflush(stdout);
|
||||
start = millis();
|
||||
while(start == millis());
|
||||
if(rc) goto failed;
|
||||
for(;;) {
|
||||
rc = f_read(&My_File_Object_x, My_Buff_x, mbxs, &bw); /* Read a chunk of file */
|
||||
if(rc || !bw) break; /* Error or end of file */
|
||||
}
|
||||
end = millis();
|
||||
if(rc) goto failed;
|
||||
rc = f_close(&My_File_Object_x);
|
||||
if(rc) goto failed;
|
||||
rt = (end - start) - 1;
|
||||
printf_P(PSTR("Time to read 10485760 bytes: %lu ms (%lu sec)\r\nDelete test file\r\n"), rt, (500 + rt) / 1000UL);
|
||||
failed:
|
||||
if(rc) die(rc);
|
||||
DISK_IOCTL(fs->drv, CTRL_COMMIT, 0);
|
||||
printf_P(PSTR("10MB timing test finished.\r\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue