Merge branch 'master' into SPPClient

Conflicts:
	BTD.cpp
This commit is contained in:
Kristian Lauszus 2014-07-01 13:55:46 +02:00
commit b2dae57d4d
25 changed files with 693 additions and 274 deletions

View file

@ -373,7 +373,7 @@ uint8_t BTD::Release() {
uint8_t BTD::Poll() {
if(!bPollEnable)
return 0;
if(qNextPollTime <= millis()) { // Don't poll if shorter than polling interval
if((long)(millis() - qNextPollTime) >= 0L) { // Don't poll if shorter than polling interval
qNextPollTime = millis() + pollInterval; // Set new poll time
HCI_event_task(); // Poll the HCI event pipe
HCI_task(); // HCI state machine
@ -470,6 +470,7 @@ void BTD::HCI_event_task() {
disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
break;
} else {
#ifdef EXTRADEBUG
Notify(PSTR("\r\nClass of device: "), 0x80);
@ -497,6 +498,7 @@ void BTD::HCI_event_task() {
Notify(PSTR(" has been found"), 0x80);
#endif
hci_set_flag(HCI_FLAG_DEVICE_FOUND);
break;
}
}

View file

@ -58,7 +58,6 @@ protected:
/** @name BTHID implementation */
/**
* Used to parse Bluetooth HID data.
* @param bthid Pointer to the BTHID class.
* @param len The length of the incoming data.
* @param buf Pointer to the data buffer.
*/

View file

@ -112,6 +112,18 @@ protected:
};
/**@}*/
/** @name USBDeviceConfig implementation */
/**
* Used by the USB core to check what this driver support.
* @param vid The device's VID.
* @param pid The device's PID.
* @return Returns true if the device's VID and PID matches this driver.
*/
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
return (vid == PS4_VID && pid == PS4_PID);
};
/**@}*/
private:
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
};

82
PSBuzz.cpp Normal file
View file

@ -0,0 +1,82 @@
/* Copyright (C) 2014 Kristian Lauszus, TKJ Electronics. All rights reserved.
This software may be distributed and modified under the terms of the GNU
General Public License version 2 (GPL2) as published by the Free Software
Foundation and appearing in the file GPL2.TXT included in the packaging of
this file. Please note that GPL2 Section 2[b] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ("Copyleft").
Contact information
-------------------
Kristian Lauszus, TKJ Electronics
Web : http://www.tkjelectronics.com
e-mail : kristianl@tkjelectronics.com
*/
#include "PSBuzz.h"
// To enable serial debugging see "settings.h"
//#define PRINTREPORT // Uncomment to print the report send by the PS Buzz Controllers
void PSBuzz::ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID && len > 0 && buf) {
#ifdef PRINTREPORT
Notify(PSTR("\r\n"), 0x80);
for (uint8_t i = 0; i < len; i++) {
D_PrintHex<uint8_t > (buf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
#endif
memcpy(&psbuzzButtons, buf + 2, min(len - 2, sizeof(psbuzzButtons)));
if (psbuzzButtons.val != oldButtonState.val) { // Check if anything has changed
buttonClickState.val = psbuzzButtons.val & ~oldButtonState.val; // Update click state variable
oldButtonState.val = psbuzzButtons.val;
}
}
};
uint8_t PSBuzz::OnInitSuccessful() {
if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID) {
Reset();
if (pFuncOnInit)
pFuncOnInit(); // Call the user function
else
setLedOnAll(); // Turn the LED on, on all four controllers
};
return 0;
};
bool PSBuzz::getButtonPress(ButtonEnum b, uint8_t controller) {
return psbuzzButtons.val & (1UL << (b + 5 * controller)); // Each controller uses 5 bits, so the value is shifted 5 for each controller
};
bool PSBuzz::getButtonClick(ButtonEnum b, uint8_t controller) {
uint32_t mask = (1UL << (b + 5 * controller)); // Each controller uses 5 bits, so the value is shifted 5 for each controller
bool click = buttonClickState.val & mask;
buttonClickState.val &= ~mask; // Clear "click" event
return click;
};
// Source: http://www.developerfusion.com/article/84338/making-usb-c-friendly/ and https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c
void PSBuzz::setLedRaw(bool value, uint8_t controller) {
ledState[controller] = value; // Save value for next time it is called
uint8_t buf[7];
buf[0] = 0x00;
buf[1] = ledState[0] ? 0xFF : 0x00;
buf[2] = ledState[1] ? 0xFF : 0x00;
buf[3] = ledState[2] ? 0xFF : 0x00;
buf[4] = ledState[3] ? 0xFF : 0x00;
buf[5] = 0x00;
buf[6] = 0x00;
PSBuzz_Command(buf, sizeof(buf));
};
void PSBuzz::PSBuzz_Command(uint8_t *data, uint16_t nbytes) {
// bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress, epInfo[0].epAddr, bmREQ_HIDOUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
};

185
PSBuzz.h Normal file
View file

