1
0
Fork 0

Squashed 'tmk_core/' changes from 7967731..b9e0ea0

b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk'
7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5

git-subtree-dir: tmk_core
git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
This commit is contained in:
Jun Wako 2015-04-24 16:26:14 +09:00
parent a20ef7052c
commit 1fe4406f37
4198 changed files with 2016457 additions and 0 deletions

View file

@ -0,0 +1,89 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MTXCIRCBUFFER_H
#define MTXCIRCBUFFER_H
#include "stdint.h"
#include "rtos.h"
//Mutex protected circular buffer
template<typename T, int size>
class MtxCircBuffer {
public:
MtxCircBuffer() {
write = 0;
read = 0;
}
bool isFull() {
mtx.lock();
bool r = (((write + 1) % size) == read);
mtx.unlock();
return r;
}
bool isEmpty() {
mtx.lock();
bool r = (read == write);
mtx.unlock();
return r;
}
void flush() {
write = 0;
read = 0;
}
void queue(T k) {
mtx.lock();
while (((write + 1) % size) == read) {
mtx.unlock();
Thread::wait(10);
mtx.lock();
}
buf[write++] = k;
write %= size;
mtx.unlock();
}
uint16_t available() {
mtx.lock();
uint16_t a = (write >= read) ? (write - read) : (size - read + write);
mtx.unlock();
return a;
}
bool dequeue(T * c) {
mtx.lock();
bool empty = (read == write);
if (!empty) {
*c = buf[read++];
read %= size;
}
mtx.unlock();
return (!empty);
}
private:
volatile uint16_t write;
volatile uint16_t read;
volatile T buf[size];
Mutex mtx;
};
#endif

View file

