Merge remote branch 'origin' into xxxajk

This commit is contained in:
Andrew J. Kroll 2013-06-09 15:47:43 -04:00
commit c5b027855b
19 changed files with 777 additions and 12 deletions

9
.gitmodules vendored Normal file
View file

@ -0,0 +1,9 @@
[submodule "examples/testusbhostFAT/generic_storage"]
path = examples/testusbhostFAT/generic_storage
url = https://github.com/xxxajk/generic_storage
[submodule "examples/testusbhostFAT/xmem2"]
path = examples/testusbhostFAT/xmem2
url = https://github.com/xxxajk/xmem2
[submodule "examples/testusbhostFAT/Arduino_Makefile_master"]
path = examples/testusbhostFAT/Arduino_Makefile_master
url = https://github.com/xxxajk/Arduino_Makefile_master

View file

@ -16,7 +16,7 @@
*/
#include "BTD.h"
// #define DEBUG // Uncomment to print data for debugging -- NO! see message.h
// To enable serial debugging uncomment "#define DEBUG" in message.h
//#define EXTRADEBUG // Uncomment to get even more debugging data
const uint8_t BTD::BTD_CONTROL_PIPE = 0;

2
BTD.h
View file

@ -129,7 +129,7 @@
#define WI_PROTOCOL_BT 0x01 // Bluetooth Programming Interface
#define BTD_MAX_ENDPOINTS 4
#define BTD_NUMSERVICES 4 // Max number of Bluetooth services
#define BTD_NUMSERVICES 4 // Max number of Bluetooth services - if you need more than four simply increase this number
/** All Bluetooth services should include this class. */
class BluetoothService {

View file

@ -16,7 +16,7 @@
*/
#include "PS3BT.h"
//#define DEBUG // Uncomment to print data for debugging -- NO! see message.h
// To enable serial debugging uncomment "#define DEBUG" in message.h
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers

View file

@ -16,7 +16,7 @@
*/
#include "PS3USB.h"
//#define DEBUG // Uncomment to print data for debugging -- NO! see message.h
// To enable serial debugging uncomment "#define DEBUG" in message.h
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers

View file

@ -16,7 +16,7 @@
*/
#include "SPP.h"
#define DEBUG // Uncomment to print data for debugging
// To enable serial debugging uncomment "#define DEBUG" in message.h
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report sent to the Arduino

View file

@ -20,7 +20,7 @@
*/
#include "Wii.h"
#define DEBUG // Uncomment to print data for debugging
// To enable serial debugging uncomment "#define DEBUG" in message.h
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the Wii controllers

View file

@ -18,7 +18,7 @@
*/
#include "XBOXRECV.h"
//#define DEBUG // Uncomment to print data for debugging -- NO! see message.h
// To enable serial debugging uncomment "#define DEBUG" in message.h
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
@ -481,15 +481,15 @@ void XBOXRECV::setLedRaw(uint8_t value, uint8_t controller) {
void XBOXRECV::setLedOn(LED led, uint8_t controller) {
if (led != ALL) // All LEDs can't be on a the same time
setLedRaw(controller, (pgm_read_byte(&XBOXLEDS[(uint8_t)led])) + 4);
setLedRaw(pgm_read_byte(&XBOXLEDS[(uint8_t)led]) + 4, controller);
}
void XBOXRECV::setLedBlink(LED led, uint8_t controller) {
setLedRaw(controller, pgm_read_byte(&XBOXLEDS[(uint8_t)led]));
setLedRaw(pgm_read_byte(&XBOXLEDS[(uint8_t)led]), controller);
}
void XBOXRECV::setLedMode(LEDMode ledMode, uint8_t controller) { // This function is used to do some speciel LED stuff the controller supports
setLedRaw(controller, (uint8_t)ledMode);
setLedRaw((uint8_t)ledMode, controller);
}
/* PC runs this at interval of approx 2 seconds

View file

@ -16,7 +16,7 @@
*/
#include "XBOXUSB.h"
//#define DEBUG // Uncomment to print data for debugging -- NO! see message.h
// To enable serial debugging uncomment "#define DEBUG" in message.h
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller

View file

@ -20,6 +20,8 @@ class KbdRptParser : public KeyboardReportParser
void PrintKey(uint8_t mod, uint8_t key);
protected:
virtual void OnControlKeysChanged(uint8_t before, uint8_t after);
virtual void OnKeyDown (uint8_t mod, uint8_t key);
virtual void OnKeyUp (uint8_t mod, uint8_t key);
virtual void OnKeyPressed(uint8_t key);
@ -54,6 +56,42 @@ void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
OnKeyPressed(c);
}
void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {
MODIFIERKEYS beforeMod;
*((uint8_t*)&beforeMod) = before;
MODIFIERKEYS afterMod;
*((uint8_t*)&afterMod) = after;
if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) {
Serial.println("LeftCtrl changed");
}
if (beforeMod.bmLeftShift != afterMod.bmLeftShift) {
Serial.println("LeftShift changed");
}
if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) {
Serial.println("LeftAlt changed");
}
if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) {
Serial.println("LeftGUI changed");
}
if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) {
Serial.println("RightCtrl changed");
}
if (beforeMod.bmRightShift != afterMod.bmRightShift) {
Serial.println("RightShift changed");
}
if (beforeMod.bmRightAlt != afterMod.bmRightAlt) {
Serial.println("RightAlt changed");
}
if (beforeMod.bmRightGUI != afterMod.bmRightGUI) {
Serial.println("RightGUI changed");
}
}
void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
{
Serial.print("UP ");

@ -0,0 +1 @@
Subproject commit f379bae02aa3d9c3da558ba2041558b88db95bbb

View file

@ -0,0 +1,42 @@
#
# 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 uncomment the following two lines
# BOARD = mega2560
# PROGRAMMER = wiring
# ...and then comment out the following two lines
BOARD = mega
PROGRAMMER = arduino
# set your Arduino tty port here
PORT = /dev/ttyUSB0
EXTRA_FLAGS = -D _FS_TINY=0
EXTRA_FLAGS += -D _USE_LFN=1
# 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 HAVEXMEM=1
EXTRA_FLAGS += -D EXT_RAM_STACK=1
EXTRA_FLAGS += -D EXT_RAM_HEAP=1
EXTRA_FLAGS += -D DISABLE_SERIAL1
EXTRA_FLAGS += -D DISABLE_SERIAL2
EXTRA_FLAGS += -D DISABLE_SERIAL3
# You should not need to change this, but I place it here if you want to play.
# These are the defaults for the optimization of the flash and ram
#OPT_FLAGS = -Os -fno-exceptions -ffunction-sections -fdata-sections -MMD
# The following are the libraries used.
LIB_DIRS =
LIB_DIRS += ../../
LIB_DIRS += xmem2
LIB_DIRS += generic_storage
# And finally, the part that brings everything together for you.
include Arduino_Makefile_master/_Makefile.master

View file

@ -0,0 +1,30 @@
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)
It is recommended to get a external RAM shield or apply the following patch: <https://github.com/arduino/Arduino/issues/1425>.
The following shield is recommended: <http://ruggedcircuits.com/html/quadram.html>.
You must use the bundled [Makefile](Makefile) to compile the code instead of the Arduino IDE if you do not use external RAM. 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
```

View file

@ -0,0 +1,6 @@
file build/testusbhostFAT.elf
target remote localhost:4242
set {int}0x802200 = 0xffff
set {int}0x802220 = 0x0000
#graph display `x /3xh 0x802200`

@ -0,0 +1 @@
Subproject commit b87902bf7a0934b62f43c2176fb11ea318da8629

View file

@ -0,0 +1,629 @@
/*
* Mega + USB storage + optional expansion RAM + funky status LED,
* Includes interactive debug level setting, and supports emulated 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.
*
*/
// Keep this at zero until enumeration is fixed.
// Set to 1 if you are fixing enumeration.
#define WANT_HUB_TEST 0
#ifndef HAVE_XMEM
// Set this to zero to disable xmem
#define HAVE_XMEM 1
#endif
#include <avr/pgmspace.h>
#if HAVE_XMEM
#include <xmem.h>
#endif
#include <avrpins.h>
#include <max3421e.h>
#include <usbhost.h>
#include <usb_ch9.h>
#include <address.h>
#include <Usb.h>
#if WANT_HUB_TEST
#include <usbhub.h>
#endif
#include <masstorage.h>
#include <message.h>
#include <avr/interrupt.h>
#include <PCpartition/PCPartition.h>
#include <Storage.h>
#include <FAT/FAT.h>
// Warning! Do not use this unless you are aware of what it does!
#if HAVE_XMEM
#define GOD_MODE 0
#endif
static FILE mystdout;
int led = 13; // the pin that the LED is attached to
volatile int brightness = 0; // how bright the LED is
volatile int fadeAmount = 80; // how many points to fade the LED by
volatile uint8_t current_state = 1;
volatile uint32_t LEDnext_time; // fade timeout
volatile uint8_t last_state = 0;
volatile boolean fatready = false;
volatile boolean partsready = false;
volatile boolean notified = false;
volatile uint32_t HEAPnext_time; // when to print out next heap report
volatile boolean runtest = false;
volatile boolean usbon = false;
volatile uint32_t usbon_time;
volatile boolean change = false;
volatile boolean reportlvl = false;
int cpart = 0;
PCPartition *PT;
#if WANT_HUB_TEST
#define MAX_HUBS 2
static USBHub *Hubs[MAX_HUBS];
#endif
static PFAT *Fats[MAX_PARTS];
static part_t parts[MAX_PARTS];
static storage_t sto[MAX_PARTS];
#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" unsigned int freeHeap();
/*
unsigned int getHeapend(){
extern unsigned int __heap_start;
if ((unsigned int)__brkval == 0) {
return (unsigned int)&__heap_start;
} else {
return (unsigned int)__brkval;
}
}
unsigned int freeHeap() {
if (SP < (unsigned int)__malloc_heap_start) {
return ((unsigned int)__malloc_heap_end - getHeapend());
} else {
return (SP - getHeapend());
}
}
*/
static int my_putc(char c, FILE *t) {
Serial.write(c);
}
void setup() {
for (int i = 0; i < MAX_PARTS; i++) {
Fats[i] = NULL;
}
// Set this to higher values to enable more debug information
// minimum 0x00, maximum 0xff
UsbDEBUGlvl = 0x51;
// declare pin 9 to be an output:
pinMode(led, OUTPUT);
pinMode(2, OUTPUT);
// Initialize 'debug' serial port
Serial.begin(115200);
//fdevopen(&my_putc, 0);
// too bad we can't tinker with iob directly, oh well.
mystdout.put = my_putc;
mystdout.get = NULL;
mystdout.flags = _FDEV_SETUP_WRITE;
mystdout.udata = 0;
stdout = &mystdout;
// Blink pin 9:
delay(500);
analogWrite(led, 255);
delay(500);
analogWrite(led, 0);
delay(500);
analogWrite(led, 255);
delay(500);
analogWrite(led, 0);
delay(500);
analogWrite(led, 255);
delay(500);
analogWrite(led, 0);
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"));
printf_P(PSTR("\r\n\r\nLong filename support: "
#if _USE_LFN
"Enabled"
#else
"Disabled"
#endif
"\r\n"));
analogWrite(led, 255);
delay(500);
analogWrite(led, 0);
delay(500);
delay(100);
analogWrite(led, 255);
delay(100);
analogWrite(led, 0);
LEDnext_time = millis() + 1;
#ifdef 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));
// 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);
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
}
#endif
while (Usb.Init() == -1) {
printf_P(PSTR("No\r\n"));
Notify(PSTR("OSC did not start."), 0x40);
}
// usb VBUS _OFF_
Usb.gpioWr(0x00);
digitalWrite(2, 0);
usbon_time = millis() + 2000;
cli();
TCCR3A = 0;
TCCR3B = 0;
// (0.01/(1/((16 *(10^6)) / 8))) - 1 = 19999
#if GOD_MODE
OCR3A = 10;
#else
OCR3A = 19999;
#endif
TCCR3B |= prescale8;
TIMSK3 |= (1 << OCIE1A);
sei();
HEAPnext_time = millis() + 10000;
}
#if GOD_MODE
volatile uint16_t *foof = reinterpret_cast<uint16_t *>(0x2200);
#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 GOD_MODE
case 'z':
cli();
*foof = 0xffff;
*(foof + 2) = 0x0000;
sei();
break;
#endif
}
}
}
ISR(TIMER3_COMPA_vect) {
#if GOD_MODE
#if !EXT_RAM_HEAP && !EXT_RAM_STACK
// Super cool debug feature to detect stack and heap collisions.
// We can use this in conjuction with the AVR dragon
// to check max depth of the stack and height of heap.
if (*foof >= (uint16_t)(SP)) {
*foof = (uint16_t)(SP);
*(foof + 2) = (uint16_t)__brkval;
}
#endif
#endif
if (millis() >= LEDnext_time) {
LEDnext_time = millis() + 30;
// set the brightness of pin 9:
analogWrite(led, 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;
}
}
}
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 (;;);
}
/*make sure this is a power of two. */
#define mbxs 128
void loop() {
uint8_t My_Buff_x[mbxs]; /* File read buffer */
FIL My_File_Object_x; /* File object */
DIR My_Dir_Object_x; /* Directory object */
FILINFO My_File_Info_Object_x; /* File information object */
// Print a heap status report about every 10 seconds.
if (millis() >= HEAPnext_time) {
if (UsbDEBUGlvl > 0x50) {
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
#if GOD_MODE
cli();
uint16_t p = *foof;
sei();
printf_P(PSTR("MAXSP %4.4x, current %4.4x\r\n"), p, SP);
#endif
}
HEAPnext_time = millis() + 10000;
}
// 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 && millis() >= usbon_time) {
change = true;
usbon = true;
}
if (change) {
change = false;
if (usbon) {
printf_P(PSTR("VBUS on\r\n"));
Usb.gpioWr(0xFF);
digitalWrite(2, 1);
} else {
Usb.gpioWr(0x00);
digitalWrite(2, 0);
usbon = false;
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 (current_state == USB_STATE_RUNNING) {
fadeAmount = 30;
/*
partsready = false;
for (int i = 0; i < cpart; i++) {
if (Fats[i] != NULL)
delete Fats[i];
}
fatready = false;
notified = false;
cpart = 0;
*/
}
if (current_state == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
fadeAmount = 80;
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;
}
#if 0
if (current_state == 0xa0) {
printf_P(PSTR("VBUS off\r\n"));
// safe to do here
Usb.gpioWr(0x00);
digitalWrite(2, 0);
usbon = false;
usbon_time = millis() + 2000;
change = false;
}
#endif
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_DRIVERS; B++) {
if (!partsready && Bulk[B]->GetAddress() != NULL) {
// Build a list.
int ML = Bulk[B]->GetbMaxLUN();
//printf("MAXLUN = %i\r\n", ML);
ML++;
for (int i = 0; i < ML; i++) {
if (Bulk[B]->LUNIsGood(i)) {
partsready = true;
sto[i].private_data = &info[i];
info[i].lun = i;
info[i].B = B;
info[i].volmap = 0; // TO-DO: keep track of > 1
sto[i].Read = *PRead;
sto[i].Write = *PWrite;
sto[i].Reads = *PReads;
sto[i].Writes = *PWrites;
sto[i].Status = *PStatus;
sto[i].TotalSectors = Bulk[B]->GetCapacity(i);
sto[i].SectorSize = Bulk[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;
int r = Fats[cpart]->Init(&sto[i], cpart, parts[cpart].firstSector);
if (r) {
delete Fats[cpart];
Fats[cpart] = NULL;
} else cpart++;
}
}
}
} else {
// try superblock
Fats[cpart] = new PFAT;
int r = Fats[cpart]->Init(&sto[i], cpart, 0);
if (r) {
printf_P(PSTR("Superblock error %x\r\n"), r);
delete Fats[cpart];
Fats[cpart] = NULL;
} else cpart++;
}
delete PT;
} else {
sto[i].Read = NULL;
sto[i].Write = NULL;
sto[i].Writes = NULL;
sto[i].Reads = 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 (!Bulk[p->B]->LUNIsGood(p->lun)) {
// media change
fadeAmount = 80;
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;
ULONG ii, wt, rt, start, end;
if (!notified) {
fadeAmount = 5;
notified = true;
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"));
else {
printf_P(PSTR("\r\nType the file content.\r\n"));
for (;;) {
rc = f_read(&My_File_Object_x, &(My_Buff_x[0]), 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:
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"));
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
for (;;) {
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);
printf_P(PSTR("\r\nTest completed.\r\n"));
}
if (runtest) {
runtest = false;
printf_P(PSTR("\r\nCreate a new 10MB test file (10MB.bin).\r\n"));
for (bw = 0; bw < mbxs; bw++) My_Buff_x[bw] = bw & 0xff;
rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_WRITE | FA_CREATE_ALWAYS);
if (rc) goto failed;
start = millis();
for (ii = 10485760 / mbxs; ii > 0; ii--) {
rc = f_write(&My_File_Object_x, &My_Buff_x[0], mbxs, &bw);
if (rc || !bw) goto failed;
}
rc = f_close(&My_File_Object_x);
if (rc) goto failed;
end = millis();
wt = end - start;
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);
start = millis();
if (rc) goto failed;
for (;;) {
rc = f_read(&My_File_Object_x, &My_Buff_x[0], 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;
printf_P(PSTR("Time to read 10485760 bytes: %lu ms (%lu sec)\r\nDelete test file\r\n"), rt, (500 + rt) / 1000UL);
failed:
rc = f_unlink("0:/10MB.bin");
if (rc) die(rc);
printf_P(PSTR("10MB timing test finished.\r\n"));
}
}
}
}

@ -0,0 +1 @@
Subproject commit b2adf12413e93de01334efeed0e5d46a73eb17ae

View file

@ -52,6 +52,11 @@ void KeyboardReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t
//KBDINFO *pki = (KBDINFO*)buf;
// provide event for changed control key state
if (prevState.bInfo[0x00] != buf[0x00]) {
OnControlKeysChanged(prevState.bInfo[0x00], buf[0x00]);
}
for (uint8_t i = 2; i < 8; i++) {
bool down = false;
bool up = false;

View file

@ -161,7 +161,10 @@ public:
protected:
virtual uint8_t HandleLockingKeys(HID* hid, uint8_t key);
virtual void OnKeyDown(uint8_t mod, uint8_t key) {
virtual void OnControlKeysChanged(uint8_t before, uint8_t after) {
};
virtual void OnKeyDown(uint8_t mod, uint8_t key) {
};
virtual void OnKeyUp(uint8_t mod, uint8_t key) {