@ -0,0 +1,185 @@
/* Copyright (C) 2014 Kristian Lauszus, TKJ Electronics. All rights reserved.
This software may be distributed and modified under the terms of the GNU
General Public License version 2 (GPL2) as published by the Free Software
Foundation and appearing in the file GPL2.TXT included in the packaging of
this file. Please note that GPL2 Section 2[b] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ("Copyleft").
Contact information
-------------------
Kristian Lauszus, TKJ Electronics
Web : http://www.tkjelectronics.com
e-mail : kristianl@tkjelectronics.com
*/
#ifndef _psbuzz_h_
#define _psbuzz_h_
#include "hiduniversal.h"
#include "controllerEnums.h"
#define PSBUZZ_VID 0x054C // Sony Corporation
#define PSBUZZ_PID 0x1000 // PS Buzz Controller
/** Struct used to easily read the different buttons on the controllers */
union PSBUZZButtons {
struct {
uint8_t red : 1;
uint8_t yellow : 1;
uint8_t green : 1;
uint8_t orange : 1;
uint8_t blue : 1;
} __attribute__((packed)) btn[4];
uint32_t val : 20;
} __attribute__((packed));
/**
* This class implements support for the PS Buzz controllers via USB.
* It uses the HIDUniversal class for all the USB communication.
*/
class PSBuzz : public HIDUniversal {
public:
/**
* Constructor for the PSBuzz class.
* @param p Pointer to the USB class instance.
*/
PSBuzz(USB *p) :
HIDUniversal(p) {
Reset();
};
/**
* Used to check if a PS Buzz controller is connected.
* @return Returns true if it is connected.
*/
bool connected() {
return HIDUniversal::isReady() && HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID;
};
/**
* Used to call your own function when the device is successfully initialized.
* @param funcOnInit Function to call.
*/
void attachOnInit(void (*funcOnInit)(void)) {
pFuncOnInit = funcOnInit;
};
/** @name PS Buzzer Controller functions */
/**
* getButtonPress(ButtonEnum b) will return true as long as the button is held down.
*
* While getButtonClick(ButtonEnum b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
* but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
* @param b ::ButtonEnum to read.
* @param controller The controller to read from. Default to 0.
* @return getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
*/
bool getButtonPress(ButtonEnum b, uint8_t controller = 0);
bool getButtonClick(ButtonEnum b, uint8_t controller = 0);
/**@}*/
/** @name PS Buzzer Controller functions */
/**
* Set LED value without using ::LEDEnum.
* @param value See: ::LEDEnum.
*/
/**
* Set LED values directly.
* @param value Used to set whenever the LED should be on or off
* @param controller The controller to control. Defaults to 0.
*/
void setLedRaw(bool value, uint8_t controller = 0);
/** Turn all LEDs off. */
void setLedOffAll() {
for (uint8_t i = 1; i < 4; i++) // Skip first as it will be set in setLedRaw
ledState[i] = false; // Just an easy way to set all four off at the same time
setLedRaw(false); // Turn the LED off, on all four controllers
};
/**
* Turn the LED off on a specific controller.
* @param controller The controller to turn off. Defaults to 0.
*/
void setLedOff(uint8_t controller = 0) {
setLedRaw(false, controller);
};
/** Turn all LEDs on. */
void setLedOnAll() {
for (uint8_t i = 1; i < 4; i++) // Skip first as it will be set in setLedRaw
ledState[i] = true; // Just an easy way to set all four off at the same time
setLedRaw(true); // Turn the LED on, on all four controllers
};
/**
* Turn the LED on on a specific controller.
* @param controller The controller to turn off. Defaults to 0.
*/
void setLedOn(uint8_t controller = 0) {
setLedRaw(true, controller);
};
/**
* Toggle the LED on a specific controller.
* @param controller The controller to turn off. Defaults to 0.
*/
void setLedToggle(uint8_t controller = 0) {
setLedRaw(!ledState[controller], controller);
};
/**@}*/
protected:
/** @name HIDUniversal implementation */
/**
* Used to parse USB HID data.
* @param hid Pointer to the HID class.
* @param is_rpt_id Only used for Hubs.
* @param len The length of the incoming data.
* @param buf Pointer to the data buffer.
*/
virtual void ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
/**
* Called when a device is successfully initialized.
* Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
* This is useful for instance if you want to set the LEDs in a specific way.
*/
virtual uint8_t OnInitSuccessful();
/**@}*/
/** Used to reset the different buffers to their default values */
void Reset() {
psbuzzButtons.val = 0;
oldButtonState.val = 0;
buttonClickState.val = 0;
for (uint8_t i = 0; i < sizeof(ledState); i++)
ledState[i] = 0;
};
/** @name USBDeviceConfig implementation */
/**
* Used by the USB core to check what this driver support.
* @param vid The device's VID.
* @param pid The device's PID.
* @return Returns true if the device's VID and PID matches this driver.
*/
virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) {
return (vid == PSBUZZ_VID && pid == PSBUZZ_PID);
};
/**@}*/
private:
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
void PSBuzz_Command(uint8_t *data, uint16_t nbytes);
PSBUZZButtons psbuzzButtons, oldButtonState, buttonClickState;
bool ledState[4];
};
#endif

View file