@ -0,0 +1,345 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "USBHostSerial.h"
#if USBHOST_SERIAL
#include "dbg.h"
#define CHECK_INTERFACE(cls,subcls,proto) \
(((cls == 0xFF) && (subcls == 0xFF) && (proto == 0xFF)) /* QUALCOM CDC */ || \
((cls == SERIAL_CLASS) && (subcls == 0x00) && (proto == 0x00)) /* STANDARD CDC */ )
#if (USBHOST_SERIAL <= 1)
USBHostSerial::USBHostSerial()
{
host = USBHost::getHostInst();
ports_found = 0;
dev_connected = false;
}
bool USBHostSerial::connected()
{
return dev_connected;
}
void USBHostSerial::disconnect(void)
{
ports_found = 0;
dev = NULL;
}
bool USBHostSerial::connect() {
if (dev)
{
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (dev == d)
return true;
}
disconnect();
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (d != NULL) {
USB_DBG("Trying to connect serial device \r\n");
if(host->enumerate(d, this))
break;
USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN);
USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT);
if (bulk_in && bulk_out)
{
USBHostSerialPort::connect(host,d,port_intf,bulk_in, bulk_out);
dev = d;
dev_connected = true;
}
}
}
return dev != NULL;
}
/*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for MSD driver
}
/*virtual*/ bool USBHostSerial::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if (!ports_found &&
CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
port_intf = intf_nb;
ports_found = true;
return true;
}
return false;
}
/*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if (ports_found && (intf_nb == port_intf)) {
if (type == BULK_ENDPOINT)
return true;
}
return false;
}
#else // (USBHOST_SERIAL > 1)
//------------------------------------------------------------------------------
USBHostMultiSerial::USBHostMultiSerial()
{
host = USBHost::getHostInst();
dev = NULL;
memset(ports, NULL, sizeof(ports));
ports_found = 0;
dev_connected = false;
}
USBHostMultiSerial::~USBHostMultiSerial()
{
disconnect();
}
bool USBHostMultiSerial::connected()
{
return dev_connected;
}
void USBHostMultiSerial::disconnect(void)
{
for (int port = 0; port < USBHOST_SERIAL; port ++)
{
if (ports[port])
{
delete ports[port];
ports[port] = NULL;
}
}
ports_found = 0;
dev = NULL;
}
bool USBHostMultiSerial::connect() {
if (dev)
{
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (dev == d)
return true;
}
disconnect();
}
for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
{
USBDeviceConnected* d = host->getDevice(i);
if (d != NULL) {
USB_DBG("Trying to connect serial device \r\n");
if(host->enumerate(d, this))
break;
for (int port = 0; port < ports_found; port ++)
{
USBEndpoint* bulk_in = d->getEndpoint(port_intf[port], BULK_ENDPOINT, IN);
USBEndpoint* bulk_out = d->getEndpoint(port_intf[port], BULK_ENDPOINT, OUT);
if (bulk_in && bulk_out)
{
ports[port] = new USBHostSerialPort();
if (ports[port])
{
ports[port]->connect(host,d,port_intf[port],bulk_in, bulk_out);
dev = d;
dev_connected = true;
}
}
}
}
}
return dev != NULL;
}
/*virtual*/ void USBHostMultiSerial::setVidPid(uint16_t vid, uint16_t pid)
{
// we don't check VID/PID for MSD driver
}
/*virtual*/ bool USBHostMultiSerial::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
if ((ports_found < USBHOST_SERIAL) &&
CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
port_intf[ports_found++] = intf_nb;
return true;
}
return false;
}
/*virtual*/ bool USBHostMultiSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
{
if ((ports_found > 0) && (intf_nb == port_intf[ports_found-1])) {
if (type == BULK_ENDPOINT)
return true;
}
return false;
}
#endif
//------------------------------------------------------------------------------
#define SET_LINE_CODING 0x20
USBHostSerialPort::USBHostSerialPort(): circ_buf()
{
init();
}
void USBHostSerialPort::init(void)
{
host = NULL;
dev = NULL;
serial_intf = NULL;
size_bulk_in = 0;
size_bulk_out = 0;
bulk_in = NULL;
bulk_out = NULL;
line_coding.baudrate = 9600;
line_coding.data_bits = 8;
line_coding.parity = None;
line_coding.stop_bits = 1;
circ_buf.flush();
}
void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev,
uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out)
{
host = _host;
dev = _dev;
serial_intf = _serial_intf;
bulk_in = _bulk_in;
bulk_out = _bulk_out;
USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf);
dev->setName("Serial", serial_intf);
host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init);
baud(9600);
size_bulk_in = bulk_in->getSize();
size_bulk_out = bulk_out->getSize();
bulk_in->attach(this, &USBHostSerialPort::rxHandler);
bulk_out->attach(this, &USBHostSerialPort::txHandler);
host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
}
void USBHostSerialPort::rxHandler() {
if (bulk_in) {
int len = bulk_in->getLengthTransferred();
if (bulk_in->getState() == USB_TYPE_IDLE) {
for (int i = 0; i < len; i++) {
circ_buf.queue(buf[i]);
}
rx.call();
host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
}
}
}
void USBHostSerialPort::txHandler() {
if (bulk_out) {
if (bulk_out->getState() == USB_TYPE_IDLE) {
tx.call();
}
}
}
int USBHostSerialPort::_putc(int c) {
if (bulk_out) {
if (host->bulkWrite(dev, bulk_out, (uint8_t *)&c, 1) == USB_TYPE_OK) {
return 1;
}
}
return -1;
}
void USBHostSerialPort::baud(int baudrate) {
line_coding.baudrate = baudrate;
format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits);
}
void USBHostSerialPort::format(int bits, Parity parity, int stop_bits) {
line_coding.data_bits = bits;
line_coding.parity = parity;
line_coding.stop_bits = (stop_bits == 1) ? 0 : 2;
// set line coding
host->controlWrite( dev,
USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
SET_LINE_CODING,
0, serial_intf, (uint8_t *)&line_coding, 7);
}
int USBHostSerialPort::_getc() {
uint8_t c = 0;
if (bulk_in == NULL) {
init();
return -1;
}
while (circ_buf.isEmpty());
circ_buf.dequeue(&c);
return c;
}
int USBHostSerialPort::writeBuf(const char* b, int s)
{
int c = 0;
if (bulk_out)
{
while (c < s)
{
int i = (s < size_bulk_out) ? s : size_bulk_out;
if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK)
c += i;
}
}
return s;
}
int USBHostSerialPort::readBuf(char* b, int s)
{
int i = 0;
if (bulk_in)
{
for (i = 0; i < s; )
b[i++] = getc();
}
return i;
}
uint8_t USBHostSerialPort::available() {
return circ_buf.available();
}
#endif

View file