@ -22,10 +22,30 @@ For more information about the hardware see the [Hardware Manual](http://www.cir
* __Alexei Glushchenko, Circuits@Home__ - <alex-gl@mail.ru>
* Developers of the USB Core, HID, FTDI, ADK, ACM, and PL2303 libraries
* __Kristian Lauszus, TKJ Electronics__ - <kristianl@tkjelectronics.com>
* Developer of the [BTD](#bluetooth-libraries), [BTHID](#bthid-library), [SPP](#spp-library), [PS4](#ps4-library), [PS3](#ps3-library), [Wii](#wii-library), and [Xbox](#xbox-library) libraries
* Developer of the [BTD](#bluetooth-libraries), [BTHID](#bthid-library), [SPP](#spp-library), [PS4](#ps4-library), [PS3](#ps3-library), [Wii](#wii-library), [Xbox](#xbox-library), and [PSBuzz](#ps-buzz-library) libraries
* __Andrew Kroll__ - <xxxajk@gmail.com>
* Major contributor to mass storage code
# Table of Contents
* [How to include the library](#how-to-include-the-library)
* [How to use the library](#how-to-use-the-library)
* [Documentation](#documentation)
* [Enable debugging](#enable-debugging)
* [Boards](#boards)
* [Bluetooth libraries](#bluetooth-libraries)
* [BTHID library](#bthid-library)
* [SPP library](#spp-library)
* [PS4 Library](#ps4-library)
* [PS3 Library](#ps3-library)
* [Xbox Libraries](#xbox-libraries)
* [Xbox library](#xbox-library)
* [Xbox 360 Library](#xbox-360-library)
* [Wii library](#wii-library)
* [PS Buzz Library](#ps-buzz-library)
* [Interface modifications](#interface-modifications)
* [FAQ](#faq)
# How to include the library
First download the library by clicking on the following link: <https://github.com/felis/USB_Host_Shield_2.0/archive/master.zip>.
@ -241,6 +261,39 @@ All the information about the Wii controllers are from these sites:
* <http://wiibrew.org/wiki/Wiimote/Extension_Controllers/Wii_Motion_Plus>
* The old library created by _Tomoyuki Tanaka_: <https://github.com/moyuchin/WiiRemote_on_Arduino> also helped a lot.
### [PS Buzz Library](PSBuzz.cpp)
This library implements support for the Playstation Buzz controllers via USB.
It is essentially just a wrapper around the [HIDUniversal](hiduniversal.cpp) which takes care of the initializing and reading of the controllers. The [PSBuzz](PSBuzz.cpp) class simply inherits this and parses the data, so it is easy for users to read the buttons and turn the big red button on the controllers on and off.
The example [PSBuzz.ino](examples/PSBuzz/PSBuzz.ino) shows how one can do this with just a few lines of code.
More information about the controller can be found at the following sites:
* http://www.developerfusion.com/article/84338/making-usb-c-friendly/
* https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c
# Interface modifications
The shield is using SPI for communicating with the MAX3421E USB host controller. It uses the SCK, MISO and MOSI pins via the ICSP on your board.
Furthermore it uses one pin as SS and one INT pin. These are by default located on pin 10 and 9 respectively. They can easily be reconfigured in case you need to use them for something else by cutting the jumper on the shield and then solder a wire from the pad to the new pin.
After that you need modify the following entry in [UsbCore.h](UsbCore.h):
```C++
typedef MAX3421e<P10, P9> MAX3421E;
```
For instance if you have rerouted SS to pin 7 it should read:
```C++
typedef MAX3421e<P7, P9> MAX3421E;
```
See the "Interface modifications" section in the [hardware manual](https://www.circuitsathome.com/usb-host-shield-hardware-manual) for more information.
# FAQ
> When I plug my device into the USB connector nothing happens?

10
Usb.cpp
View file

@ -327,7 +327,7 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
rcode = (regRd(rHRSL) & 0x0f);
while(rcode && (timeout > millis())) {
while(rcode && ((long)(millis() - timeout) < 0L)) {
switch(rcode) {
case hrNAK:
nak_count++;
@ -380,11 +380,11 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
uint8_t retry_count = 0;
uint16_t nak_count = 0;
while(timeout > millis()) {
while((long)(millis() - timeout) < 0L) {
regWr(rHXFR, (token | ep)); //launch the transfer
rcode = USB_ERROR_TRANSFER_TIMEOUT;
while(timeout > millis()) //wait for transfer completion
while((long)(millis() - timeout) < 0L) //wait for transfer completion
{
tmpdata = regRd(rHIRQ);
@ -475,7 +475,7 @@ void USB::Task(void) //USB state machine
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
break;
case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
if(delay < millis())
if((long)(millis() - delay) >= 0L)
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
else break; // don't fall through
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
@ -502,7 +502,7 @@ void USB::Task(void) //USB state machine
}
break;
case USB_ATTACHED_SUBSTATE_WAIT_RESET:
if(delay < millis()) usb_task_state = USB_STATE_CONFIGURING;
if((long)(millis() - delay) >= 0L) usb_task_state = USB_STATE_CONFIGURING;
else break; // don't fall through
case USB_STATE_CONFIGURING:

View file

@ -657,7 +657,7 @@ void WII::L2CAP_task() {
/* The next states are in run() */
case L2CAP_INTERRUPT_DISCONNECT:
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE) && millis() > timer) {
if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE) && ((long)(millis() - timer) >= 0L)) {
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80);
#endif
@ -682,7 +682,7 @@ void WII::L2CAP_task() {
}
void WII::Run() {
if(l2cap_state == L2CAP_INTERRUPT_DISCONNECT && millis() > timer)
if(l2cap_state == L2CAP_INTERRUPT_DISCONNECT && ((long)(millis() - timer) >= 0L))
L2CAP_task(); // Call the rest of the disconnection routine after we have waited long enough
switch(l2cap_state) {

View file

@ -514,9 +514,9 @@ void XBOXRECV::setLedRaw(uint8_t value, uint8_t controller) {
void XBOXRECV::setLedOn(LEDEnum led, uint8_t controller) {
if(led == OFF)
setLedRaw(0);
setLedRaw(0, controller);
else if(led != ALL) // All LEDs can't be on a the same time
setLedRaw(pgm_read_byte(&XBOX_LEDS[(uint8_t)led]) + 4);
setLedRaw(pgm_read_byte(&XBOX_LEDS[(uint8_t)led]) + 4, controller);
}
void XBOXRECV::setLedBlink(LEDEnum led, uint8_t controller) {

View file

@ -137,6 +137,14 @@ enum ButtonEnum {
BLACK = 8, // Available on the original Xbox controller
WHITE = 9, // Available on the original Xbox controller
/**@}*/
/** PS Buzz controllers */
RED = 0,
YELLOW = 1,
GREEN = 2,
ORANGE = 3,
BLUE = 4,
/**@}*/
};
/** Joysticks on the PS3 and Xbox controllers. */

View file

@ -6,7 +6,7 @@
#include <SPP.h>
#include <usbhub.h>
// Satisfy IDE, which only needs to see the include statment in the ino.
// Satisfy IDE, which only needs to see the include statement in the ino.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
@ -15,10 +15,11 @@ USB Usb;
//USBHub Hub1(&Usb); // Some dongles have a hub inside
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
SPP *SerialBT[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM!
const uint8_t length = sizeof(SerialBT) / sizeof(SerialBT[0]); // Get the lenght of the array
const uint8_t length = 2; // Set the number of instances here
SPP *SerialBT[length]; // We will use this pointer to store the instances, you can easily make it larger if you like, but it will use a lot of RAM!
boolean firstMessage[length] = { true }; // Set all to true
uint8_t buffer[50];
void setup() {
for (uint8_t i = 0; i < length; i++)
@ -28,10 +29,11 @@ void setup() {
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1); //halt
while (1); // Halt
}
Serial.print(F("\r\nSPP Bluetooth Library Started"));
}
void loop() {
Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well
@ -47,22 +49,15 @@ void loop() {
else
firstMessage[i] = true;
}
// Set the connection you want to send to using the first character
// For instance "0Hello World" would send "Hello World" to connection 0
if (Serial.available()) {
delay(10); // Wait for the rest of the data to arrive
uint8_t i = 0;
while (Serial.available() && i < sizeof(buffer)) // Read the data
buffer[i++] = Serial.read();
/*
Set the connection you want to send to using the first character
For instace "0Hello World" would send "Hello World" to connection 0
*/
uint8_t id = buffer[0] - '0'; // Convert from ASCII
if (id < length && i > 1) { // And then compare to length and make sure there is any text
if (SerialBT[id]->connected) { // Check if a device is actually connected
for (uint8_t i2 = 0; i2 < i - 1; i2++) // Don't include the first character
buffer[i2] = buffer[i2 + 1];
SerialBT[id]->write(buffer, i - 1); // Send the data
}
uint8_t id = Serial.read() - '0'; // Convert from ASCII
if (id < length && SerialBT[id]->connected) { // Make sure that the id is valid and make sure that a device is actually connected
while (Serial.available()) // Check if data is available
SerialBT[id]->write(Serial.read()); // Send the data
}
}
}

View file

@ -0,0 +1,46 @@
/*
Example sketch for the Playstation Buzz library - developed by Kristian Lauszus
For more information visit my blog: http://blog.tkjelectronics.dk/ or
send me an e-mail: kristianl@tkjelectronics.com
*/
#include <PSBuzz.h>
// Satisfy IDE, which only needs to see the include statment in the ino.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
USB Usb;
PSBuzz Buzz(&Usb);
void setup() {
Serial.begin(115200);
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1); // Halt
}
Serial.println(F("\r\nPS Buzz Library Started"));
}
void loop() {
Usb.Task();
if (Buzz.connected()) {
for (uint8_t i = 0; i < 4; i++) {
if (Buzz.getButtonClick(RED, i)) {
Buzz.setLedToggle(i); // Toggle the LED
Serial.println(F("RED"));
}
if (Buzz.getButtonClick(YELLOW, i))
Serial.println(F("YELLOW"));
if (Buzz.getButtonClick(GREEN, i))
Serial.println(F("GREEN"));
if (Buzz.getButtonClick(ORANGE, i))
Serial.println(F("ORANGE"));
if (Buzz.getButtonClick(BLUE, i))
Serial.println(F("BLUE"));
}
}
}

View file

@ -97,7 +97,7 @@ void loop()
if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
{
if (millis() >= next_time)
if ((millis() - next_time) >= 0L)
{
Usb.ForEachUsbDevice(&PrintAllDescriptors);
Usb.ForEachUsbDevice(&PrintAllAddresses);

View file

@ -10,80 +10,75 @@
#include <spi4teensy3.h>
#endif
class PLAsyncOper : public CDCAsyncOper
{
class PLAsyncOper : public CDCAsyncOper {
public:
virtual uint8_t OnInit(ACM *pacm);
virtual uint8_t OnInit(ACM *pacm);
};
uint8_t PLAsyncOper::OnInit(ACM *pacm)
{
uint8_t rcode;
uint8_t PLAsyncOper::OnInit(ACM *pacm) {
uint8_t rcode;
// Set DTR = 1
rcode = pacm->SetControlLineState(1);
// Set DTR = 1
rcode = pacm->SetControlLineState(1);
if(rcode) {
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 4800; //default serial speed of GPS unit
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if(rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
if (rcode)
{
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 4800; //default serial speed of GPS unit
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
return rcode;
}
USB Usb;
USBHub Hub(&Usb);
PLAsyncOper AsyncOper;
PL2303 Pl(&Usb, &AsyncOper);
USB Usb;
USBHub Hub(&Usb);
PLAsyncOper AsyncOper;
PL2303 Pl(&Usb, &AsyncOper);
uint32_t read_delay;
#define READ_DELAY 100
void setup()
{
Serial.begin( 115200 );
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
Serial.println("Start");
void setup() {
Serial.begin(115200);
while(!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
Serial.println("Start");
if (Usb.Init() == -1)
Serial.println("OSCOKIRQ failed to assert");
if(Usb.Init() == -1)
Serial.println("OSCOKIRQ failed to assert");
delay( 200 );
delay(200);
}
void loop()
{
uint8_t rcode;
uint8_t buf[64]; //serial buffer equals Max.packet size of bulk-IN endpoint
uint16_t rcvd = 64;
void loop() {
uint8_t rcode;
uint8_t buf[64]; //serial buffer equals Max.packet size of bulk-IN endpoint
uint16_t rcvd = 64;
Usb.Task();
Usb.Task();
if( Pl.isReady()) {
/* reading the GPS */
if( read_delay < millis() ){
read_delay += READ_DELAY;
rcode = Pl.RcvData(&rcvd, buf);
if ( rcode && rcode != hrNAK )
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
if( rcvd ) { //more than zero bytes received
for( uint16_t i=0; i < rcvd; i++ ) {
Serial.print((char)buf[i]); //printing on the screen
}//for( uint16_t i=0; i < rcvd; i++...
}//if( rcvd
}//if( read_delay > millis()...
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
if(Pl.isReady()) {
/* reading the GPS */
if((long)(millis() - read_delay) >= 0L) {
read_delay += READ_DELAY;
rcode = Pl.RcvData(&rcvd, buf);
if(rcode && rcode != hrNAK)
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
if(rcvd) { //more than zero bytes received
for(uint16_t i = 0; i < rcvd; i++) {
Serial.print((char)buf[i]); //printing on the screen
}//for( uint16_t i=0; i < rcvd; i++...
}//if( rcvd
}//if( read_delay > millis()...
}//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
}

@ -1 +1 @@
Subproject commit da3afff036725584bab36174c1c8441cceba6943
Subproject commit 1edd5f46188a6c4b68d6f9120fa72359a12e38f1

View file

@ -9,6 +9,10 @@
BOARD = mega
PROGRAMMER = arduino
#BOARD = teensypp2
#BOARD = teensy3
#BOARD = teensy31
# set your Arduino tty port here
PORT = /dev/ttyUSB0

@ -1 +1 @@
Subproject commit 9108effe4d4e556198e3e7b95365d1c898680dae
Subproject commit b119b97e1484a08aebcf24e070113d78c82fb023

@ -1 +1 @@
Subproject commit 0b8e3076b5a072251e01cfc6e6333b364d4e71e7
Subproject commit 72b5bf467a1c2479ba7354ee4d864e382c167425

340
examples/testusbhostFAT/testusbhostFAT.ino Normal file → Executable file
View file

@ -19,35 +19,39 @@
*
*/
/////////////////////////////////////////////////////////////
// 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 EXT_RAM_STACK 1
//#define EXT_RAM_HEAP 1
//#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 0
/////////////////////////////////////////////////////////////
// Please Note: This section is for Arduino IDE ONLY. //
// Use of Make creates a flash image that is 3.3KB smaller //
/////////////////////////////////////////////////////////////
#ifndef USING_MAKEFILE
// 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
// These you can safely leave alone.
#define _USE_LFN 3
#define EXT_RAM_STACK 1
#define EXT_RAM_HEAP 1
#define _MAX_SS 512
#endif
/////////////////////////////////////////////////////////////
// End of Arduino IDE specific hacks //
/////////////////////////////////////////////////////////////
#if defined(AVR)
#if defined(__AVR__)
#include <xmem.h>
#else
#include <spi4teensy3.h>
@ -63,7 +67,7 @@
#include <Wire.h>
#include <RTClib.h>
#include <stdio.h>
#if defined(AVR)
#if defined(__AVR__)
static FILE tty_stdio;
static FILE tty_stderr;
volatile uint32_t LEDnext_time; // fade timeout
@ -100,7 +104,7 @@ static storage_t sto[_VOLUMES];
#define mbxs 128
static uint8_t My_Buff_x[mbxs]; /* File read buffer */
#if defined(AVR)
#if defined(__AVR__)
#define prescale1 ((1 << WGM12) | (1 << CS10))
#define prescale8 ((1 << WGM12) | (1 << CS11))
@ -126,7 +130,7 @@ static int tty_std_putc(char c, FILE *t) {
}
static int tty_std_getc(FILE *t) {
while (!Serial.available());
while(!Serial.available());
return Serial.read();
}
@ -140,18 +144,18 @@ extern "C" {
int _write(int fd, const char *ptr, int len) {
int j;
for (j = 0; j < len; j++) {
if (fd == 1)
for(j = 0; j < len; j++) {
if(fd == 1)
Serial.write(*ptr++);
else if (fd == 2)
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());
if(len > 0 && fd == 0) {
while(!Serial.available());
*ptr = Serial.read();
return 1;
}
@ -175,7 +179,7 @@ extern "C" {
void setup() {
boolean serr = false;
for (int i = 0; i < _VOLUMES; i++) {
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
@ -184,7 +188,7 @@ void setup() {
// minimum 0x00, maximum 0xff
UsbDEBUGlvl = 0x51;
#if defined(AVR)
#if !defined(CORE_TEENSY) && defined(__AVR__)
// make LED pin as an output:
pinMode(LED_BUILTIN, OUTPUT);
pinMode(2, OUTPUT);
@ -193,11 +197,23 @@ void setup() {
// Initialize 'debug' serial port
USB_HOST_SERIAL.begin(115200);
// Do not start primary Serial port if already started.
if (bit_is_clear(UCSR0B, TXEN0)) {
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;
@ -212,17 +228,7 @@ void setup() {
stdout = &tty_stdio;
stdin = &tty_stdio;
stderr = &tty_stderr;
// Blink LED
delay(500);
analogWrite(LED_BUILTIN, 255);
delay(500);
analogWrite(LED_BUILTIN, 0);
delay(500);
#else
while (!Serial);
#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"));
@ -236,7 +242,7 @@ void setup() {
"Disabled"
#endif
"\r\n"));
if (serr) {
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: "
@ -247,8 +253,8 @@ void setup() {
#endif
"\r\n"));
}
#if defined(AVR)
#if !defined(CORE_TEENSY) && defined(__AVR__)
analogWrite(LED_BUILTIN, 255);
delay(500);
analogWrite(LED_BUILTIN, 0);
@ -263,7 +269,7 @@ void setup() {
delay(500);
LEDnext_time = millis() + 1;
#ifdef EXT_RAM
#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());
@ -274,22 +280,22 @@ void setup() {
// 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++) {
for(int i = 0; i < MAX_HUBS; i++) {
Hubs[i] = new USBHub(&Usb);
#if defined(AVR)
#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.
InitStorage();
Init_Generic_Storage();
while (Usb.Init(1000) == -1) {
while(Usb.Init(1000) == -1) {
printf_P(PSTR("No USB HOST Shield?\r\n"));
Notify(PSTR("OSC did not start."), 0x40);
}
#if defined(AVR)
#if !defined(CORE_TEENSY) && defined(__AVR__)
cli();
TCCR3A = 0;
TCCR3B = 0;
@ -300,32 +306,10 @@ void setup() {
sei();
HEAPnext_time = millis() + 10000;
#else
#if 0
//
// On the teensy 3 we can raise the speed of SPI here.
//
// Default seen is 0xB8011001.
//
uint32_t ctar = SPI0_CTAR0;
//printf("SPI_CTAR0 = %8.8X\r\n", ctar);
ctar &= 0x7FFCFFF0; // 1/4 fSYS, 12.5Mhz
//printf("SPI_CTAR0 = %8.8X\r\n", ctar);
ctar |= 0x80000000; // 1/2 fSYS 25Mhz
//printf("SPI_CTAR0 = %8.8X\r\n", ctar);
uint32_t mcr = SPI0_MCR;
if (mcr & SPI_MCR_MDIS) {
SPI0_CTAR0 = ctar;
} else {
SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
SPI0_CTAR0 = ctar;
SPI0_MCR = mcr;
}
#endif
#if defined(__AVR__)
HEAPnext_time = millis() + 10000;
#endif
}
void serialEvent() {
@ -334,23 +318,23 @@ void serialEvent() {
// . to increase by 16, , to decrease by 16
// e to flick VBUS
// * to report debug level
if (Serial.available()) {
if(Serial.available()) {
int inByte = Serial.read();
switch (inByte) {
switch(inByte) {
case '+':
if (UsbDEBUGlvl < 0xff) UsbDEBUGlvl++;
if(UsbDEBUGlvl < 0xff) UsbDEBUGlvl++;
reportlvl = true;
break;
case '-':
if (UsbDEBUGlvl > 0x00) UsbDEBUGlvl--;
if(UsbDEBUGlvl > 0x00) UsbDEBUGlvl--;
reportlvl = true;
break;
case '.':
if (UsbDEBUGlvl < 0xf0) UsbDEBUGlvl += 16;
if(UsbDEBUGlvl < 0xf0) UsbDEBUGlvl += 16;
reportlvl = true;
break;
case ',':
if (UsbDEBUGlvl > 0x0f) UsbDEBUGlvl -= 16;
if(UsbDEBUGlvl > 0x0f) UsbDEBUGlvl -= 16;
reportlvl = true;
break;
case '*':
@ -367,10 +351,11 @@ void serialEvent() {
}
}
#if defined(AVR)
#if !defined(CORE_TEENSY) && defined(__AVR__)
// ALL teensy versions LACK PWM ON LED
ISR(TIMER3_COMPA_vect) {
if (millis() >= LEDnext_time) {
if((long)(millis() - LEDnext_time) >= 0L) {
LEDnext_time = millis() + 30;
// set the brightness of LED
@ -380,11 +365,11 @@ ISR(TIMER3_COMPA_vect) {
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness <= 0) {
if(brightness <= 0) {
brightness = 0;
fadeAmount = -fadeAmount;
}
if (brightness >= 255) {
if(brightness >= 255) {
brightness = 255;
fadeAmount = -fadeAmount;
}
@ -404,29 +389,30 @@ void die(FRESULT rc) {
void loop() {
FIL My_File_Object_x; /* File object */
#if defined(AVR)
#if defined(__AVR__)
// Print a heap status report about every 10 seconds.
if (millis() >= HEAPnext_time) {
if (UsbDEBUGlvl > 0x50) {
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;
#else
// Arm suffers here, oh well...
#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 && millis() >= usbon_time) {
if(!change && !usbon && (long)(millis() - usbon_time) >= 0L) {
change = true;
usbon = true;
}
if (change) {
if(change) {
change = false;
if (usbon) {
if(usbon) {
Usb.vbusPower(vbus_on);
printf_P(PSTR("VBUS on\r\n"));
} else {
@ -436,21 +422,21 @@ void loop() {
}
Usb.Task();
current_state = Usb.getUsbTaskState();
if (current_state != last_state) {
if (UsbDEBUGlvl > 0x50)
if(current_state != last_state) {
if(UsbDEBUGlvl > 0x50)
printf_P(PSTR("USB state = %x\r\n"), current_state);
#if defined(AVR)
if (current_state == USB_STATE_RUNNING) {
#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(AVR)
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)
for(int i = 0; i < cpart; i++) {
if(Fats[i] != NULL)
delete Fats[i];
Fats[i] = NULL;
}
@ -462,48 +448,48 @@ void loop() {
}
// only do any of this if usb is on
if (usbon) {
if (partsready && !fatready) {
if (cpart > 0) fatready = true;
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 && (Bulk[B]->GetAddress() != NULL)) {
for(int B = 0; B < MAX_USB_MS_DRIVERS; B++) {
if(!partsready && (UHS_USB_BulkOnly[B]->GetAddress() != NULL)) {
// Build a list.
int ML = Bulk[B]->GetbMaxLUN();
int ML = UHS_USB_BulkOnly[B]->GetbMaxLUN();
//printf("MAXLUN = %i\r\n", ML);
ML++;
for (int i = 0; i < ML; i++) {
if (Bulk[B]->LUNIsGood(i)) {
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].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);
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])) {
if(!PT->Init(&sto[i])) {
part_t *apart;
for (int j = 0; j < 4; j++) {
for(int j = 0; j < 4; j++) {
apart = PT->GetPart(j);
if (apart != NULL && apart->type != 0x00) {
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)) {
if(isfat(parts[cpart].type)) {
Fats[cpart] = new PFAT(&sto[i], cpart, parts[cpart].firstSector);
//int r = Fats[cpart]->Good();
if (Fats[cpart]->MountStatus()) {
if(Fats[cpart]->MountStatus()) {
delete Fats[cpart];
Fats[cpart] = NULL;
} else cpart++;
@ -514,7 +500,7 @@ void loop() {
// try superblock
Fats[cpart] = new PFAT(&sto[i], cpart, 0);
//int r = Fats[cpart]->Good();
if (Fats[cpart]->MountStatus()) {
if(Fats[cpart]->MountStatus()) {
//printf_P(PSTR("Superblock error %x\r\n"), r);
delete Fats[cpart];
Fats[cpart] = NULL;
@ -523,10 +509,9 @@ void loop() {
}
delete PT;
} else {
sto[i].Read = NULL;
sto[i].Write = NULL;
sto[i].Writes = NULL;
sto[i].Reads = NULL;
sto[i].Initialize = NULL;
sto[i].TotalSectors = 0UL;
sto[i].SectorSize = 0;
}
@ -535,18 +520,18 @@ void loop() {
}
}
if (fatready) {
if (Fats[0] != NULL) {
if(fatready) {
if(Fats[0] != NULL) {
struct Pvt * p;
p = ((struct Pvt *)(Fats[0]->storage->private_data));
if (!Bulk[p->B]->LUNIsGood(p->lun)) {
if(!UHS_USB_BulkOnly[p->B]->LUNIsGood(p->lun)) {
// media change
#if defined(AVR)
#if !defined(CORE_TEENSY) && defined(__AVR__)
fadeAmount = 80;
#endif
partsready = false;
for (int i = 0; i < cpart; i++) {
if (Fats[i] != NULL)
for(int i = 0; i < cpart; i++) {
if(Fats[i] != NULL)
delete Fats[i];
Fats[cpart] = NULL;
}
@ -557,62 +542,64 @@ void loop() {
}
}
if (fatready) {
if(fatready) {
FRESULT rc; /* Result code */
UINT bw, br, i;
if (!notified) {
#if defined(AVR)
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);
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 (;;) {
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++) {
if(rc || !br) break; /* Error or end of file */
for(i = 0; i < br; i++) {
/* Type the data */
if (My_Buff_x[i] == '\n')
if(My_Buff_x[i] == '\n')
Serial.write('\r');
if (My_Buff_x[i] != '\r')
if(My_Buff_x[i] != '\r')
Serial.write(My_Buff_x[i]);
Serial.flush();
}
}
if (rc) {
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;
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) {
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) {
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) {
if(rc) {
die(rc);
goto out;
}
outdir:
{
outdir:{
#if _USE_LFN
char lfn[_MAX_LFN + 1];
FILINFO My_File_Info_Object_x; /* File information object */
@ -621,55 +608,55 @@ outdir:
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) {
if(rc) {
die(rc);
goto out;
}
printf_P(PSTR("\r\nDirectory listing...\r\n"));
#if defined(AVR)
#if defined(__AVR__)
printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap());
#endif
for (;;) {
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(rc || !My_File_Info_Object_x.fname[0]) break; /* Error or end of dir */
if (My_File_Info_Object_x.fattrib & AM_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) {
if(My_File_Info_Object_x.fattrib & AM_RDO) {
Serial.write('-');
} else {
Serial.write('w');
}
if (My_File_Info_Object_x.fattrib & AM_HID) {
if(My_File_Info_Object_x.fattrib & AM_HID) {
Serial.write('h');
} else {
Serial.write('-');
}
if (My_File_Info_Object_x.fattrib & AM_SYS) {
if(My_File_Info_Object_x.fattrib & AM_SYS) {
Serial.write('s');
} else {
Serial.write('-');
}
if (My_File_Info_Object_x.fattrib & AM_ARC) {
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)
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
@ -677,48 +664,55 @@ outdir:
}
}
out:
if (rc) die(rc);
if(rc) die(rc);
DISK_IOCTL(fs->drv, CTRL_COMMIT, 0);
printf_P(PSTR("\r\nTest completed.\r\n"));
}
if (runtest) {
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;
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--) {
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;
if(rc || !bw) goto failed;
}
rc = f_close(&My_File_Object_x);
if (rc) goto failed;
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 (;;) {
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 */
if(rc || !bw) break; /* Error or end of file */
}
end = millis();
if (rc) goto failed;
if(rc) goto failed;
rc = f_close(&My_File_Object_x);
if (rc) goto failed;
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);
if(rc) die(rc);
DISK_IOCTL(fs->drv, CTRL_COMMIT, 0);
printf_P(PSTR("10MB timing test finished.\r\n"));
}
}

@ -1 +1 @@
Subproject commit 4226cc772c3e0d5fa71871dd6f8a28fa26dc692c
Subproject commit 2bf8f633e7f9bc5a7bf4c00f3f45c7b79484198e

View file

@ -536,7 +536,7 @@ template <const uint8_t BOOT_PROTOCOL>
uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
uint8_t rcode = 0;
if(bPollEnable && qNextPollTime <= millis()) {
if(bPollEnable && ((long)(millis() - qNextPollTime) >= 0L)) {
// To-do: optimize manually, using the for loop only if needed.
for(int i = 0; i < epMUL(BOOT_PROTOCOL); i++) {

View file

@ -370,7 +370,7 @@ uint8_t HIDUniversal::Poll() {
if(!bPollEnable)
return 0;
if(qNextPollTime <= millis()) {
if((long)(millis() - qNextPollTime) >= 0L) {
qNextPollTime = millis() + pollInterval;
uint8_t buf[constBuffLen];
@ -398,11 +398,13 @@ uint8_t HIDUniversal::Poll() {
if(identical)
return 0;
#if 1
#if 0
Notify(PSTR("\r\nBuf: "), 0x80);
for(uint8_t i = 0; i < read; i++)
for(uint8_t i = 0; i < read; i++) {
D_PrintHex<uint8_t > (buf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
Notify(PSTR("\r\n"), 0x80);
#endif

View file

@ -319,7 +319,7 @@ getIRy4 KEYWORD2
getIRs4 KEYWORD2
####################################################
# Syntax Coloring Map For RFCOMM/SPP Library
# Syntax Coloring Map For BTHID Library
####################################################
####################################################
@ -332,4 +332,31 @@ BTHID KEYWORD1
# Methods and Functions (KEYWORD2)
####################################################
SetReportParser KEYWORD2
setProtocolMode KEYWORD2
setProtocolMode KEYWORD2
####################################################
# Syntax Coloring Map For PS Buzz Library
####################################################
####################################################
# Datatypes (KEYWORD1)
####################################################
PSBuzz KEYWORD1
####################################################
# Methods and Functions (KEYWORD2)
####################################################
setLedOnAll KEYWORD2
setLedOffAll KEYWORD2
####################################################
# Constants and enums (LITERAL1)
####################################################
RED LITERAL1
YELLOW LITERAL1
GREEN LITERAL1
ORANGE LITERAL1
BLUE LITERAL1

View file

@ -549,6 +549,20 @@ void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t
uint8_t index;
#if 1
if((pep->bmAttributes & 0x02) == 2) {
index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
// Fill in the endpoint info structure
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[index].epAttribs = 0;
bNumEP++;
PrintEndpointDescriptor(pep);
}
#else
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
index = epInterruptInIndex;
else
@ -565,6 +579,7 @@ void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t
bNumEP++;
PrintEndpointDescriptor(pep);
#endif
}
/**
@ -656,7 +671,7 @@ uint8_t BulkOnly::Poll() {
if(!bPollEnable)
return 0;
if(qNextPollTime <= millis()) {
if((long)(millis() - qNextPollTime) >= 0L) {
CheckMedia();
}
//rcode = 0;

View file

@ -230,7 +230,7 @@ uint8_t USBHub::Poll() {
if(!bPollEnable)
return 0;
if(qNextPollTime <= millis()) {
if(((long)(millis() - qNextPollTime) >= 0L)) {
rcode = CheckHubStatus();
qNextPollTime = millis() + 100;
}