@ -0,0 +1,231 @@
/* mbed USBHost Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef USBHOSTSERIAL_H
#define USBHOSTSERIAL_H
#include "USBHostConf.h"
#if USBHOST_SERIAL
#include "USBHost.h"
#include "Stream.h"
#include "MtxCircBuffer.h"
/**
* A class to communicate a USB virtual serial port
*/
class USBHostSerialPort : public Stream {
public:
/**
* Constructor
*/
USBHostSerialPort();
enum IrqType {
RxIrq,
TxIrq
};
enum Parity {
None = 0,
Odd,
Even,
Mark,
Space
};
void connect(USBHost* _host, USBDeviceConnected * _dev,
uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out);
/**
* Check the number of bytes available.
*
* @returns the number of bytes available
*/
uint8_t available();
/**
* Attach a member function to call when a packet is received.
*
* @param tptr pointer to the object to call the member function on
* @param mptr pointer to the member function to be called
* @param irq irq type
*/
template<typename T>
inline void attach(T* tptr, void (T::*mptr)(void), IrqType irq = RxIrq) {
if ((mptr != NULL) && (tptr != NULL)) {
if (irq == RxIrq) {
rx.attach(tptr, mptr);
} else {
tx.attach(tptr, mptr);
}
}
}
/**
* Attach a callback called when a packet is received
*
* @param ptr function pointer
*/
inline void attach(void (*fn)(void), IrqType irq = RxIrq) {
if (fn != NULL) {
if (irq == RxIrq) {
rx.attach(fn);
} else {
tx.attach(fn);
}
}
}
/** Set the baud rate of the serial port
*
* @param baudrate The baudrate of the serial port (default = 9600).
*/
void baud(int baudrate = 9600);
/** Set the transmission format used by the Serial port
*
* @param bits The number of bits in a word (default = 8)
* @param parity The parity used (USBHostSerialPort::None, USBHostSerialPort::Odd, USBHostSerialPort::Even, USBHostSerialPort::Mark, USBHostSerialPort::Space; default = USBHostSerialPort::None)
* @param stop The number of stop bits (1 or 2; default = 1)
*/
void format(int bits = 8, Parity parity = USBHostSerialPort::None, int stop_bits = 1);
virtual int writeBuf(const char* b, int s);
virtual int readBuf(char* b, int s);
protected:
virtual int _getc();
virtual int _putc(int c);
private:
USBHost * host;
USBDeviceConnected * dev;
USBEndpoint * bulk_in;
USBEndpoint * bulk_out;
uint32_t size_bulk_in;
uint32_t size_bulk_out;
void init();
MtxCircBuffer<uint8_t, 128> circ_buf;
uint8_t buf[64];
typedef struct {
uint32_t baudrate;
uint8_t stop_bits;
uint8_t parity;
uint8_t data_bits;
} PACKED LINE_CODING;
LINE_CODING line_coding;
void rxHandler();
void txHandler();
FunctionPointer rx;
FunctionPointer tx;
uint8_t serial_intf;
};
#if (USBHOST_SERIAL <= 1)
class USBHostSerial : public IUSBEnumerator, public USBHostSerialPort
{
public:
USBHostSerial();
/**
* Try to connect a serial device
*
* @return true if connection was successful
*/
bool connect();
void disconnect();
/**
* Check if a any serial port is connected
*
* @returns true if a serial device is connected
*/
bool connected();
protected:
USBHost* host;
USBDeviceConnected* dev;
uint8_t port_intf;
int ports_found;
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
bool dev_connected;
};
#else // (USBHOST_SERIAL > 1)
class USBHostMultiSerial : public IUSBEnumerator {
public:
USBHostMultiSerial();
virtual ~USBHostMultiSerial();
USBHostSerialPort* getPort(int port)
{
return port < USBHOST_SERIAL ? ports[port] : NULL;
}
/**
* Try to connect a serial device
*
* @return true if connection was successful
*/
bool connect();
void disconnect();
/**
* Check if a any serial port is connected
*
* @returns true if a serial device is connected
*/
bool connected();
protected:
USBHost* host;
USBDeviceConnected* dev;
USBHostSerialPort* ports[USBHOST_SERIAL];
uint8_t port_intf[USBHOST_SERIAL];
int ports_found;
//From IUSBEnumerator
virtual void setVidPid(uint16_t vid, uint16_t pid);
virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
private:
bool dev_connected;
};
#endif // (USBHOST_SERIAL <= 1)
#endif
#endif