Add Core implementation
This commit is contained in:
parent
76abb70916
commit
c5d1469296
|
@ -0,0 +1,193 @@
|
||||||
|
/*
|
||||||
|
Arduino.h - Main include file for the Arduino SDK
|
||||||
|
Copyright (c) 2005-2013 Arduino Team. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Arduino_h
|
||||||
|
#define Arduino_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// #include <avr/pgmspace.h>
|
||||||
|
// #include <avr/io.h>
|
||||||
|
// #include <avr/interrupt.h>
|
||||||
|
|
||||||
|
//#include "binary.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void yield(void);
|
||||||
|
|
||||||
|
#define HIGH 0x1
|
||||||
|
#define LOW 0x0
|
||||||
|
|
||||||
|
#define INPUT 0x0
|
||||||
|
#define OUTPUT 0x1
|
||||||
|
#define INPUT_PULLUP 0x2
|
||||||
|
#define INPUT_PULLDOWN 0x3
|
||||||
|
|
||||||
|
#define PI 3.1415926535897932384626433832795
|
||||||
|
#define HALF_PI 1.5707963267948966192313216916398
|
||||||
|
#define TWO_PI 6.283185307179586476925286766559
|
||||||
|
#define DEG_TO_RAD 0.017453292519943295769236907684886
|
||||||
|
#define RAD_TO_DEG 57.295779513082320876798154814105
|
||||||
|
#define EULER 2.718281828459045235360287471352
|
||||||
|
|
||||||
|
#define SERIAL 0x0
|
||||||
|
#define DISPLAY 0x1
|
||||||
|
|
||||||
|
#define LSBFIRST 0
|
||||||
|
#define MSBFIRST 1
|
||||||
|
|
||||||
|
#define CHANGE 1
|
||||||
|
#define FALLING 2
|
||||||
|
#define RISING 3
|
||||||
|
|
||||||
|
|
||||||
|
#define min(a,b) ((a)<(b)?(a):(b))
|
||||||
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
|
#define abs(x) ((x)>0?(x):-(x))
|
||||||
|
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||||
|
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||||
|
#define radians(deg) ((deg)*DEG_TO_RAD)
|
||||||
|
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
||||||
|
#define sq(x) ((x)*(x))
|
||||||
|
|
||||||
|
#define interrupts() sei()
|
||||||
|
#define noInterrupts() cli()
|
||||||
|
|
||||||
|
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
||||||
|
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
||||||
|
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
|
||||||
|
|
||||||
|
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
||||||
|
#define highByte(w) ((uint8_t) ((w) >> 8))
|
||||||
|
|
||||||
|
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||||
|
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||||
|
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||||
|
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
||||||
|
|
||||||
|
// avr-libc defines _NOP() since 1.6.2
|
||||||
|
#ifndef _NOP
|
||||||
|
#define _NOP() do { __asm__ volatile ("nop"); } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned int word;
|
||||||
|
|
||||||
|
#define bit(b) (1UL << (b))
|
||||||
|
|
||||||
|
typedef bool boolean;
|
||||||
|
typedef uint8_t byte;
|
||||||
|
|
||||||
|
void init(void);
|
||||||
|
void initVariant(void);
|
||||||
|
|
||||||
|
int atexit(void (*func)()) __attribute__((weak));
|
||||||
|
|
||||||
|
void pinMode(uint8_t, uint8_t);
|
||||||
|
void digitalWrite(uint8_t, uint8_t);
|
||||||
|
int digitalRead(uint8_t);
|
||||||
|
int analogRead(uint8_t);
|
||||||
|
void analogReference(uint8_t mode);
|
||||||
|
void analogWrite(uint8_t, int);
|
||||||
|
|
||||||
|
unsigned long millis(void);
|
||||||
|
unsigned long micros(void);
|
||||||
|
void delay(unsigned long);
|
||||||
|
void delayMicroseconds(unsigned int us);
|
||||||
|
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
|
||||||
|
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout);
|
||||||
|
|
||||||
|
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
||||||
|
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
|
||||||
|
|
||||||
|
void attachInterrupt(uint8_t, void (*)(void), int mode);
|
||||||
|
void detachInterrupt(uint8_t);
|
||||||
|
|
||||||
|
void setup(void);
|
||||||
|
void loop(void);
|
||||||
|
|
||||||
|
// Get the bit location within the hardware port of the given virtual pin.
|
||||||
|
// This comes from the pins_*.c file for the active board configuration.
|
||||||
|
|
||||||
|
#define analogInPinToBit(P) (P)
|
||||||
|
|
||||||
|
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
|
||||||
|
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
|
||||||
|
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
|
||||||
|
#define analogInPinToBit(P) (P)
|
||||||
|
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
|
||||||
|
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
|
||||||
|
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
|
||||||
|
|
||||||
|
#define NOT_A_PIN 0
|
||||||
|
#define NOT_A_PORT 0
|
||||||
|
|
||||||
|
#define NOT_AN_INTERRUPT -1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
//#include "WCharacter.h"
|
||||||
|
//#include "WString.h"
|
||||||
|
//#include "HardwareSerial.h"
|
||||||
|
//#include "USBAPI.h"
|
||||||
|
#if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL)
|
||||||
|
#error "Targets with both UART0 and CDC serial not supported"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint16_t makeWord(uint16_t w);
|
||||||
|
uint16_t makeWord(byte h, byte l);
|
||||||
|
|
||||||
|
#define word(...) makeWord(__VA_ARGS__)
|
||||||
|
|
||||||
|
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||||
|
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||||
|
|
||||||
|
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
|
||||||
|
void noTone(uint8_t _pin);
|
||||||
|
|
||||||
|
// WMath prototypes
|
||||||
|
long random(long);
|
||||||
|
long random(long, long);
|
||||||
|
void randomSeed(unsigned long);
|
||||||
|
long map(long, long, long, long, long);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "stm32_def.h"
|
||||||
|
#include "stm32_clock.h"
|
||||||
|
#include "stm32_gpio.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "SerialUART.h"
|
||||||
|
#include "USBSerial.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,266 @@
|
||||||
|
/*
|
||||||
|
Print.cpp - Base class that provides print() and println()
|
||||||
|
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Modified 23 November 2006 by David A. Mellis
|
||||||
|
Modified 03 August 2015 by Chuck Todd
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#include "Print.h"
|
||||||
|
|
||||||
|
// Public Methods //////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/* default implementation: may be overridden */
|
||||||
|
size_t Print::write(const uint8_t *buffer, size_t size)
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
while (size--) {
|
||||||
|
if (write(*buffer++)) n++;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(const __FlashStringHelper *ifsh)
|
||||||
|
{
|
||||||
|
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
|
||||||
|
size_t n = 0;
|
||||||
|
while (1) {
|
||||||
|
unsigned char c = pgm_read_byte(p++);
|
||||||
|
if (c == 0) break;
|
||||||
|
if (write(c)) n++;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(const String &s)
|
||||||
|
{
|
||||||
|
return write(s.c_str(), s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(const char str[])
|
||||||
|
{
|
||||||
|
return write(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(char c)
|
||||||
|
{
|
||||||
|
return write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(unsigned char b, int base)
|
||||||
|
{
|
||||||
|
return print((unsigned long) b, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(int n, int base)
|
||||||
|
{
|
||||||
|
return print((long) n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(unsigned int n, int base)
|
||||||
|
{
|
||||||
|
return print((unsigned long) n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(long n, int base)
|
||||||
|
{
|
||||||
|
if (base == 0) {
|
||||||
|
return write(n);
|
||||||
|
} else if (base == 10) {
|
||||||
|
if (n < 0) {
|
||||||
|
int t = print('-');
|
||||||
|
n = -n;
|
||||||
|
return printNumber(n, 10) + t;
|
||||||
|
}
|
||||||
|
return printNumber(n, 10);
|
||||||
|
} else {
|
||||||
|
return printNumber(n, base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(unsigned long n, int base)
|
||||||
|
{
|
||||||
|
if (base == 0) return write(n);
|
||||||
|
else return printNumber(n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(double n, int digits)
|
||||||
|
{
|
||||||
|
return printFloat(n, digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(const __FlashStringHelper *ifsh)
|
||||||
|
{
|
||||||
|
size_t n = print(ifsh);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::print(const Printable& x)
|
||||||
|
{
|
||||||
|
return x.printTo(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(void)
|
||||||
|
{
|
||||||
|
return write("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(const String &s)
|
||||||
|
{
|
||||||
|
size_t n = print(s);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(const char c[])
|
||||||
|
{
|
||||||
|
size_t n = print(c);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(char c)
|
||||||
|
{
|
||||||
|
size_t n = print(c);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(unsigned char b, int base)
|
||||||
|
{
|
||||||
|
size_t n = print(b, base);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(int num, int base)
|
||||||
|
{
|
||||||
|
size_t n = print(num, base);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(unsigned int num, int base)
|
||||||
|
{
|
||||||
|
size_t n = print(num, base);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(long num, int base)
|
||||||
|
{
|
||||||
|
size_t n = print(num, base);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(unsigned long num, int base)
|
||||||
|
{
|
||||||
|
size_t n = print(num, base);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(double num, int digits)
|
||||||
|
{
|
||||||
|
size_t n = print(num, digits);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::println(const Printable& x)
|
||||||
|
{
|
||||||
|
size_t n = print(x);
|
||||||
|
n += println();
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private Methods /////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
size_t Print::printNumber(unsigned long n, uint8_t base)
|
||||||
|
{
|
||||||
|
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
|
||||||
|
char *str = &buf[sizeof(buf) - 1];
|
||||||
|
|
||||||
|
*str = '\0';
|
||||||
|
|
||||||
|
// prevent crash if called with base == 1
|
||||||
|
if (base < 2) base = 10;
|
||||||
|
|
||||||
|
do {
|
||||||
|
char c = n % base;
|
||||||
|
n /= base;
|
||||||
|
|
||||||
|
*--str = c < 10 ? c + '0' : c + 'A' - 10;
|
||||||
|
} while(n);
|
||||||
|
|
||||||
|
return write(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Print::printFloat(double number, uint8_t digits)
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
if (isnan(number)) return print("nan");
|
||||||
|
if (isinf(number)) return print("inf");
|
||||||
|
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
|
||||||
|
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
|
||||||
|
|
||||||
|
// Handle negative numbers
|
||||||
|
if (number < 0.0)
|
||||||
|
{
|
||||||
|
n += print('-');
|
||||||
|
number = -number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||||
|
double rounding = 0.5;
|
||||||
|
for (uint8_t i=0; i<digits; ++i)
|
||||||
|
rounding /= 10.0;
|
||||||
|
|
||||||
|
number += rounding;
|
||||||
|
|
||||||
|
// Extract the integer part of the number and print it
|
||||||
|
unsigned long int_part = (unsigned long)number;
|
||||||
|
double remainder = number - (double)int_part;
|
||||||
|
n += print(int_part);
|
||||||
|
|
||||||
|
// Print the decimal point, but only if there are digits beyond
|
||||||
|
if (digits > 0) {
|
||||||
|
n += print('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract digits from the remainder one at a time
|
||||||
|
while (digits-- > 0)
|
||||||
|
{
|
||||||
|
remainder *= 10.0;
|
||||||
|
unsigned int toPrint = (unsigned int)(remainder);
|
||||||
|
n += print(toPrint);
|
||||||
|
remainder -= toPrint;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
Print.h - Base class that provides print() and println()
|
||||||
|
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Print_h
|
||||||
|
#define Print_h
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h> // for size_t
|
||||||
|
|
||||||
|
#include "WString.h"
|
||||||
|
#include "Printable.h"
|
||||||
|
|
||||||
|
#define DEC 10
|
||||||
|
#define HEX 16
|
||||||
|
#define OCT 8
|
||||||
|
#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar
|
||||||
|
#undef BIN
|
||||||
|
#endif
|
||||||
|
#define BIN 2
|
||||||
|
|
||||||
|
class Print
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int write_error;
|
||||||
|
size_t printNumber(unsigned long, uint8_t);
|
||||||
|
size_t printFloat(double, uint8_t);
|
||||||
|
protected:
|
||||||
|
void setWriteError(int err = 1) { write_error = err; }
|
||||||
|
public:
|
||||||
|
Print() : write_error(0) {}
|
||||||
|
|
||||||
|
int getWriteError() { return write_error; }
|
||||||
|
void clearWriteError() { setWriteError(0); }
|
||||||
|
|
||||||
|
virtual size_t write(uint8_t) = 0;
|
||||||
|
size_t write(const char *str) {
|
||||||
|
if (str == NULL) return 0;
|
||||||
|
return write((const uint8_t *)str, strlen(str));
|
||||||
|
}
|
||||||
|
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||||
|
size_t write(const char *buffer, size_t size) {
|
||||||
|
return write((const uint8_t *)buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t print(const __FlashStringHelper *);
|
||||||
|
size_t print(const String &);
|
||||||
|
size_t print(const char[]);
|
||||||
|
size_t print(char);
|
||||||
|
size_t print(unsigned char, int = DEC);
|
||||||
|
size_t print(int, int = DEC);
|
||||||
|
size_t print(unsigned int, int = DEC);
|
||||||
|
size_t print(long, int = DEC);
|
||||||
|
size_t print(unsigned long, int = DEC);
|
||||||
|
size_t print(double, int = 2);
|
||||||
|
size_t print(const Printable&);
|
||||||
|
|
||||||
|
size_t println(const __FlashStringHelper *);
|
||||||
|
size_t println(const String &s);
|
||||||
|
size_t println(const char[]);
|
||||||
|
size_t println(char);
|
||||||
|
size_t println(unsigned char, int = DEC);
|
||||||
|
size_t println(int, int = DEC);
|
||||||
|
size_t println(unsigned int, int = DEC);
|
||||||
|
size_t println(long, int = DEC);
|
||||||
|
size_t println(unsigned long, int = DEC);
|
||||||
|
size_t println(double, int = 2);
|
||||||
|
size_t println(const Printable&);
|
||||||
|
size_t println(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
Printable.h - Interface class that allows printing of complex types
|
||||||
|
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Printable_h
|
||||||
|
#define Printable_h
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
class Print;
|
||||||
|
|
||||||
|
/** The Printable class provides a way for new classes to allow themselves to be printed.
|
||||||
|
By deriving from Printable and implementing the printTo method, it will then be possible
|
||||||
|
for users to print out instances of this class by passing them into the usual
|
||||||
|
Print::print and Print::println methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Printable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual size_t printTo(Print& p) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,319 @@
|
||||||
|
/*
|
||||||
|
Stream.cpp - adds parsing methods to Stream class
|
||||||
|
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Created July 2011
|
||||||
|
parsing functions based on TextFinder library by Michael Margolis
|
||||||
|
|
||||||
|
findMulti/findUntil routines written by Jim Leonard/Xuth
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "Stream.h"
|
||||||
|
|
||||||
|
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
|
||||||
|
|
||||||
|
// private method to read stream with timeout
|
||||||
|
int Stream::timedRead()
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
_startMillis = millis();
|
||||||
|
do {
|
||||||
|
c = read();
|
||||||
|
if (c >= 0) return c;
|
||||||
|
} while(millis() - _startMillis < _timeout);
|
||||||
|
return -1; // -1 indicates timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
// private method to peek stream with timeout
|
||||||
|
int Stream::timedPeek()
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
_startMillis = millis();
|
||||||
|
do {
|
||||||
|
c = peek();
|
||||||
|
if (c >= 0) return c;
|
||||||
|
} while(millis() - _startMillis < _timeout);
|
||||||
|
return -1; // -1 indicates timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns peek of the next digit in the stream or -1 if timeout
|
||||||
|
// discards non-numeric characters
|
||||||
|
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
while (1) {
|
||||||
|
c = timedPeek();
|
||||||
|
|
||||||
|
if( c < 0 ||
|
||||||
|
c == '-' ||
|
||||||
|
(c >= '0' && c <= '9') ||
|
||||||
|
(detectDecimal && c == '.')) return c;
|
||||||
|
|
||||||
|
switch( lookahead ){
|
||||||
|
case SKIP_NONE: return -1; // Fail code.
|
||||||
|
case SKIP_WHITESPACE:
|
||||||
|
switch( c ){
|
||||||
|
case ' ':
|
||||||
|
case '\t':
|
||||||
|
case '\r':
|
||||||
|
case '\n': break;
|
||||||
|
default: return -1; // Fail code.
|
||||||
|
}
|
||||||
|
case SKIP_ALL:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
read(); // discard non-numeric
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public Methods
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
|
||||||
|
{
|
||||||
|
_timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find returns true if the target string is found
|
||||||
|
bool Stream::find(char *target)
|
||||||
|
{
|
||||||
|
return findUntil(target, strlen(target), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads data from the stream until the target string of given length is found
|
||||||
|
// returns true if target string is found, false if timed out
|
||||||
|
bool Stream::find(char *target, size_t length)
|
||||||
|
{
|
||||||
|
return findUntil(target, length, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// as find but search ends if the terminator string is found
|
||||||
|
bool Stream::findUntil(char *target, char *terminator)
|
||||||
|
{
|
||||||
|
return findUntil(target, strlen(target), terminator, strlen(terminator));
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads data from the stream until the target string of the given length is found
|
||||||
|
// search terminated if the terminator string is found
|
||||||
|
// returns true if target string is found, false if terminated or timed out
|
||||||
|
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
|
||||||
|
{
|
||||||
|
if (terminator == NULL) {
|
||||||
|
MultiTarget t[1] = {{target, targetLen, 0}};
|
||||||
|
return findMulti(t, 1) == 0 ? true : false;
|
||||||
|
} else {
|
||||||
|
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
|
||||||
|
return findMulti(t, 2) == 0 ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the first valid (long) integer value from the current position.
|
||||||
|
// lookahead determines how parseInt looks ahead in the stream.
|
||||||
|
// See LookaheadMode enumeration at the top of the file.
|
||||||
|
// Lookahead is terminated by the first character that is not a valid part of an integer.
|
||||||
|
// Once parsing commences, 'ignore' will be skipped in the stream.
|
||||||
|
long Stream::parseInt(LookaheadMode lookahead, char ignore)
|
||||||
|
{
|
||||||
|
bool isNegative = false;
|
||||||
|
long value = 0;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
c = peekNextDigit(lookahead, false);
|
||||||
|
// ignore non numeric leading characters
|
||||||
|
if(c < 0)
|
||||||
|
return 0; // zero returned if timeout
|
||||||
|
|
||||||
|
do{
|
||||||
|
if(c == ignore)
|
||||||
|
; // ignore this character
|
||||||
|
else if(c == '-')
|
||||||
|
isNegative = true;
|
||||||
|
else if(c >= '0' && c <= '9') // is c a digit?
|
||||||
|
value = value * 10 + c - '0';
|
||||||
|
read(); // consume the character we got with peek
|
||||||
|
c = timedPeek();
|
||||||
|
}
|
||||||
|
while( (c >= '0' && c <= '9') || c == ignore );
|
||||||
|
|
||||||
|
if(isNegative)
|
||||||
|
value = -value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// as parseInt but returns a floating point value
|
||||||
|
float Stream::parseFloat(LookaheadMode lookahead, char ignore)
|
||||||
|
{
|
||||||
|
bool isNegative = false;
|
||||||
|
bool isFraction = false;
|
||||||
|
long value = 0;
|
||||||
|
int c;
|
||||||
|
float fraction = 1.0;
|
||||||
|
|
||||||
|
c = peekNextDigit(lookahead, true);
|
||||||
|
// ignore non numeric leading characters
|
||||||
|
if(c < 0)
|
||||||
|
return 0; // zero returned if timeout
|
||||||
|
|
||||||
|
do{
|
||||||
|
if(c == ignore)
|
||||||
|
; // ignore
|
||||||
|
else if(c == '-')
|
||||||
|
isNegative = true;
|
||||||
|
else if (c == '.')
|
||||||
|
isFraction = true;
|
||||||
|
else if(c >= '0' && c <= '9') { // is c a digit?
|
||||||
|
value = value * 10 + c - '0';
|
||||||
|
if(isFraction)
|
||||||
|
fraction *= 0.1;
|
||||||
|
}
|
||||||
|
read(); // consume the character we got with peek
|
||||||
|
c = timedPeek();
|
||||||
|
}
|
||||||
|
while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore );
|
||||||
|
|
||||||
|
if(isNegative)
|
||||||
|
value = -value;
|
||||||
|
if(isFraction)
|
||||||
|
return value * fraction;
|
||||||
|
else
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read characters from stream into buffer
|
||||||
|
// terminates if length characters have been read, or timeout (see setTimeout)
|
||||||
|
// returns the number of characters placed in the buffer
|
||||||
|
// the buffer is NOT null terminated.
|
||||||
|
//
|
||||||
|
size_t Stream::readBytes(char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
while (count < length) {
|
||||||
|
int c = timedRead();
|
||||||
|
if (c < 0) break;
|
||||||
|
*buffer++ = (char)c;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// as readBytes with terminator character
|
||||||
|
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||||
|
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||||
|
|
||||||
|
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
|
||||||
|
{
|
||||||
|
if (length < 1) return 0;
|
||||||
|
size_t index = 0;
|
||||||
|
while (index < length) {
|
||||||
|
int c = timedRead();
|
||||||
|
if (c < 0 || c == terminator) break;
|
||||||
|
*buffer++ = (char)c;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return index; // return number of characters, not including null terminator
|
||||||
|
}
|
||||||
|
|
||||||
|
String Stream::readString()
|
||||||
|
{
|
||||||
|
String ret;
|
||||||
|
int c = timedRead();
|
||||||
|
while (c >= 0)
|
||||||
|
{
|
||||||
|
ret += (char)c;
|
||||||
|
c = timedRead();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
String Stream::readStringUntil(char terminator)
|
||||||
|
{
|
||||||
|
String ret;
|
||||||
|
int c = timedRead();
|
||||||
|
while (c >= 0 && c != terminator)
|
||||||
|
{
|
||||||
|
ret += (char)c;
|
||||||
|
c = timedRead();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
|
||||||
|
// any zero length target string automatically matches and would make
|
||||||
|
// a mess of the rest of the algorithm.
|
||||||
|
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
|
||||||
|
if (t->len <= 0)
|
||||||
|
return t - targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int c = timedRead();
|
||||||
|
if (c < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
|
||||||
|
// the simple case is if we match, deal with that first.
|
||||||
|
if (c == t->str[t->index]) {
|
||||||
|
if (++t->index == t->len)
|
||||||
|
return t - targets;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not we need to walk back and see if we could have matched further
|
||||||
|
// down the stream (ie '1112' doesn't match the first position in '11112'
|
||||||
|
// but it will match the second position so we can't just reset the current
|
||||||
|
// index to 0 when we find a mismatch.
|
||||||
|
if (t->index == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int origIndex = t->index;
|
||||||
|
do {
|
||||||
|
--t->index;
|
||||||
|
// first check if current char works against the new current index
|
||||||
|
if (c != t->str[t->index])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if it's the only char then we're good, nothing more to check
|
||||||
|
if (t->index == 0) {
|
||||||
|
t->index++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise we need to check the rest of the found string
|
||||||
|
int diff = origIndex - t->index;
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < t->index; ++i) {
|
||||||
|
if (t->str[i] != t->str[i + diff])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we successfully got through the previous loop then our current
|
||||||
|
// index is good.
|
||||||
|
if (i == t->index) {
|
||||||
|
t->index++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise we just try the next index
|
||||||
|
} while (t->index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// unreachable
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
Stream.h - base class for character-based streams.
|
||||||
|
Copyright (c) 2010 David A. Mellis. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
parsing functions based on TextFinder library by Michael Margolis
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Stream_h
|
||||||
|
#define Stream_h
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "Print.h"
|
||||||
|
|
||||||
|
// compatability macros for testing
|
||||||
|
/*
|
||||||
|
#define getInt() parseInt()
|
||||||
|
#define getInt(ignore) parseInt(ignore)
|
||||||
|
#define getFloat() parseFloat()
|
||||||
|
#define getFloat(ignore) parseFloat(ignore)
|
||||||
|
#define getString( pre_string, post_string, buffer, length)
|
||||||
|
readBytesBetween( pre_string, terminator, buffer, length)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This enumeration provides the lookahead options for parseInt(), parseFloat()
|
||||||
|
// The rules set out here are used until either the first valid character is found
|
||||||
|
// or a time out occurs due to lack of input.
|
||||||
|
enum LookaheadMode{
|
||||||
|
SKIP_ALL, // All invalid characters are ignored.
|
||||||
|
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
|
||||||
|
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
|
||||||
|
|
||||||
|
class Stream : public Print
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
|
||||||
|
unsigned long _startMillis; // used for timeout measurement
|
||||||
|
int timedRead(); // private method to read stream with timeout
|
||||||
|
int timedPeek(); // private method to peek stream with timeout
|
||||||
|
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int available() = 0;
|
||||||
|
virtual int read() = 0;
|
||||||
|
virtual int peek() = 0;
|
||||||
|
virtual void flush() = 0;
|
||||||
|
|
||||||
|
Stream() {_timeout=1000;}
|
||||||
|
|
||||||
|
// parsing methods
|
||||||
|
|
||||||
|
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
|
||||||
|
unsigned long getTimeout(void) { return _timeout; }
|
||||||
|
|
||||||
|
bool find(char *target); // reads data from the stream until the target string is found
|
||||||
|
bool find(uint8_t *target) { return find ((char *)target); }
|
||||||
|
// returns true if target string is found, false if timed out (see setTimeout)
|
||||||
|
|
||||||
|
bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
|
||||||
|
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
|
||||||
|
// returns true if target string is found, false if timed out
|
||||||
|
|
||||||
|
bool find(char target) { return find (&target, 1); }
|
||||||
|
|
||||||
|
bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
|
||||||
|
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
|
||||||
|
|
||||||
|
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
|
||||||
|
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
|
||||||
|
|
||||||
|
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
|
||||||
|
// returns the first valid (long) integer value from the current position.
|
||||||
|
// lookahead determines how parseInt looks ahead in the stream.
|
||||||
|
// See LookaheadMode enumeration at the top of the file.
|
||||||
|
// Lookahead is terminated by the first character that is not a valid part of an integer.
|
||||||
|
// Once parsing commences, 'ignore' will be skipped in the stream.
|
||||||
|
|
||||||
|
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
|
||||||
|
// float version of parseInt
|
||||||
|
|
||||||
|
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
|
||||||
|
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
|
||||||
|
// terminates if length characters have been read or timeout (see setTimeout)
|
||||||
|
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||||
|
|
||||||
|
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
|
||||||
|
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
|
||||||
|
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||||
|
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||||
|
|
||||||
|
// Arduino String functions to be added here
|
||||||
|
String readString();
|
||||||
|
String readStringUntil(char terminator);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
|
||||||
|
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
|
||||||
|
// These overload exists for compatibility with any class that has derived
|
||||||
|
// Stream and used parseFloat/Int with a custom ignore character. To keep
|
||||||
|
// the public API simple, these overload remains protected.
|
||||||
|
|
||||||
|
struct MultiTarget {
|
||||||
|
const char *str; // string you're searching for
|
||||||
|
size_t len; // length of string you're searching for
|
||||||
|
size_t index; // index used by the search routine.
|
||||||
|
};
|
||||||
|
|
||||||
|
// This allows you to search for an arbitrary number of strings.
|
||||||
|
// Returns index of the target that is found first or -1 if timeout occurs.
|
||||||
|
int findMulti(struct MultiTarget *targets, int tCount);
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef NO_IGNORE_CHAR
|
||||||
|
#endif
|
|
@ -0,0 +1,752 @@
|
||||||
|
/*
|
||||||
|
WString.cpp - String library for Wiring & Arduino
|
||||||
|
...mostly rewritten by Paul Stoffregen...
|
||||||
|
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
|
||||||
|
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WString.h"
|
||||||
|
#include "itoa.h"
|
||||||
|
#include "avr/dtostrf.h"
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Constructors */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
String::String(const char *cstr)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
if (cstr) copy(cstr, strlen(cstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(const String &value)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
*this = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(const __FlashStringHelper *pstr)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
*this = pstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
String::String(String &&rval)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
move(rval);
|
||||||
|
}
|
||||||
|
String::String(StringSumHelper &&rval)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
move(rval);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String::String(char c)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
char buf[2];
|
||||||
|
buf[0] = c;
|
||||||
|
buf[1] = 0;
|
||||||
|
*this = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(unsigned char value, unsigned char base)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
char buf[1 + 8 * sizeof(unsigned char)];
|
||||||
|
utoa(value, buf, base);
|
||||||
|
*this = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(int value, unsigned char base)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
char buf[2 + 8 * sizeof(int)];
|
||||||
|
itoa(value, buf, base);
|
||||||
|
*this = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(unsigned int value, unsigned char base)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
char buf[1 + 8 * sizeof(unsigned int)];
|
||||||
|
utoa(value, buf, base);
|
||||||
|
*this = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(long value, unsigned char base)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
char buf[2 + 8 * sizeof(long)];
|
||||||
|
ltoa(value, buf, base);
|
||||||
|
*this = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(unsigned long value, unsigned char base)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
char buf[1 + 8 * sizeof(unsigned long)];
|
||||||
|
ultoa(value, buf, base);
|
||||||
|
*this = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(float value, unsigned char decimalPlaces)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
char buf[33];
|
||||||
|
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
String::String(double value, unsigned char decimalPlaces)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
char buf[33];
|
||||||
|
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
String::~String()
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Memory Management */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
inline void String::init(void)
|
||||||
|
{
|
||||||
|
buffer = NULL;
|
||||||
|
capacity = 0;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::invalidate(void)
|
||||||
|
{
|
||||||
|
if (buffer) free(buffer);
|
||||||
|
buffer = NULL;
|
||||||
|
capacity = len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::reserve(unsigned int size)
|
||||||
|
{
|
||||||
|
if (buffer && capacity >= size) return 1;
|
||||||
|
if (changeBuffer(size)) {
|
||||||
|
if (len == 0) buffer[0] = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::changeBuffer(unsigned int maxStrLen)
|
||||||
|
{
|
||||||
|
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
|
||||||
|
if (newbuffer) {
|
||||||
|
buffer = newbuffer;
|
||||||
|
capacity = maxStrLen;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Copy and Move */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
String & String::copy(const char *cstr, unsigned int length)
|
||||||
|
{
|
||||||
|
if (!reserve(length)) {
|
||||||
|
invalidate();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
len = length;
|
||||||
|
strcpy(buffer, cstr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
|
||||||
|
{
|
||||||
|
if (!reserve(length)) {
|
||||||
|
invalidate();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
len = length;
|
||||||
|
strcpy_P(buffer, (PGM_P)pstr);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
void String::move(String &rhs)
|
||||||
|
{
|
||||||
|
if (buffer) {
|
||||||
|
if (rhs && capacity >= rhs.len) {
|
||||||
|
strcpy(buffer, rhs.buffer);
|
||||||
|
len = rhs.len;
|
||||||
|
rhs.len = 0;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer = rhs.buffer;
|
||||||
|
capacity = rhs.capacity;
|
||||||
|
len = rhs.len;
|
||||||
|
rhs.buffer = NULL;
|
||||||
|
rhs.capacity = 0;
|
||||||
|
rhs.len = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String & String::operator = (const String &rhs)
|
||||||
|
{
|
||||||
|
if (this == &rhs) return *this;
|
||||||
|
|
||||||
|
if (rhs.buffer) copy(rhs.buffer, rhs.len);
|
||||||
|
else invalidate();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
String & String::operator = (String &&rval)
|
||||||
|
{
|
||||||
|
if (this != &rval) move(rval);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String & String::operator = (StringSumHelper &&rval)
|
||||||
|
{
|
||||||
|
if (this != &rval) move(rval);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
String & String::operator = (const char *cstr)
|
||||||
|
{
|
||||||
|
if (cstr) copy(cstr, strlen(cstr));
|
||||||
|
else invalidate();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String & String::operator = (const __FlashStringHelper *pstr)
|
||||||
|
{
|
||||||
|
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
|
||||||
|
else invalidate();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* concat */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
unsigned char String::concat(const String &s)
|
||||||
|
{
|
||||||
|
return concat(s.buffer, s.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(const char *cstr, unsigned int length)
|
||||||
|
{
|
||||||
|
unsigned int newlen = len + length;
|
||||||
|
if (!cstr) return 0;
|
||||||
|
if (length == 0) return 1;
|
||||||
|
if (!reserve(newlen)) return 0;
|
||||||
|
strcpy(buffer + len, cstr);
|
||||||
|
len = newlen;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(const char *cstr)
|
||||||
|
{
|
||||||
|
if (!cstr) return 0;
|
||||||
|
return concat(cstr, strlen(cstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(char c)
|
||||||
|
{
|
||||||
|
char buf[2];
|
||||||
|
buf[0] = c;
|
||||||
|
buf[1] = 0;
|
||||||
|
return concat(buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(unsigned char num)
|
||||||
|
{
|
||||||
|
char buf[1 + 3 * sizeof(unsigned char)];
|
||||||
|
itoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(int num)
|
||||||
|
{
|
||||||
|
char buf[2 + 3 * sizeof(int)];
|
||||||
|
itoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(unsigned int num)
|
||||||
|
{
|
||||||
|
char buf[1 + 3 * sizeof(unsigned int)];
|
||||||
|
utoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(long num)
|
||||||
|
{
|
||||||
|
char buf[2 + 3 * sizeof(long)];
|
||||||
|
ltoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(unsigned long num)
|
||||||
|
{
|
||||||
|
char buf[1 + 3 * sizeof(unsigned long)];
|
||||||
|
ultoa(num, buf, 10);
|
||||||
|
return concat(buf, strlen(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(float num)
|
||||||
|
{
|
||||||
|
char buf[20];
|
||||||
|
char* string = dtostrf(num, 4, 2, buf);
|
||||||
|
return concat(string, strlen(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(double num)
|
||||||
|
{
|
||||||
|
char buf[20];
|
||||||
|
char* string = dtostrf(num, 4, 2, buf);
|
||||||
|
return concat(string, strlen(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::concat(const __FlashStringHelper * str)
|
||||||
|
{
|
||||||
|
if (!str) return 0;
|
||||||
|
int length = strlen_P((const char *) str);
|
||||||
|
if (length == 0) return 1;
|
||||||
|
unsigned int newlen = len + length;
|
||||||
|
if (!reserve(newlen)) return 0;
|
||||||
|
strcpy_P(buffer + len, (const char *) str);
|
||||||
|
len = newlen;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Concatenate */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(c)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(num)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(num)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(num)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(num)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(num)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(num)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(num)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
|
||||||
|
{
|
||||||
|
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||||
|
if (!a.concat(rhs)) a.invalidate();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Comparison */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
int String::compareTo(const String &s) const
|
||||||
|
{
|
||||||
|
if (!buffer || !s.buffer) {
|
||||||
|
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
|
||||||
|
if (buffer && len > 0) return *(unsigned char *)buffer;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return strcmp(buffer, s.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::equals(const String &s2) const
|
||||||
|
{
|
||||||
|
return (len == s2.len && compareTo(s2) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::equals(const char *cstr) const
|
||||||
|
{
|
||||||
|
if (len == 0) return (cstr == NULL || *cstr == 0);
|
||||||
|
if (cstr == NULL) return buffer[0] == 0;
|
||||||
|
return strcmp(buffer, cstr) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::operator<(const String &rhs) const
|
||||||
|
{
|
||||||
|
return compareTo(rhs) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::operator>(const String &rhs) const
|
||||||
|
{
|
||||||
|
return compareTo(rhs) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::operator<=(const String &rhs) const
|
||||||
|
{
|
||||||
|
return compareTo(rhs) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::operator>=(const String &rhs) const
|
||||||
|
{
|
||||||
|
return compareTo(rhs) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::equalsIgnoreCase( const String &s2 ) const
|
||||||
|
{
|
||||||
|
if (this == &s2) return 1;
|
||||||
|
if (len != s2.len) return 0;
|
||||||
|
if (len == 0) return 1;
|
||||||
|
const char *p1 = buffer;
|
||||||
|
const char *p2 = s2.buffer;
|
||||||
|
while (*p1) {
|
||||||
|
if (tolower(*p1++) != tolower(*p2++)) return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::startsWith( const String &s2 ) const
|
||||||
|
{
|
||||||
|
if (len < s2.len) return 0;
|
||||||
|
return startsWith(s2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
|
||||||
|
{
|
||||||
|
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
|
||||||
|
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char String::endsWith( const String &s2 ) const
|
||||||
|
{
|
||||||
|
if ( len < s2.len || !buffer || !s2.buffer) return 0;
|
||||||
|
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Character Access */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
char String::charAt(unsigned int loc) const
|
||||||
|
{
|
||||||
|
return operator[](loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::setCharAt(unsigned int loc, char c)
|
||||||
|
{
|
||||||
|
if (loc < len) buffer[loc] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char & String::operator[](unsigned int index)
|
||||||
|
{
|
||||||
|
static char dummy_writable_char;
|
||||||
|
if (index >= len || !buffer) {
|
||||||
|
dummy_writable_char = 0;
|
||||||
|
return dummy_writable_char;
|
||||||
|
}
|
||||||
|
return buffer[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
char String::operator[]( unsigned int index ) const
|
||||||
|
{
|
||||||
|
if (index >= len || !buffer) return 0;
|
||||||
|
return buffer[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
|
||||||
|
{
|
||||||
|
if (!bufsize || !buf) return;
|
||||||
|
if (index >= len) {
|
||||||
|
buf[0] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsigned int n = bufsize - 1;
|
||||||
|
if (n > len - index) n = len - index;
|
||||||
|
strncpy((char *)buf, buffer + index, n);
|
||||||
|
buf[n] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Search */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
int String::indexOf(char c) const
|
||||||
|
{
|
||||||
|
return indexOf(c, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int String::indexOf( char ch, unsigned int fromIndex ) const
|
||||||
|
{
|
||||||
|
if (fromIndex >= len) return -1;
|
||||||
|
const char* temp = strchr(buffer + fromIndex, ch);
|
||||||
|
if (temp == NULL) return -1;
|
||||||
|
return temp - buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int String::indexOf(const String &s2) const
|
||||||
|
{
|
||||||
|
return indexOf(s2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int String::indexOf(const String &s2, unsigned int fromIndex) const
|
||||||
|
{
|
||||||
|
if (fromIndex >= len) return -1;
|
||||||
|
const char *found = strstr(buffer + fromIndex, s2.buffer);
|
||||||
|
if (found == NULL) return -1;
|
||||||
|
return found - buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int String::lastIndexOf( char theChar ) const
|
||||||
|
{
|
||||||
|
return lastIndexOf(theChar, len - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int String::lastIndexOf(char ch, unsigned int fromIndex) const
|
||||||
|
{
|
||||||
|
if (fromIndex >= len) return -1;
|
||||||
|
char tempchar = buffer[fromIndex + 1];
|
||||||
|
buffer[fromIndex + 1] = '\0';
|
||||||
|
char* temp = strrchr( buffer, ch );
|
||||||
|
buffer[fromIndex + 1] = tempchar;
|
||||||
|
if (temp == NULL) return -1;
|
||||||
|
return temp - buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int String::lastIndexOf(const String &s2) const
|
||||||
|
{
|
||||||
|
return lastIndexOf(s2, len - s2.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
|
||||||
|
{
|
||||||
|
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
|
||||||
|
if (fromIndex >= len) fromIndex = len - 1;
|
||||||
|
int found = -1;
|
||||||
|
for (char *p = buffer; p <= buffer + fromIndex; p++) {
|
||||||
|
p = strstr(p, s2.buffer);
|
||||||
|
if (!p) break;
|
||||||
|
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
String String::substring(unsigned int left, unsigned int right) const
|
||||||
|
{
|
||||||
|
if (left > right) {
|
||||||
|
unsigned int temp = right;
|
||||||
|
right = left;
|
||||||
|
left = temp;
|
||||||
|
}
|
||||||
|
String out;
|
||||||
|
if (left >= len) return out;
|
||||||
|
if (right > len) right = len;
|
||||||
|
char temp = buffer[right]; // save the replaced character
|
||||||
|
buffer[right] = '\0';
|
||||||
|
out = buffer + left; // pointer arithmetic
|
||||||
|
buffer[right] = temp; //restore character
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Modification */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
void String::replace(char find, char replace)
|
||||||
|
{
|
||||||
|
if (!buffer) return;
|
||||||
|
for (char *p = buffer; *p; p++) {
|
||||||
|
if (*p == find) *p = replace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::replace(const String& find, const String& replace)
|
||||||
|
{
|
||||||
|
if (len == 0 || find.len == 0) return;
|
||||||
|
int diff = replace.len - find.len;
|
||||||
|
char *readFrom = buffer;
|
||||||
|
char *foundAt;
|
||||||
|
if (diff == 0) {
|
||||||
|
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||||
|
memcpy(foundAt, replace.buffer, replace.len);
|
||||||
|
readFrom = foundAt + replace.len;
|
||||||
|
}
|
||||||
|
} else if (diff < 0) {
|
||||||
|
char *writeTo = buffer;
|
||||||
|
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||||
|
unsigned int n = foundAt - readFrom;
|
||||||
|
memcpy(writeTo, readFrom, n);
|
||||||
|
writeTo += n;
|
||||||
|
memcpy(writeTo, replace.buffer, replace.len);
|
||||||
|
writeTo += replace.len;
|
||||||
|
readFrom = foundAt + find.len;
|
||||||
|
len += diff;
|
||||||
|
}
|
||||||
|
strcpy(writeTo, readFrom);
|
||||||
|
} else {
|
||||||
|
unsigned int size = len; // compute size needed for result
|
||||||
|
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||||
|
readFrom = foundAt + find.len;
|
||||||
|
size += diff;
|
||||||
|
}
|
||||||
|
if (size == len) return;
|
||||||
|
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
|
||||||
|
int index = len - 1;
|
||||||
|
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
||||||
|
readFrom = buffer + index + find.len;
|
||||||
|
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
|
||||||
|
len += diff;
|
||||||
|
buffer[len] = 0;
|
||||||
|
memcpy(buffer + index, replace.buffer, replace.len);
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::remove(unsigned int index){
|
||||||
|
// Pass the biggest integer as the count. The remove method
|
||||||
|
// below will take care of truncating it at the end of the
|
||||||
|
// string.
|
||||||
|
remove(index, (unsigned int)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::remove(unsigned int index, unsigned int count){
|
||||||
|
if (index >= len) { return; }
|
||||||
|
if (count <= 0) { return; }
|
||||||
|
if (count > len - index) { count = len - index; }
|
||||||
|
char *writeTo = buffer + index;
|
||||||
|
len = len - count;
|
||||||
|
strncpy(writeTo, buffer + index + count,len - index);
|
||||||
|
buffer[len] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::toLowerCase(void)
|
||||||
|
{
|
||||||
|
if (!buffer) return;
|
||||||
|
for (char *p = buffer; *p; p++) {
|
||||||
|
*p = tolower(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::toUpperCase(void)
|
||||||
|
{
|
||||||
|
if (!buffer) return;
|
||||||
|
for (char *p = buffer; *p; p++) {
|
||||||
|
*p = toupper(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void String::trim(void)
|
||||||
|
{
|
||||||
|
if (!buffer || len == 0) return;
|
||||||
|
char *begin = buffer;
|
||||||
|
while (isspace(*begin)) begin++;
|
||||||
|
char *end = buffer + len - 1;
|
||||||
|
while (isspace(*end) && end >= begin) end--;
|
||||||
|
len = end + 1 - begin;
|
||||||
|
if (begin > buffer) memcpy(buffer, begin, len);
|
||||||
|
buffer[len] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
/* Parsing / Conversion */
|
||||||
|
/*********************************************/
|
||||||
|
|
||||||
|
long String::toInt(void) const
|
||||||
|
{
|
||||||
|
if (buffer) return atol(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float String::toFloat(void) const
|
||||||
|
{
|
||||||
|
return float(toDouble());
|
||||||
|
}
|
||||||
|
|
||||||
|
double String::toDouble(void) const
|
||||||
|
{
|
||||||
|
if (buffer) return atof(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,229 @@
|
||||||
|
/*
|
||||||
|
WString.h - String library for Wiring & Arduino
|
||||||
|
...mostly rewritten by Paul Stoffregen...
|
||||||
|
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
|
||||||
|
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef String_class_h
|
||||||
|
#define String_class_h
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
// When compiling programs with this class, the following gcc parameters
|
||||||
|
// dramatically increase performance and memory (RAM) efficiency, typically
|
||||||
|
// with little or no increase in code size.
|
||||||
|
// -felide-constructors
|
||||||
|
// -std=c++0x
|
||||||
|
|
||||||
|
class __FlashStringHelper;
|
||||||
|
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
|
||||||
|
|
||||||
|
// An inherited class for holding the result of a concatenation. These
|
||||||
|
// result objects are assumed to be writable by subsequent concatenations.
|
||||||
|
class StringSumHelper;
|
||||||
|
|
||||||
|
// The string class
|
||||||
|
class String
|
||||||
|
{
|
||||||
|
// use a function pointer to allow for "if (s)" without the
|
||||||
|
// complications of an operator bool(). for more information, see:
|
||||||
|
// http://www.artima.com/cppsource/safebool.html
|
||||||
|
typedef void (String::*StringIfHelperType)() const;
|
||||||
|
void StringIfHelper() const {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// constructors
|
||||||
|
// creates a copy of the initial value.
|
||||||
|
// if the initial value is null or invalid, or if memory allocation
|
||||||
|
// fails, the string will be marked as invalid (i.e. "if (s)" will
|
||||||
|
// be false).
|
||||||
|
String(const char *cstr = "");
|
||||||
|
String(const String &str);
|
||||||
|
String(const __FlashStringHelper *str);
|
||||||
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
String(String &&rval);
|
||||||
|
String(StringSumHelper &&rval);
|
||||||
|
#endif
|
||||||
|
explicit String(char c);
|
||||||
|
explicit String(unsigned char, unsigned char base=10);
|
||||||
|
explicit String(int, unsigned char base=10);
|
||||||
|
explicit String(unsigned int, unsigned char base=10);
|
||||||
|
explicit String(long, unsigned char base=10);
|
||||||
|
explicit String(unsigned long, unsigned char base=10);
|
||||||
|
explicit String(float, unsigned char decimalPlaces=2);
|
||||||
|
explicit String(double, unsigned char decimalPlaces=2);
|
||||||
|
~String(void);
|
||||||
|
|
||||||
|
// memory management
|
||||||
|
// return true on success, false on failure (in which case, the string
|
||||||
|
// is left unchanged). reserve(0), if successful, will validate an
|
||||||
|
// invalid string (i.e., "if (s)" will be true afterwards)
|
||||||
|
unsigned char reserve(unsigned int size);
|
||||||
|
inline unsigned int length(void) const {return len;}
|
||||||
|
|
||||||
|
// creates a copy of the assigned value. if the value is null or
|
||||||
|
// invalid, or if the memory allocation fails, the string will be
|
||||||
|
// marked as invalid ("if (s)" will be false).
|
||||||
|
String & operator = (const String &rhs);
|
||||||
|
String & operator = (const char *cstr);
|
||||||
|
String & operator = (const __FlashStringHelper *str);
|
||||||
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
String & operator = (String &&rval);
|
||||||
|
String & operator = (StringSumHelper &&rval);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// concatenate (works w/ built-in types)
|
||||||
|
|
||||||
|
// returns true on success, false on failure (in which case, the string
|
||||||
|
// is left unchanged). if the argument is null or invalid, the
|
||||||
|
// concatenation is considered unsucessful.
|
||||||
|
unsigned char concat(const String &str);
|
||||||
|
unsigned char concat(const char *cstr);
|
||||||
|
unsigned char concat(char c);
|
||||||
|
unsigned char concat(unsigned char c);
|
||||||
|
unsigned char concat(int num);
|
||||||
|
unsigned char concat(unsigned int num);
|
||||||
|
unsigned char concat(long num);
|
||||||
|
unsigned char concat(unsigned long num);
|
||||||
|
unsigned char concat(float num);
|
||||||
|
unsigned char concat(double num);
|
||||||
|
unsigned char concat(const __FlashStringHelper * str);
|
||||||
|
|
||||||
|
// if there's not enough memory for the concatenated value, the string
|
||||||
|
// will be left unchanged (but this isn't signalled in any way)
|
||||||
|
String & operator += (const String &rhs) {concat(rhs); return (*this);}
|
||||||
|
String & operator += (const char *cstr) {concat(cstr); return (*this);}
|
||||||
|
String & operator += (char c) {concat(c); return (*this);}
|
||||||
|
String & operator += (unsigned char num) {concat(num); return (*this);}
|
||||||
|
String & operator += (int num) {concat(num); return (*this);}
|
||||||
|
String & operator += (unsigned int num) {concat(num); return (*this);}
|
||||||
|
String & operator += (long num) {concat(num); return (*this);}
|
||||||
|
String & operator += (unsigned long num) {concat(num); return (*this);}
|
||||||
|
String & operator += (float num) {concat(num); return (*this);}
|
||||||
|
String & operator += (double num) {concat(num); return (*this);}
|
||||||
|
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
|
||||||
|
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
|
||||||
|
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
|
||||||
|
|
||||||
|
// comparison (only works w/ Strings and "strings")
|
||||||
|
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
|
||||||
|
int compareTo(const String &s) const;
|
||||||
|
unsigned char equals(const String &s) const;
|
||||||
|
unsigned char equals(const char *cstr) const;
|
||||||
|
unsigned char operator == (const String &rhs) const {return equals(rhs);}
|
||||||
|
unsigned char operator == (const char *cstr) const {return equals(cstr);}
|
||||||
|
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
|
||||||
|
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
|
||||||
|
unsigned char operator < (const String &rhs) const;
|
||||||
|
unsigned char operator > (const String &rhs) const;
|
||||||
|
unsigned char operator <= (const String &rhs) const;
|
||||||
|
unsigned char operator >= (const String &rhs) const;
|
||||||
|
unsigned char equalsIgnoreCase(const String &s) const;
|
||||||
|
unsigned char startsWith( const String &prefix) const;
|
||||||
|
unsigned char startsWith(const String &prefix, unsigned int offset) const;
|
||||||
|
unsigned char endsWith(const String &suffix) const;
|
||||||
|
|
||||||
|
// character acccess
|
||||||
|
char charAt(unsigned int index) const;
|
||||||
|
void setCharAt(unsigned int index, char c);
|
||||||
|
char operator [] (unsigned int index) const;
|
||||||
|
char& operator [] (unsigned int index);
|
||||||
|
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
|
||||||
|
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
|
||||||
|
{ getBytes((unsigned char *)buf, bufsize, index); }
|
||||||
|
const char* c_str() const { return buffer; }
|
||||||
|
char* begin() { return buffer; }
|
||||||
|
char* end() { return buffer + length(); }
|
||||||
|
const char* begin() const { return c_str(); }
|
||||||
|
const char* end() const { return c_str() + length(); }
|
||||||
|
|
||||||
|
// search
|
||||||
|
int indexOf( char ch ) const;
|
||||||
|
int indexOf( char ch, unsigned int fromIndex ) const;
|
||||||
|
int indexOf( const String &str ) const;
|
||||||
|
int indexOf( const String &str, unsigned int fromIndex ) const;
|
||||||
|
int lastIndexOf( char ch ) const;
|
||||||
|
int lastIndexOf( char ch, unsigned int fromIndex ) const;
|
||||||
|
int lastIndexOf( const String &str ) const;
|
||||||
|
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
|
||||||
|
String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
|
||||||
|
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
|
||||||
|
|
||||||
|
// modification
|
||||||
|
void replace(char find, char replace);
|
||||||
|
void replace(const String& find, const String& replace);
|
||||||
|
void remove(unsigned int index);
|
||||||
|
void remove(unsigned int index, unsigned int count);
|
||||||
|
void toLowerCase(void);
|
||||||
|
void toUpperCase(void);
|
||||||
|
void trim(void);
|
||||||
|
|
||||||
|
// parsing/conversion
|
||||||
|
long toInt(void) const;
|
||||||
|
float toFloat(void) const;
|
||||||
|
double toDouble(void) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
char *buffer; // the actual char array
|
||||||
|
unsigned int capacity; // the array length minus one (for the '\0')
|
||||||
|
unsigned int len; // the String length (not counting the '\0')
|
||||||
|
protected:
|
||||||
|
void init(void);
|
||||||
|
void invalidate(void);
|
||||||
|
unsigned char changeBuffer(unsigned int maxStrLen);
|
||||||
|
unsigned char concat(const char *cstr, unsigned int length);
|
||||||
|
|
||||||
|
// copy and move
|
||||||
|
String & copy(const char *cstr, unsigned int length);
|
||||||
|
String & copy(const __FlashStringHelper *pstr, unsigned int length);
|
||||||
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
void move(String &rhs);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class StringSumHelper : public String
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StringSumHelper(const String &s) : String(s) {}
|
||||||
|
StringSumHelper(const char *p) : String(p) {}
|
||||||
|
StringSumHelper(char c) : String(c) {}
|
||||||
|
StringSumHelper(unsigned char num) : String(num) {}
|
||||||
|
StringSumHelper(int num) : String(num) {}
|
||||||
|
StringSumHelper(unsigned int num) : String(num) {}
|
||||||
|
StringSumHelper(long num) : String(num) {}
|
||||||
|
StringSumHelper(unsigned long num) : String(num) {}
|
||||||
|
StringSumHelper(float num) : String(num) {}
|
||||||
|
StringSumHelper(double num) : String(num) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
#endif // String_class_h
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
dtostrf - Emulation for dtostrf function from avr-libc
|
||||||
|
Copyright (c) 2013 Arduino. All rights reserved.
|
||||||
|
Written by Cristian Maglie <c.maglie@bug.st>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
|
||||||
|
char fmt[20];
|
||||||
|
sprintf(fmt, "%%%d.%df", width, prec);
|
||||||
|
sprintf(sout, fmt, val);
|
||||||
|
return sout;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
dtostrf - Emulation for dtostrf function from avr-libc
|
||||||
|
Copyright (c) 2013 Arduino. All rights reserved.
|
||||||
|
Written by Cristian Maglie <c.maglie@bug.st>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *dtostrf (double val, signed char width, unsigned char prec, char *sout);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef __PGMSPACE_H_
|
||||||
|
#define __PGMSPACE_H_ 1
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#define PROGMEM
|
||||||
|
#define PGM_P const char *
|
||||||
|
#define PSTR(str) (str)
|
||||||
|
|
||||||
|
#define _SFR_BYTE(n) (n)
|
||||||
|
|
||||||
|
typedef void prog_void;
|
||||||
|
typedef char prog_char;
|
||||||
|
typedef unsigned char prog_uchar;
|
||||||
|
typedef int8_t prog_int8_t;
|
||||||
|
typedef uint8_t prog_uint8_t;
|
||||||
|
typedef int16_t prog_int16_t;
|
||||||
|
typedef uint16_t prog_uint16_t;
|
||||||
|
typedef int32_t prog_int32_t;
|
||||||
|
typedef uint32_t prog_uint32_t;
|
||||||
|
|
||||||
|
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
|
||||||
|
#define strcpy_P(dest, src) strcpy((dest), (src))
|
||||||
|
#define strcat_P(dest, src) strcat((dest), (src))
|
||||||
|
#define strcmp_P(a, b) strcmp((a), (b))
|
||||||
|
#define strstr_P(a, b) strstr((a), (b))
|
||||||
|
#define strlen_P(a) strlen((a))
|
||||||
|
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
|
||||||
|
|
||||||
|
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||||
|
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
|
||||||
|
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
|
||||||
|
#define pgm_read_float(addr) (*(const float *)(addr))
|
||||||
|
|
||||||
|
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
|
||||||
|
#define pgm_read_word_near(addr) pgm_read_word(addr)
|
||||||
|
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
|
||||||
|
#define pgm_read_float_near(addr) pgm_read_float(addr)
|
||||||
|
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
|
||||||
|
#define pgm_read_word_far(addr) pgm_read_word(addr)
|
||||||
|
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
|
||||||
|
#define pgm_read_float_far(addr) pgm_read_float(addr)
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011 Arduino. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "itoa.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* reverse: reverse string s in place */
|
||||||
|
static void reverse( char s[] )
|
||||||
|
{
|
||||||
|
int i, j ;
|
||||||
|
char c ;
|
||||||
|
|
||||||
|
for ( i = 0, j = strlen(s)-1 ; i < j ; i++, j-- )
|
||||||
|
{
|
||||||
|
c = s[i] ;
|
||||||
|
s[i] = s[j] ;
|
||||||
|
s[j] = c ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* itoa: convert n to characters in s */
|
||||||
|
extern void itoa( int n, char s[] )
|
||||||
|
{
|
||||||
|
int i, sign ;
|
||||||
|
|
||||||
|
if ( (sign = n) < 0 ) /* record sign */
|
||||||
|
{
|
||||||
|
n = -n; /* make n positive */
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
do
|
||||||
|
{ /* generate digits in reverse order */
|
||||||
|
s[i++] = n % 10 + '0'; /* get next digit */
|
||||||
|
} while ((n /= 10) > 0) ; /* delete it */
|
||||||
|
|
||||||
|
if (sign < 0 )
|
||||||
|
{
|
||||||
|
s[i++] = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
s[i] = '\0';
|
||||||
|
|
||||||
|
reverse( s ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern char* itoa( int value, char *string, int radix )
|
||||||
|
{
|
||||||
|
return ltoa( value, string, radix ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char* ltoa( long value, char *string, int radix )
|
||||||
|
{
|
||||||
|
char tmp[33];
|
||||||
|
char *tp = tmp;
|
||||||
|
long i;
|
||||||
|
unsigned long v;
|
||||||
|
int sign;
|
||||||
|
char *sp;
|
||||||
|
|
||||||
|
if ( string == NULL )
|
||||||
|
{
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radix > 36 || radix <= 1)
|
||||||
|
{
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
sign = (radix == 10 && value < 0);
|
||||||
|
if (sign)
|
||||||
|
{
|
||||||
|
v = -value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v = (unsigned long)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (v || tp == tmp)
|
||||||
|
{
|
||||||
|
i = v % radix;
|
||||||
|
v = v / radix;
|
||||||
|
if (i < 10)
|
||||||
|
*tp++ = i+'0';
|
||||||
|
else
|
||||||
|
*tp++ = i + 'a' - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp = string;
|
||||||
|
|
||||||
|
if (sign)
|
||||||
|
*sp++ = '-';
|
||||||
|
while (tp > tmp)
|
||||||
|
*sp++ = *--tp;
|
||||||
|
*sp = 0;
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char* utoa( unsigned long value, char *string, int radix )
|
||||||
|
{
|
||||||
|
return ultoa( value, string, radix ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char* ultoa( unsigned long value, char *string, int radix )
|
||||||
|
{
|
||||||
|
char tmp[33];
|
||||||
|
char *tp = tmp;
|
||||||
|
long i;
|
||||||
|
unsigned long v = value;
|
||||||
|
char *sp;
|
||||||
|
|
||||||
|
if ( string == NULL )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radix > 36 || radix <= 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (v || tp == tmp)
|
||||||
|
{
|
||||||
|
i = v % radix;
|
||||||
|
v = v / radix;
|
||||||
|
if (i < 10)
|
||||||
|
*tp++ = i+'0';
|
||||||
|
else
|
||||||
|
*tp++ = i + 'a' - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp = string;
|
||||||
|
|
||||||
|
|
||||||
|
while (tp > tmp)
|
||||||
|
*sp++ = *--tp;
|
||||||
|
*sp = 0;
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif // __cplusplus
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2011 Arduino. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ITOA_
|
||||||
|
#define _ITOA_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
extern void itoa( int n, char s[] ) ;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern char* itoa( int value, char *string, int radix ) ;
|
||||||
|
extern char* ltoa( long value, char *string, int radix ) ;
|
||||||
|
extern char* utoa( unsigned long value, char *string, int radix ) ;
|
||||||
|
extern char* ultoa( unsigned long value, char *string, int radix ) ;
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif // _ITOA_
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
main.cpp - Main loop for Arduino sketches
|
||||||
|
Copyright (c) 2005-2013 Arduino Team. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
// Declared weak in Arduino.h to allow user redefinitions.
|
||||||
|
int atexit(void (* /*func*/ )()) { return 0; }
|
||||||
|
|
||||||
|
// Weak empty variant initialization function.
|
||||||
|
// May be redefined by variant files.
|
||||||
|
void initVariant() __attribute__((weak));
|
||||||
|
void initVariant() { }
|
||||||
|
|
||||||
|
void setupUSB() __attribute__((weak));
|
||||||
|
void setupUSB() { }
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
initVariant();
|
||||||
|
|
||||||
|
#if defined(USBCON)
|
||||||
|
USBDevice.attach();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setup();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014 Arduino. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void *operator new(size_t size) {
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](size_t size) {
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void * ptr) {
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void * ptr) {
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014 Arduino. All right reserved.
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NEW_H
|
||||||
|
#define NEW_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void * operator new(size_t size);
|
||||||
|
void * operator new[](size_t size);
|
||||||
|
void operator delete(void * ptr);
|
||||||
|
void operator delete[](void * ptr);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
#include "SerialUART.h"
|
||||||
|
|
||||||
|
SerialUART::SerialUART(USART_TypeDef *instance) {
|
||||||
|
this->instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SerialUART::begin(const uint32_t baud) {
|
||||||
|
static uint8_t tx[BUFFER_SIZE];
|
||||||
|
txBuffer = (uint8_t*)tx;
|
||||||
|
|
||||||
|
static uint8_t rx[BUFFER_SIZE];
|
||||||
|
rxBuffer = (uint8_t*)rx;
|
||||||
|
|
||||||
|
static UART_HandleTypeDef h;
|
||||||
|
handle = &h;
|
||||||
|
|
||||||
|
handle->Instance = instance;
|
||||||
|
|
||||||
|
#ifdef USART1
|
||||||
|
if (handle->Instance == USART1) {
|
||||||
|
__HAL_RCC_USART1_CLK_ENABLE();
|
||||||
|
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(USART1_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USART2
|
||||||
|
if (handle->Instance == USART2) {
|
||||||
|
__HAL_RCC_USART2_CLK_ENABLE();
|
||||||
|
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(USART2_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USART3
|
||||||
|
if (handle->Instance == USART3) {
|
||||||
|
__HAL_RCC_USART3_CLK_ENABLE();
|
||||||
|
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(USART3_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USART4
|
||||||
|
if (handle->Instance == USART4) {
|
||||||
|
__HAL_RCC_USART4_CLK_ENABLE();
|
||||||
|
HAL_NVIC_SetPriority(USART4_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(USART4_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
stm32_chip_UART_GPIO_init_default(instance);
|
||||||
|
|
||||||
|
handle->Init.BaudRate = baud;
|
||||||
|
handle->Init.WordLength = UART_WORDLENGTH_8B;
|
||||||
|
handle->Init.StopBits = UART_STOPBITS_1;
|
||||||
|
handle->Init.Parity = UART_PARITY_NONE;
|
||||||
|
handle->Init.Mode = UART_MODE_TX_RX;
|
||||||
|
handle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||||
|
handle->Init.OverSampling = UART_OVERSAMPLING_16;
|
||||||
|
HAL_UART_Init(handle);
|
||||||
|
|
||||||
|
HAL_UART_Receive_IT(handle, &receive_buffer, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialUART::available() {
|
||||||
|
return rxEnd != rxStart;
|
||||||
|
}
|
||||||
|
int SerialUART::peek() {
|
||||||
|
if (available()) {
|
||||||
|
return rxBuffer[rxStart % BUFFER_SIZE];
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialUART::flush() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialUART::read() {
|
||||||
|
if (available()) {
|
||||||
|
return rxBuffer[rxStart++ % BUFFER_SIZE];
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SerialUART::write(const uint8_t c) {
|
||||||
|
txBuffer[txEnd % BUFFER_SIZE] = c;
|
||||||
|
txEnd++;
|
||||||
|
if (txEnd == txStart + 1) {
|
||||||
|
HAL_UART_Transmit_IT(handle, &txBuffer[txStart % BUFFER_SIZE], 1);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// Interrupt
|
||||||
|
|
||||||
|
SerialUART *interruptUART;
|
||||||
|
|
||||||
|
#ifdef USART1
|
||||||
|
extern "C" void USART1_IRQHandler(void) {
|
||||||
|
interruptUART = &SerialUART1;
|
||||||
|
HAL_UART_IRQHandler(interruptUART->handle);
|
||||||
|
}
|
||||||
|
SerialUART SerialUART1(USART1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USART2
|
||||||
|
extern "C" void USART2_IRQHandler(void) {
|
||||||
|
interruptUART = &SerialUART2;
|
||||||
|
HAL_UART_IRQHandler(interruptUART->handle);
|
||||||
|
}
|
||||||
|
SerialUART SerialUART2(USART2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USART3
|
||||||
|
extern "C" void USART3_IRQHandler(void) {
|
||||||
|
interruptUART = &SerialUART3;
|
||||||
|
HAL_UART_IRQHandler(interruptUART->handle);
|
||||||
|
}
|
||||||
|
SerialUART SerialUART3(USART3);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USART4
|
||||||
|
extern "C" void USART4_IRQHandler(void) {
|
||||||
|
interruptUART = &SerialUART4;
|
||||||
|
HAL_UART_IRQHandler(interruptUART->handle);
|
||||||
|
}
|
||||||
|
SerialUART SerialUART4(USART4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
|
||||||
|
interruptUART->txStart++;
|
||||||
|
if (interruptUART->txStart != interruptUART->txEnd) {
|
||||||
|
HAL_UART_Transmit_IT(interruptUART->handle, &interruptUART->txBuffer[interruptUART->txStart % BUFFER_SIZE], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
|
||||||
|
interruptUART->rxBuffer[interruptUART->rxEnd % BUFFER_SIZE] = interruptUART->receive_buffer;
|
||||||
|
interruptUART->rxEnd++;
|
||||||
|
HAL_UART_Receive_IT(interruptUART->handle, &interruptUART->receive_buffer, 1);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef SERIAL_UART_H
|
||||||
|
#define SERIAL_UART_H
|
||||||
|
|
||||||
|
#include "stm32_def.h"
|
||||||
|
#include "stm32_gpio.h"
|
||||||
|
#include "Stream.h"
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 128
|
||||||
|
|
||||||
|
class SerialUART : public Stream {
|
||||||
|
public:
|
||||||
|
SerialUART(USART_TypeDef *instance);
|
||||||
|
void begin(const uint32_t baud);
|
||||||
|
void end(void);
|
||||||
|
int available(void);
|
||||||
|
int peek(void);
|
||||||
|
int read(void);
|
||||||
|
void flush(void);
|
||||||
|
size_t write(const uint8_t c);
|
||||||
|
using Print::write; // pull in write(str) and write(buf, size) from Print
|
||||||
|
operator bool() { return true; }; // UART always active
|
||||||
|
|
||||||
|
USART_TypeDef *instance;
|
||||||
|
UART_HandleTypeDef *handle;
|
||||||
|
|
||||||
|
uint8_t receive_buffer;
|
||||||
|
|
||||||
|
uint8_t *txBuffer;
|
||||||
|
volatile uint8_t txStart = 0;
|
||||||
|
volatile uint8_t txEnd = 0;
|
||||||
|
|
||||||
|
uint8_t *rxBuffer;
|
||||||
|
volatile uint8_t rxStart = 0;
|
||||||
|
volatile uint8_t rxEnd = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef USART1
|
||||||
|
extern SerialUART SerialUART1;
|
||||||
|
#endif
|
||||||
|
#ifdef USART2
|
||||||
|
extern SerialUART SerialUART2;
|
||||||
|
#endif
|
||||||
|
#ifdef USART3
|
||||||
|
extern SerialUART SerialUART3;
|
||||||
|
#endif
|
||||||
|
#ifdef USART4
|
||||||
|
extern SerialUART SerialUART4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _UART_CLASS_
|
|
@ -0,0 +1,245 @@
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* USBSerial core library for Arduino STM32 + HAL + CubeMX (HALMX).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 by Vassilis Serasidis <info@serasidis.gr>
|
||||||
|
* Home: http://www.serasidis.gr
|
||||||
|
* email: avrsite@yahoo.gr
|
||||||
|
*
|
||||||
|
* Arduino_STM32 forum: http://www.stm32duino.com
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
|
* above copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* Some functions follow the sam and samd arduino core libray files.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||||
|
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||||
|
* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef SERIAL_USB
|
||||||
|
|
||||||
|
#include "USBSerial.h"
|
||||||
|
#include "variant.h"
|
||||||
|
|
||||||
|
// Constructors ////////////////////////////////////////////////////////////////
|
||||||
|
USBSerial::USBSerial(){
|
||||||
|
// Make sure Rx ring buffer is initialized back to empty.
|
||||||
|
rx_buffer.iHead = rx_buffer.iTail = 0;
|
||||||
|
//tx_buffer.iHead = tx_buffer.iTail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBSerial::init(void){
|
||||||
|
/* Re-enumerate the USB */
|
||||||
|
volatile unsigned int i;
|
||||||
|
|
||||||
|
#ifdef USB_DISC_PIN
|
||||||
|
pinMode(USB_DISC_PIN, OUTPUT);
|
||||||
|
digitalWrite(USB_DISC_PIN, HIGH);
|
||||||
|
for(i=0;i<512;i++);
|
||||||
|
digitalWrite(USB_DISC_PIN, LOW);
|
||||||
|
#else
|
||||||
|
//pinMode(USBDP_PIN, OUTPUT);
|
||||||
|
//digitalWrite(USBDP_PIN, LOW);
|
||||||
|
//for(i=0;i<512;i++);
|
||||||
|
//digitalWrite(USBDP_PIN, HIGH);
|
||||||
|
|
||||||
|
|
||||||
|
pinMode(PA12, OUTPUT);
|
||||||
|
digitalWrite(PA12, LOW);
|
||||||
|
//HAL_Delay(1000);
|
||||||
|
for(i=0;i<512;i++){};
|
||||||
|
digitalWrite(PA12, HIGH);
|
||||||
|
//HAL_Delay(1000);
|
||||||
|
for(i=0;i<512;i++){};
|
||||||
|
#endif
|
||||||
|
MX_USB_DEVICE_Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USBSerial::begin(uint32_t baud_count){
|
||||||
|
init();
|
||||||
|
// suppress "unused parameter" warning
|
||||||
|
(void)baud_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBSerial::begin(uint32_t baud_count, uint8_t config){
|
||||||
|
init();
|
||||||
|
//suppress "unused parameter" warning
|
||||||
|
(void)baud_count;
|
||||||
|
(void)config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBSerial::end(void){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int USBSerial::availableForWrite(void){
|
||||||
|
//return (CDC_SERIAL_BUFFER_SIZE - available());
|
||||||
|
//return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + tx_buffer.iHead - tx_buffer.iTail) % CDC_SERIAL_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int USBSerial::available(void){
|
||||||
|
return (uint32_t)(CDC_SERIAL_BUFFER_SIZE + rx_buffer.iHead - rx_buffer.iTail) % CDC_SERIAL_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBSerial::peek(void)
|
||||||
|
{
|
||||||
|
if ( rx_buffer.iHead == rx_buffer.iTail )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return rx_buffer.buffer[rx_buffer.iTail];
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBSerial::read(void)
|
||||||
|
{
|
||||||
|
// if the head isn't ahead of the tail, we don't have any characters
|
||||||
|
if ( rx_buffer.iHead == rx_buffer.iTail )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint8_t uc = rx_buffer.buffer[rx_buffer.iTail];
|
||||||
|
rx_buffer.iTail = (unsigned int)(rx_buffer.iTail + 1) % CDC_SERIAL_BUFFER_SIZE;
|
||||||
|
|
||||||
|
return uc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBSerial::flush(void){
|
||||||
|
//It's not implemented yet.
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t USBSerial::write(const uint8_t *buffer, size_t size){
|
||||||
|
unsigned long timeout=millis()+5;
|
||||||
|
if(hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED)
|
||||||
|
{
|
||||||
|
while(millis()<timeout)
|
||||||
|
{
|
||||||
|
if(CDC_Transmit_FS((uint8_t*)buffer, size) == USBD_OK)
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* uint8_t i;
|
||||||
|
|
||||||
|
if(hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED){
|
||||||
|
|
||||||
|
//HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||||
|
for(i=0;i<200;i++)
|
||||||
|
if(CDC_Transmit_FS((uint8_t*)buffer, size) == USBD_OK){
|
||||||
|
return size;
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||||
|
}
|
||||||
|
return 0; */
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t USBSerial::write(uint8_t c) {
|
||||||
|
return write(&c, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBSerial::CDC_RxHandler (uint8_t* Buf, uint16_t Len){
|
||||||
|
|
||||||
|
for(uint16_t i=0;i<Len;i++){
|
||||||
|
if(available() < (CDC_SERIAL_BUFFER_SIZE - 1)){
|
||||||
|
rx_buffer.buffer[rx_buffer.iHead] = *Buf++;
|
||||||
|
rx_buffer.iHead = (uint16_t)(rx_buffer.iHead + 1) % CDC_SERIAL_BUFFER_SIZE;
|
||||||
|
}else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This operator is a convenient way for a sketch to check whether the
|
||||||
|
// port has actually been configured and opened by the host (as opposed
|
||||||
|
// to just being connected to the host). It can be used, for example, in
|
||||||
|
// setup() before printing to ensure that an application on the host is
|
||||||
|
// actually ready to receive and display the data.
|
||||||
|
// We add a short delay before returning to fix a bug observed by Federico
|
||||||
|
// where the port is configured (lineState != 0) but not quite opened.
|
||||||
|
USBSerial::operator bool()
|
||||||
|
{
|
||||||
|
// this is here to avoid spurious opening after upload
|
||||||
|
if (millis() < 500)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
/* if (_usbLineInfo.lineState > 0)
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(10); */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t USBSerial::baud() {
|
||||||
|
//return _usbLineInfo.dwDTERate;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t USBSerial::stopbits() {
|
||||||
|
//return _usbLineInfo.bCharFormat;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t USBSerial::paritytype() {
|
||||||
|
//return _usbLineInfo.bParityType;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t USBSerial::numbits() {
|
||||||
|
//return _usbLineInfo.bDataBits;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool USBSerial::dtr() {
|
||||||
|
//return _usbLineInfo.lineState & 0x1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool USBSerial::rts() {
|
||||||
|
//return _usbLineInfo.lineState & 0x2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern PCD_HandleTypeDef hpcd_USB_FS;
|
||||||
|
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
||||||
|
|
||||||
|
//F1
|
||||||
|
extern "C" void USB_LP_CAN1_RX0_IRQHandler(void) {
|
||||||
|
HAL_PCD_IRQHandler(&hpcd_USB_FS);
|
||||||
|
}
|
||||||
|
//F4
|
||||||
|
extern "C" void OTG_FS_IRQHandler(void) {
|
||||||
|
HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
|
||||||
|
}
|
||||||
|
//L0
|
||||||
|
extern "C" void USB_IRQHandler(void) {
|
||||||
|
HAL_PCD_IRQHandler(&hpcd_USB_FS);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void USBSerial_Rx_Handler(uint8_t *data, uint16_t len){
|
||||||
|
SerialUSB.CDC_RxHandler(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
USBSerial SerialUSB;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,98 @@
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* USBSerial core library for Arduino STM32 + HAL + CubeMX (HALMX).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 by Vassilis Serasidis <info@serasidis.gr>
|
||||||
|
* Home: http://www.serasidis.gr
|
||||||
|
* email: avrsite@yahoo.gr
|
||||||
|
*
|
||||||
|
* Arduino_STM32 forum: http://www.stm32duino.com
|
||||||
|
*
|
||||||
|
* The USBSerial.h file follows the function prototypes of
|
||||||
|
* the Arduino CDC.h file that was written by Peter Barrett
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
|
* above copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||||
|
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||||
|
* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _SERIAL_USB_H_INCLUDED
|
||||||
|
#define _SERIAL_USB_H_INCLUDED
|
||||||
|
|
||||||
|
#include "usb_device.h"
|
||||||
|
#include "usbd_core.h"
|
||||||
|
#include "usbd_desc.h"
|
||||||
|
#include "usbd_cdc.h"
|
||||||
|
#include "usbd_cdc_if.h"
|
||||||
|
|
||||||
|
#include "Stream.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
// Serial over CDC (Serial1 is the physical port)
|
||||||
|
//================================================================================
|
||||||
|
class USBSerial : public Stream{
|
||||||
|
|
||||||
|
public:
|
||||||
|
USBSerial();
|
||||||
|
void begin(uint32_t baud_count);
|
||||||
|
void begin(uint32_t baud_count, uint8_t config);
|
||||||
|
void end(void);
|
||||||
|
|
||||||
|
virtual int available(void);
|
||||||
|
virtual int availableForWrite(void);
|
||||||
|
//virtual void accept(void);
|
||||||
|
virtual int peek(void);
|
||||||
|
virtual int read(void);
|
||||||
|
virtual void flush(void);
|
||||||
|
virtual size_t write(uint8_t c);
|
||||||
|
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||||
|
using Print::write; // pull in write(str) from Print
|
||||||
|
operator bool();
|
||||||
|
void CDC_RxHandler(uint8_t* Buf, uint16_t Len);
|
||||||
|
void CDC_TxHandler(void);
|
||||||
|
// These return the settings specified by the USB host for the
|
||||||
|
// serial port. These aren't really used, but are offered here
|
||||||
|
// in case a sketch wants to act on these settings.
|
||||||
|
uint32_t baud();
|
||||||
|
uint8_t stopbits();
|
||||||
|
uint8_t paritytype();
|
||||||
|
uint8_t numbits();
|
||||||
|
bool dtr();
|
||||||
|
bool rts();
|
||||||
|
enum {
|
||||||
|
ONE_STOP_BIT = 0,
|
||||||
|
ONE_AND_HALF_STOP_BIT = 1,
|
||||||
|
TWO_STOP_BITS = 2,
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
NO_PARITY = 0,
|
||||||
|
ODD_PARITY = 1,
|
||||||
|
EVEN_PARITY = 2,
|
||||||
|
MARK_PARITY = 3,
|
||||||
|
SPACE_PARITY = 4,
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
void init(void);
|
||||||
|
struct ring_buffer{
|
||||||
|
uint8_t buffer[CDC_SERIAL_BUFFER_SIZE];
|
||||||
|
volatile uint16_t iHead;
|
||||||
|
volatile uint16_t iTail;
|
||||||
|
};
|
||||||
|
ring_buffer rx_buffer;
|
||||||
|
//ring_buffer tx_buffer;
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern USBSerial SerialUSB;
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef STM32_CLOCK_H
|
||||||
|
#define STM32_CLOCK_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline void delay(unsigned long millis) {
|
||||||
|
HAL_Delay(millis);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32_t millis() {
|
||||||
|
return HAL_GetTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef STM32_DEF_H
|
||||||
|
#define STM32_DEF_H
|
||||||
|
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx.h"
|
||||||
|
#include "stm32f0xx_hal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx.h"
|
||||||
|
#include "stm32f1xx_hal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx.h"
|
||||||
|
#include "stm32f2xx_hal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx.h"
|
||||||
|
#include "stm32f3xx_hal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "stm32f4xx_hal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx.h"
|
||||||
|
#include "stm32f7xx_hal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx.h"
|
||||||
|
#include "stm32l0xx_hal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx.h"
|
||||||
|
#include "stm32l1xx_hal.h"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx.h"
|
||||||
|
#include "stm32l4xx_hal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,63 @@
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "variant.h"
|
||||||
|
|
||||||
|
void stm32_gpio_clock(GPIO_TypeDef *port) {
|
||||||
|
|
||||||
|
#ifdef GPIOA
|
||||||
|
if (port == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
|
#endif
|
||||||
|
#ifdef GPIOB
|
||||||
|
if (port == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE();
|
||||||
|
#endif
|
||||||
|
#ifdef GPIOC
|
||||||
|
if (port == GPIOC) __HAL_RCC_GPIOC_CLK_ENABLE();
|
||||||
|
#endif
|
||||||
|
#ifdef GPIOD
|
||||||
|
if (port == GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE();
|
||||||
|
#endif
|
||||||
|
#ifdef GPIOE
|
||||||
|
if (port == GPIOE) __HAL_RCC_GPIOE_CLK_ENABLE();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void pinMode(uint8_t pin, uint8_t mode) {
|
||||||
|
stm32_port_pin_type port_pin = port_pin_list[pin];
|
||||||
|
|
||||||
|
stm32_gpio_clock(port_pin.port);
|
||||||
|
|
||||||
|
GPIO_InitTypeDef init;
|
||||||
|
|
||||||
|
init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||||
|
init.Pin = port_pin.pin_mask;
|
||||||
|
|
||||||
|
switch ( mode ) {
|
||||||
|
case INPUT:
|
||||||
|
init.Mode = GPIO_MODE_INPUT;
|
||||||
|
init.Pull = GPIO_NOPULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_PULLUP:
|
||||||
|
init.Mode = GPIO_MODE_INPUT;
|
||||||
|
init.Pull = GPIO_PULLUP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_PULLDOWN:
|
||||||
|
init.Mode = GPIO_MODE_INPUT;
|
||||||
|
init.Pull = GPIO_PULLDOWN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OUTPUT:
|
||||||
|
init.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
|
init.Pull = GPIO_NOPULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_GPIO_Init(port_pin.port, &init);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef STM32_GPIO_H
|
||||||
|
#define STM32_GPIO_H
|
||||||
|
|
||||||
|
#include "stm32_def.h"
|
||||||
|
|
||||||
|
#include "variant.h"
|
||||||
|
|
||||||
|
#ifndef GPIO_SPEED_FREQ_VERY_HIGH
|
||||||
|
#define GPIO_SPEED_FREQ_VERY_HIGH GPIO_SPEED_FREQ_HIGH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint32_t pin_mask;
|
||||||
|
} stm32_port_pin_type;
|
||||||
|
|
||||||
|
extern const stm32_port_pin_type port_pin_list[NUM_PINS];
|
||||||
|
|
||||||
|
void stm32_chip_UART_GPIO_init(const USART_TypeDef *instance, const GPIO_TypeDef *rxPort, const uint32_t rxPin, const GPIO_TypeDef *txPort, const uint32_t txPin);
|
||||||
|
void stm32_chip_UART_GPIO_init_default(const USART_TypeDef *instance);
|
||||||
|
|
||||||
|
void stm32_gpio_clock(GPIO_TypeDef *port);
|
||||||
|
|
||||||
|
inline void digitalWrite(uint8_t pin, uint8_t value) {
|
||||||
|
if (pin < 0 || pin >= sizeof(port_pin_list) / sizeof(port_pin_list[0])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stm32_port_pin_type port_pin = port_pin_list[pin];
|
||||||
|
|
||||||
|
HAL_GPIO_WritePin(port_pin.port, port_pin.pin_mask, value ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,69 @@
|
||||||
|
#if defined(STM32F0) || defined(STM32F2) || defined(STM32F3) || defined(STM32F4) || \
|
||||||
|
defined(STM32F7) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4)
|
||||||
|
|
||||||
|
#include "stm32_gpio.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *instance;
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint32_t pin;
|
||||||
|
uint8_t alternate;
|
||||||
|
} alternate_pin_type;
|
||||||
|
|
||||||
|
#include CHIP_PERIPHERAL_INCLUDE
|
||||||
|
|
||||||
|
int8_t stm32_get_alternate(alternate_pin_type list[], int size, const void *instance, const GPIO_TypeDef *port, const uint32_t pin) {
|
||||||
|
for(int i=0; i<size; i++) {
|
||||||
|
if (instance == list[i].instance
|
||||||
|
&& port == list[i].port
|
||||||
|
&& pin == list[i].pin) {
|
||||||
|
|
||||||
|
return list[i].alternate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GPIO_TypeDef *stm32_alternate_default(alternate_pin_type list[], int size, const void *instance, uint32_t *pin) {
|
||||||
|
for(int i=0; i<size; i++) {
|
||||||
|
if (instance == list[i].instance) {
|
||||||
|
*pin = list[i].pin;
|
||||||
|
return list[i].port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm32_chip_UART_GPIO_init(const USART_TypeDef *instance, const GPIO_TypeDef *rxPort, const uint32_t rxPin, const GPIO_TypeDef *txPort, const uint32_t txPin) {
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
|
||||||
|
|
||||||
|
stm32_gpio_clock(rxPort);
|
||||||
|
if (rxPort == NULL) {
|
||||||
|
rxPort = stm32_alternate_default(alternate_usart_rx, sizeof(alternate_usart_rx) / sizeof(alternate_usart_rx[0]), instance, &rxPin);
|
||||||
|
}
|
||||||
|
GPIO_InitStruct.Pin = rxPin;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||||
|
GPIO_InitStruct.Alternate = stm32_get_alternate(alternate_usart_rx, sizeof(alternate_usart_rx) / sizeof(alternate_usart_rx[0]), instance, rxPort, rxPin);
|
||||||
|
HAL_GPIO_Init(rxPort, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
stm32_gpio_clock(txPort);
|
||||||
|
if (txPort == NULL) {
|
||||||
|
txPort = stm32_alternate_default(alternate_usart_tx, sizeof(alternate_usart_tx) / sizeof(alternate_usart_tx[0]), instance, &txPin);
|
||||||
|
}
|
||||||
|
GPIO_InitStruct.Pin = txPin;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||||
|
GPIO_InitStruct.Alternate = stm32_get_alternate(alternate_usart_tx, sizeof(alternate_usart_tx) / sizeof(alternate_usart_tx[0]), instance, txPort, txPin);
|
||||||
|
HAL_GPIO_Init(txPort, &GPIO_InitStruct);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm32_chip_UART_GPIO_init_default(const USART_TypeDef *instance) {
|
||||||
|
stm32_chip_UART_GPIO_init(instance, NULL, 0, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,71 @@
|
||||||
|
#if defined(STM32F1)
|
||||||
|
|
||||||
|
#include "stm32_gpio.h"
|
||||||
|
|
||||||
|
typedef void (*alternate_callback)();
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *instance;
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint32_t pin;
|
||||||
|
alternate_callback alternate;
|
||||||
|
} alternate_pin_type;
|
||||||
|
|
||||||
|
#include CHIP_PERIPHERAL_INCLUDE
|
||||||
|
|
||||||
|
alternate_callback stm32_pin_alternate(alternate_pin_type list[], int size, const void *instance, const GPIO_TypeDef *port, const uint32_t pin) {
|
||||||
|
for(int i=0; i<size; i++) {
|
||||||
|
if (instance == list[i].instance
|
||||||
|
&& port == list[i].port
|
||||||
|
&& pin == list[i].pin) {
|
||||||
|
|
||||||
|
return list[i].alternate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GPIO_TypeDef *stm32_alternate_default(alternate_pin_type list[], int size, const void *instance, uint32_t *pin) {
|
||||||
|
for(int i=0; i<size; i++) {
|
||||||
|
if (instance == list[i].instance) {
|
||||||
|
*pin = list[i].pin;
|
||||||
|
return list[i].port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm32_chip_UART_GPIO_init(const USART_TypeDef *instance, const GPIO_TypeDef *rxPort, const uint32_t rxPin, const GPIO_TypeDef *txPort, const uint32_t txPin) {
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
|
||||||
|
stm32_gpio_clock(rxPort);
|
||||||
|
if (rxPort == NULL) {
|
||||||
|
rxPort = stm32_alternate_default(alternate_usart_rx, sizeof(alternate_usart_rx) / sizeof(alternate_usart_rx[0]), instance, &rxPin);
|
||||||
|
}
|
||||||
|
GPIO_InitStruct.Pin = port_pin_list[rxPin].pin_mask;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
stm32_pin_alternate(alternate_usart_rx, sizeof(alternate_usart_rx) / sizeof(alternate_usart_rx[0]), instance, port_pin_list[rxPin].port, port_pin_list[rxPin].pin_mask)();
|
||||||
|
|
||||||
|
stm32_gpio_clock(txPort);
|
||||||
|
if (txPort == NULL) {
|
||||||
|
txPort = stm32_alternate_default(alternate_usart_tx, sizeof(alternate_usart_tx) / sizeof(alternate_usart_tx[0]), instance, &txPin);
|
||||||
|
}
|
||||||
|
GPIO_InitStruct.Pin = port_pin_list[txPin].pin_mask;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
stm32_pin_alternate(alternate_usart_tx, sizeof(alternate_usart_tx) / sizeof(alternate_usart_tx[0]), instance, port_pin_list[txPin].port, port_pin_list[txPin].pin_mask)();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stm32_chip_UART_GPIO_init_default(const USART_TypeDef *instance) {
|
||||||
|
stm32_chip_UART_GPIO_init(instance, NULL, 0, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "stm32_def.h"
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
HAL_Init();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void initVariant() {
|
||||||
|
SystemClock_Config();
|
||||||
|
|
||||||
|
#ifdef STM32F1
|
||||||
|
__HAL_RCC_AFIO_CLK_ENABLE();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysTick_Handler(void) {
|
||||||
|
HAL_IncTick();
|
||||||
|
HAL_SYSTICK_IRQHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Error_Handler() {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#include CMSIS_STARTUP_ASSEMBLY
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_cortex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal_cortex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_cortex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_cortex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_cortex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_cortex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal_cortex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_cortex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_cortex.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_dma.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal_dma.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_dma.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_dma.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_dma.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_dma.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal_dma.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_dma.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_dma.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_dma_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_dma_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_dma_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_dma_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_dma_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_dma_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_dma_ex.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_gpio.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal_gpio.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_gpio.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_gpio.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_gpio.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_gpio.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal_gpio.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_gpio.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_gpio.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_pcd.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal_pcd.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_pcd.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_pcd.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_pcd.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_pcd.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal_pcd.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_pcd.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_pcd.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_pcd_ex.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_rcc.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal_rcc.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_rcc.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_rcc.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_rcc.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_rcc.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal_rcc.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_rcc.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_rcc.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_rcc_ex.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_hal_uart.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_hal_uart.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_hal_uart.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_hal_uart.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_hal_uart.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_hal_uart.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "stm32l0xx_hal_uart.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_hal_uart.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_hal_uart.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "stm32f0xx_ll_usb.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "stm32f1xx_ll_usb.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "stm32f2xx_ll_usb.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "stm32f3xx_ll_usb.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "stm32f4xx_ll_usb.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "stm32f7xx_ll_usb.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "stm32l1xx_ll_usb.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "stm32l4xx_ll_usb.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "stm32_build_defines.h"
|
||||||
|
|
||||||
|
#ifdef STM32F0
|
||||||
|
#include "system_stm32f0xx.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F1
|
||||||
|
#include "system_stm32f1xx.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F2
|
||||||
|
#include "system_stm32f2xx.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F3
|
||||||
|
#include "system_stm32f3xx.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F4
|
||||||
|
#include "system_stm32f4xx.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32F7
|
||||||
|
#include "system_stm32f7xx.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L0
|
||||||
|
#include "system_stm32l0xx.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L1
|
||||||
|
#include "system_stm32l1xx.c"
|
||||||
|
#endif
|
||||||
|
#ifdef STM32L4
|
||||||
|
#include "system_stm32l4xx.c"
|
||||||
|
#endif
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : USB_DEVICE
|
||||||
|
* @version : v1.0_Cube
|
||||||
|
* @brief : This file implements the USB Device
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* COPYRIGHT(c) 2016 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "usb_device.h"
|
||||||
|
#include "usbd_core.h"
|
||||||
|
#include "usbd_desc.h"
|
||||||
|
#include "usbd_cdc.h"
|
||||||
|
#include "usbd_cdc_if.h"
|
||||||
|
|
||||||
|
/* USB Device Core handle declaration */
|
||||||
|
USBD_HandleTypeDef hUsbDeviceFS;
|
||||||
|
|
||||||
|
/* init function */
|
||||||
|
void MX_USB_DEVICE_Init(void)
|
||||||
|
{
|
||||||
|
/* Init Device Library,Add Supported Class and Start the library*/
|
||||||
|
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
|
||||||
|
|
||||||
|
USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);
|
||||||
|
|
||||||
|
USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);
|
||||||
|
|
||||||
|
USBD_Start(&hUsbDeviceFS);
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : USB_DEVICE
|
||||||
|
* @version : v1.0_Cube
|
||||||
|
* @brief : Header for usb_device file.
|
||||||
|
******************************************************************************
|
||||||
|
* COPYRIGHT(c) 2016 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __usb_device_H
|
||||||
|
#define __usb_device_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "stm32_def.h"
|
||||||
|
|
||||||
|
#include "usbd_def.h"
|
||||||
|
|
||||||
|
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||||
|
|
||||||
|
/* USB_Device init function */
|
||||||
|
void MX_USB_DEVICE_Init(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /*__usb_device_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,925 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_cdc.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief This file provides the high layer firmware functions to manage the
|
||||||
|
* following functionalities of the USB CDC Class:
|
||||||
|
* - Initialization and Configuration of high and low layer
|
||||||
|
* - Enumeration as CDC Device (and enumeration for each implemented memory interface)
|
||||||
|
* - OUT/IN data transfer
|
||||||
|
* - Command IN transfer (class requests management)
|
||||||
|
* - Error management
|
||||||
|
*
|
||||||
|
* @verbatim
|
||||||
|
*
|
||||||
|
* ===================================================================
|
||||||
|
* CDC Class Driver Description
|
||||||
|
* ===================================================================
|
||||||
|
* This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
|
||||||
|
* Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
|
||||||
|
* Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
|
||||||
|
* This driver implements the following aspects of the specification:
|
||||||
|
* - Device descriptor management
|
||||||
|
* - Configuration descriptor management
|
||||||
|
* - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
|
||||||
|
* - Requests management (as described in section 6.2 in specification)
|
||||||
|
* - Abstract Control Model compliant
|
||||||
|
* - Union Functional collection (using 1 IN endpoint for control)
|
||||||
|
* - Data interface class
|
||||||
|
*
|
||||||
|
* These aspects may be enriched or modified for a specific user application.
|
||||||
|
*
|
||||||
|
* This driver doesn't implement the following aspects of the specification
|
||||||
|
* (but it is possible to manage these features with some modifications on this driver):
|
||||||
|
* - Any class-specific aspect relative to communication classes should be managed by user application.
|
||||||
|
* - All communication classes other than PSTN are not managed
|
||||||
|
*
|
||||||
|
* @endverbatim
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_cdc.h"
|
||||||
|
#include "usbd_desc.h"
|
||||||
|
#include "usbd_ctlreq.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC
|
||||||
|
* @brief usbd core module
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_FunctionPrototypes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t cfgidx);
|
||||||
|
|
||||||
|
static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t cfgidx);
|
||||||
|
|
||||||
|
static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev,
|
||||||
|
USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t epnum);
|
||||||
|
|
||||||
|
static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t epnum);
|
||||||
|
|
||||||
|
static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev);
|
||||||
|
|
||||||
|
static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length);
|
||||||
|
|
||||||
|
static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length);
|
||||||
|
|
||||||
|
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
|
||||||
|
|
||||||
|
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
|
||||||
|
|
||||||
|
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length);
|
||||||
|
|
||||||
|
/* USB Standard Device Descriptor */
|
||||||
|
__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
|
||||||
|
{
|
||||||
|
USB_LEN_DEV_QUALIFIER_DESC,
|
||||||
|
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||||
|
0x00,
|
||||||
|
0x02,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
0x40,
|
||||||
|
0x01,
|
||||||
|
0x00,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* CDC interface class callbacks structure */
|
||||||
|
USBD_ClassTypeDef USBD_CDC =
|
||||||
|
{
|
||||||
|
USBD_CDC_Init,
|
||||||
|
USBD_CDC_DeInit,
|
||||||
|
USBD_CDC_Setup,
|
||||||
|
NULL, /* EP0_TxSent, */
|
||||||
|
USBD_CDC_EP0_RxReady,
|
||||||
|
USBD_CDC_DataIn,
|
||||||
|
USBD_CDC_DataOut,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
USBD_CDC_GetHSCfgDesc,
|
||||||
|
USBD_CDC_GetFSCfgDesc,
|
||||||
|
USBD_CDC_GetOtherSpeedCfgDesc,
|
||||||
|
USBD_CDC_GetDeviceQualifierDescriptor,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* USB CDC device Configuration Descriptor */
|
||||||
|
__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||||
|
{
|
||||||
|
/*Configuration Descriptor*/
|
||||||
|
0x09, /* bLength: Configuration Descriptor size */
|
||||||
|
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||||
|
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
|
||||||
|
0x00,
|
||||||
|
0x02, /* bNumInterfaces: 2 interface */
|
||||||
|
0x01, /* bConfigurationValue: Configuration value */
|
||||||
|
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||||
|
0xC0, /* bmAttributes: self powered */
|
||||||
|
0x32, /* MaxPower 0 mA */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*Interface Descriptor */
|
||||||
|
0x09, /* bLength: Interface Descriptor size */
|
||||||
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||||
|
/* Interface descriptor type */
|
||||||
|
0x00, /* bInterfaceNumber: Number of Interface */
|
||||||
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
|
0x01, /* bNumEndpoints: One endpoints used */
|
||||||
|
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||||
|
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||||
|
0x01, /* bInterfaceProtocol: Common AT commands */
|
||||||
|
0x00, /* iInterface: */
|
||||||
|
|
||||||
|
/*Header Functional Descriptor*/
|
||||||
|
0x05, /* bLength: Endpoint Descriptor size */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||||
|
0x10, /* bcdCDC: spec release number */
|
||||||
|
0x01,
|
||||||
|
|
||||||
|
/*Call Management Functional Descriptor*/
|
||||||
|
0x05, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||||
|
0x00, /* bmCapabilities: D0+D1 */
|
||||||
|
0x01, /* bDataInterface: 1 */
|
||||||
|
|
||||||
|
/*ACM Functional Descriptor*/
|
||||||
|
0x04, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||||
|
0x02, /* bmCapabilities */
|
||||||
|
|
||||||
|
/*Union Functional Descriptor*/
|
||||||
|
0x05, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x06, /* bDescriptorSubtype: Union func desc */
|
||||||
|
0x00, /* bMasterInterface: Communication class interface */
|
||||||
|
0x01, /* bSlaveInterface0: Data Class Interface */
|
||||||
|
|
||||||
|
/*Endpoint 2 Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CDC_CMD_EP, /* bEndpointAddress */
|
||||||
|
0x03, /* bmAttributes: Interrupt */
|
||||||
|
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_CMD_PACKET_SIZE),
|
||||||
|
0x10, /* bInterval: */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*Data class interface descriptor*/
|
||||||
|
0x09, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
|
||||||
|
0x01, /* bInterfaceNumber: Number of Interface */
|
||||||
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
|
0x02, /* bNumEndpoints: Two endpoints used */
|
||||||
|
0x0A, /* bInterfaceClass: CDC */
|
||||||
|
0x00, /* bInterfaceSubClass: */
|
||||||
|
0x00, /* bInterfaceProtocol: */
|
||||||
|
0x00, /* iInterface: */
|
||||||
|
|
||||||
|
/*Endpoint OUT Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CDC_OUT_EP, /* bEndpointAddress */
|
||||||
|
0x02, /* bmAttributes: Bulk */
|
||||||
|
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
|
||||||
|
0x00, /* bInterval: ignore for Bulk transfer */
|
||||||
|
|
||||||
|
/*Endpoint IN Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CDC_IN_EP, /* bEndpointAddress */
|
||||||
|
0x02, /* bmAttributes: Bulk */
|
||||||
|
LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
|
||||||
|
0x00 /* bInterval: ignore for Bulk transfer */
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
/* USB CDC device Configuration Descriptor */
|
||||||
|
__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||||
|
{
|
||||||
|
/*Configuration Descriptor*/
|
||||||
|
0x09, /* bLength: Configuration Descriptor size */
|
||||||
|
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||||
|
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
|
||||||
|
0x00,
|
||||||
|
0x02, /* bNumInterfaces: 2 interface */
|
||||||
|
0x01, /* bConfigurationValue: Configuration value */
|
||||||
|
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||||
|
0xC0, /* bmAttributes: self powered */
|
||||||
|
0x32, /* MaxPower 0 mA */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*Interface Descriptor */
|
||||||
|
0x09, /* bLength: Interface Descriptor size */
|
||||||
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||||
|
/* Interface descriptor type */
|
||||||
|
0x00, /* bInterfaceNumber: Number of Interface */
|
||||||
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
|
0x01, /* bNumEndpoints: One endpoints used */
|
||||||
|
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||||
|
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||||
|
0x01, /* bInterfaceProtocol: Common AT commands */
|
||||||
|
0x00, /* iInterface: */
|
||||||
|
|
||||||
|
/*Header Functional Descriptor*/
|
||||||
|
0x05, /* bLength: Endpoint Descriptor size */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||||
|
0x10, /* bcdCDC: spec release number */
|
||||||
|
0x01,
|
||||||
|
|
||||||
|
/*Call Management Functional Descriptor*/
|
||||||
|
0x05, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||||
|
0x00, /* bmCapabilities: D0+D1 */
|
||||||
|
0x01, /* bDataInterface: 1 */
|
||||||
|
|
||||||
|
/*ACM Functional Descriptor*/
|
||||||
|
0x04, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||||
|
0x02, /* bmCapabilities */
|
||||||
|
|
||||||
|
/*Union Functional Descriptor*/
|
||||||
|
0x05, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x06, /* bDescriptorSubtype: Union func desc */
|
||||||
|
0x00, /* bMasterInterface: Communication class interface */
|
||||||
|
0x01, /* bSlaveInterface0: Data Class Interface */
|
||||||
|
|
||||||
|
/*Endpoint 2 Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CDC_CMD_EP, /* bEndpointAddress */
|
||||||
|
0x03, /* bmAttributes: Interrupt */
|
||||||
|
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_CMD_PACKET_SIZE),
|
||||||
|
0x10, /* bInterval: */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*Data class interface descriptor*/
|
||||||
|
0x09, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
|
||||||
|
0x01, /* bInterfaceNumber: Number of Interface */
|
||||||
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
|
0x02, /* bNumEndpoints: Two endpoints used */
|
||||||
|
0x0A, /* bInterfaceClass: CDC */
|
||||||
|
0x00, /* bInterfaceSubClass: */
|
||||||
|
0x00, /* bInterfaceProtocol: */
|
||||||
|
0x00, /* iInterface: */
|
||||||
|
|
||||||
|
/*Endpoint OUT Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CDC_OUT_EP, /* bEndpointAddress */
|
||||||
|
0x02, /* bmAttributes: Bulk */
|
||||||
|
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||||
|
0x00, /* bInterval: ignore for Bulk transfer */
|
||||||
|
|
||||||
|
/*Endpoint IN Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CDC_IN_EP, /* bEndpointAddress */
|
||||||
|
0x02, /* bmAttributes: Bulk */
|
||||||
|
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||||
|
0x00 /* bInterval: ignore for Bulk transfer */
|
||||||
|
} ;
|
||||||
|
|
||||||
|
__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||||
|
{
|
||||||
|
0x09, /* bLength: Configuation Descriptor size */
|
||||||
|
USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
|
||||||
|
USB_CDC_CONFIG_DESC_SIZ,
|
||||||
|
0x00,
|
||||||
|
0x02, /* bNumInterfaces: 2 interfaces */
|
||||||
|
0x01, /* bConfigurationValue: */
|
||||||
|
0x04, /* iConfiguration: */
|
||||||
|
0xC0, /* bmAttributes: */
|
||||||
|
0x32, /* MaxPower 100 mA */
|
||||||
|
|
||||||
|
/*Interface Descriptor */
|
||||||
|
0x09, /* bLength: Interface Descriptor size */
|
||||||
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||||
|
/* Interface descriptor type */
|
||||||
|
0x00, /* bInterfaceNumber: Number of Interface */
|
||||||
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
|
0x01, /* bNumEndpoints: One endpoints used */
|
||||||
|
0x02, /* bInterfaceClass: Communication Interface Class */
|
||||||
|
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||||
|
0x01, /* bInterfaceProtocol: Common AT commands */
|
||||||
|
0x00, /* iInterface: */
|
||||||
|
|
||||||
|
/*Header Functional Descriptor*/
|
||||||
|
0x05, /* bLength: Endpoint Descriptor size */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||||
|
0x10, /* bcdCDC: spec release number */
|
||||||
|
0x01,
|
||||||
|
|
||||||
|
/*Call Management Functional Descriptor*/
|
||||||
|
0x05, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||||
|
0x00, /* bmCapabilities: D0+D1 */
|
||||||
|
0x01, /* bDataInterface: 1 */
|
||||||
|
|
||||||
|
/*ACM Functional Descriptor*/
|
||||||
|
0x04, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||||
|
0x02, /* bmCapabilities */
|
||||||
|
|
||||||
|
/*Union Functional Descriptor*/
|
||||||
|
0x05, /* bFunctionLength */
|
||||||
|
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||||
|
0x06, /* bDescriptorSubtype: Union func desc */
|
||||||
|
0x00, /* bMasterInterface: Communication class interface */
|
||||||
|
0x01, /* bSlaveInterface0: Data Class Interface */
|
||||||
|
|
||||||
|
/*Endpoint 2 Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT , /* bDescriptorType: Endpoint */
|
||||||
|
CDC_CMD_EP, /* bEndpointAddress */
|
||||||
|
0x03, /* bmAttributes: Interrupt */
|
||||||
|
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
|
||||||
|
HIBYTE(CDC_CMD_PACKET_SIZE),
|
||||||
|
0xFF, /* bInterval: */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*Data class interface descriptor*/
|
||||||
|
0x09, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
|
||||||
|
0x01, /* bInterfaceNumber: Number of Interface */
|
||||||
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
|
0x02, /* bNumEndpoints: Two endpoints used */
|
||||||
|
0x0A, /* bInterfaceClass: CDC */
|
||||||
|
0x00, /* bInterfaceSubClass: */
|
||||||
|
0x00, /* bInterfaceProtocol: */
|
||||||
|
0x00, /* iInterface: */
|
||||||
|
|
||||||
|
/*Endpoint OUT Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CDC_OUT_EP, /* bEndpointAddress */
|
||||||
|
0x02, /* bmAttributes: Bulk */
|
||||||
|
0x40, /* wMaxPacketSize: */
|
||||||
|
0x00,
|
||||||
|
0x00, /* bInterval: ignore for Bulk transfer */
|
||||||
|
|
||||||
|
/*Endpoint IN Descriptor*/
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CDC_IN_EP, /* bEndpointAddress */
|
||||||
|
0x02, /* bmAttributes: Bulk */
|
||||||
|
0x40, /* wMaxPacketSize: */
|
||||||
|
0x00,
|
||||||
|
0x00 /* bInterval */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_Init
|
||||||
|
* Initialize the CDC interface
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param cfgidx: Configuration index
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t cfgidx)
|
||||||
|
{
|
||||||
|
uint8_t ret = 0;
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc;
|
||||||
|
|
||||||
|
if(pdev->dev_speed == USBD_SPEED_HIGH )
|
||||||
|
{
|
||||||
|
/* Open EP IN */
|
||||||
|
USBD_LL_OpenEP(pdev,
|
||||||
|
CDC_IN_EP,
|
||||||
|
USBD_EP_TYPE_BULK,
|
||||||
|
CDC_DATA_HS_IN_PACKET_SIZE);
|
||||||
|
|
||||||
|
/* Open EP OUT */
|
||||||
|
USBD_LL_OpenEP(pdev,
|
||||||
|
CDC_OUT_EP,
|
||||||
|
USBD_EP_TYPE_BULK,
|
||||||
|
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Open EP IN */
|
||||||
|
USBD_LL_OpenEP(pdev,
|
||||||
|
CDC_IN_EP,
|
||||||
|
USBD_EP_TYPE_BULK,
|
||||||
|
CDC_DATA_FS_IN_PACKET_SIZE);
|
||||||
|
|
||||||
|
/* Open EP OUT */
|
||||||
|
USBD_LL_OpenEP(pdev,
|
||||||
|
CDC_OUT_EP,
|
||||||
|
USBD_EP_TYPE_BULK,
|
||||||
|
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||||
|
}
|
||||||
|
/* Open Command IN EP */
|
||||||
|
USBD_LL_OpenEP(pdev,
|
||||||
|
CDC_CMD_EP,
|
||||||
|
USBD_EP_TYPE_INTR,
|
||||||
|
CDC_CMD_PACKET_SIZE);
|
||||||
|
|
||||||
|
|
||||||
|
pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));
|
||||||
|
|
||||||
|
if(pdev->pClassData == NULL)
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
/* Init physical Interface components */
|
||||||
|
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
|
||||||
|
|
||||||
|
/* Init Xfer states */
|
||||||
|
hcdc->TxState =0;
|
||||||
|
hcdc->RxState =0;
|
||||||
|
|
||||||
|
if(pdev->dev_speed == USBD_SPEED_HIGH )
|
||||||
|
{
|
||||||
|
/* Prepare Out endpoint to receive next packet */
|
||||||
|
USBD_LL_PrepareReceive(pdev,
|
||||||
|
CDC_OUT_EP,
|
||||||
|
hcdc->RxBuffer,
|
||||||
|
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Prepare Out endpoint to receive next packet */
|
||||||
|
USBD_LL_PrepareReceive(pdev,
|
||||||
|
CDC_OUT_EP,
|
||||||
|
hcdc->RxBuffer,
|
||||||
|
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_Init
|
||||||
|
* DeInitialize the CDC layer
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param cfgidx: Configuration index
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t cfgidx)
|
||||||
|
{
|
||||||
|
uint8_t ret = 0;
|
||||||
|
|
||||||
|
/* Open EP IN */
|
||||||
|
USBD_LL_CloseEP(pdev,
|
||||||
|
CDC_IN_EP);
|
||||||
|
|
||||||
|
/* Open EP OUT */
|
||||||
|
USBD_LL_CloseEP(pdev,
|
||||||
|
CDC_OUT_EP);
|
||||||
|
|
||||||
|
/* Open Command IN EP */
|
||||||
|
USBD_LL_CloseEP(pdev,
|
||||||
|
CDC_CMD_EP);
|
||||||
|
|
||||||
|
|
||||||
|
/* DeInit physical Interface components */
|
||||||
|
if(pdev->pClassData != NULL)
|
||||||
|
{
|
||||||
|
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
|
||||||
|
USBD_free(pdev->pClassData);
|
||||||
|
pdev->pClassData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_Setup
|
||||||
|
* Handle the CDC specific requests
|
||||||
|
* @param pdev: instance
|
||||||
|
* @param req: usb requests
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
static uint8_t ifalt = 0;
|
||||||
|
|
||||||
|
switch (req->bmRequest & USB_REQ_TYPE_MASK)
|
||||||
|
{
|
||||||
|
case USB_REQ_TYPE_CLASS :
|
||||||
|
if (req->wLength)
|
||||||
|
{
|
||||||
|
if (req->bmRequest & 0x80)
|
||||||
|
{
|
||||||
|
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
|
||||||
|
(uint8_t *)hcdc->data,
|
||||||
|
req->wLength);
|
||||||
|
USBD_CtlSendData (pdev,
|
||||||
|
(uint8_t *)hcdc->data,
|
||||||
|
req->wLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hcdc->CmdOpCode = req->bRequest;
|
||||||
|
hcdc->CmdLength = req->wLength;
|
||||||
|
|
||||||
|
USBD_CtlPrepareRx (pdev,
|
||||||
|
(uint8_t *)hcdc->data,
|
||||||
|
req->wLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
|
||||||
|
(uint8_t*)req,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_TYPE_STANDARD:
|
||||||
|
switch (req->bRequest)
|
||||||
|
{
|
||||||
|
case USB_REQ_GET_INTERFACE :
|
||||||
|
USBD_CtlSendData (pdev,
|
||||||
|
&ifalt,
|
||||||
|
1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_SET_INTERFACE :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_DataIn
|
||||||
|
* Data sent on non-control IN endpoint
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param epnum: endpoint number
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
if(pdev->pClassData != NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
hcdc->TxState = 0;
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return USBD_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_DataOut
|
||||||
|
* Data received on non-control Out endpoint
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param epnum: endpoint number
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
/* Get the received data length */
|
||||||
|
hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
|
||||||
|
|
||||||
|
/* USB data will be immediately processed, this allow next USB traffic being
|
||||||
|
NAKed till the end of the application Xfer */
|
||||||
|
if(pdev->pClassData != NULL)
|
||||||
|
{
|
||||||
|
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return USBD_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_DataOut
|
||||||
|
* Data received on non-control Out endpoint
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param epnum: endpoint number
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
|
||||||
|
{
|
||||||
|
((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
|
||||||
|
(uint8_t *)hcdc->data,
|
||||||
|
hcdc->CmdLength);
|
||||||
|
hcdc->CmdOpCode = 0xFF;
|
||||||
|
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_GetFSCfgDesc
|
||||||
|
* Return configuration descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer data length
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length)
|
||||||
|
{
|
||||||
|
*length = sizeof (USBD_CDC_CfgFSDesc);
|
||||||
|
return USBD_CDC_CfgFSDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_GetHSCfgDesc
|
||||||
|
* Return configuration descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer data length
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length)
|
||||||
|
{
|
||||||
|
*length = sizeof (USBD_CDC_CfgHSDesc);
|
||||||
|
return USBD_CDC_CfgHSDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_GetCfgDesc
|
||||||
|
* Return configuration descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer data length
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length)
|
||||||
|
{
|
||||||
|
*length = sizeof (USBD_CDC_OtherSpeedCfgDesc);
|
||||||
|
return USBD_CDC_OtherSpeedCfgDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DeviceQualifierDescriptor
|
||||||
|
* return Device Qualifier descriptor
|
||||||
|
* @param length : pointer data length
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length)
|
||||||
|
{
|
||||||
|
*length = sizeof (USBD_CDC_DeviceQualifierDesc);
|
||||||
|
return USBD_CDC_DeviceQualifierDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_RegisterInterface
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param fops: CD Interface callback
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev,
|
||||||
|
USBD_CDC_ItfTypeDef *fops)
|
||||||
|
{
|
||||||
|
uint8_t ret = USBD_FAIL;
|
||||||
|
|
||||||
|
if(fops != NULL)
|
||||||
|
{
|
||||||
|
pdev->pUserData= fops;
|
||||||
|
ret = USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_SetTxBuffer
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param pbuff: Tx Buffer
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuff,
|
||||||
|
uint16_t length)
|
||||||
|
{
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
hcdc->TxBuffer = pbuff;
|
||||||
|
hcdc->TxLength = length;
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_SetRxBuffer
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param pbuff: Rx Buffer
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuff)
|
||||||
|
{
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
hcdc->RxBuffer = pbuff;
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_DataOut
|
||||||
|
* Data received on non-control Out endpoint
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param epnum: endpoint number
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
if(pdev->pClassData != NULL)
|
||||||
|
{
|
||||||
|
if(hcdc->TxState == 0)
|
||||||
|
{
|
||||||
|
/* Tx Transfer in progress */
|
||||||
|
hcdc->TxState = 1;
|
||||||
|
|
||||||
|
/* Transmit next packet */
|
||||||
|
USBD_LL_Transmit(pdev,
|
||||||
|
CDC_IN_EP,
|
||||||
|
hcdc->TxBuffer,
|
||||||
|
hcdc->TxLength);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return USBD_BUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return USBD_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CDC_ReceivePacket
|
||||||
|
* prepare OUT Endpoint for reception
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
|
||||||
|
|
||||||
|
/* Suspend or Resume USB Out process */
|
||||||
|
if(pdev->pClassData != NULL)
|
||||||
|
{
|
||||||
|
if(pdev->dev_speed == USBD_SPEED_HIGH )
|
||||||
|
{
|
||||||
|
/* Prepare Out endpoint to receive next packet */
|
||||||
|
USBD_LL_PrepareReceive(pdev,
|
||||||
|
CDC_OUT_EP,
|
||||||
|
hcdc->RxBuffer,
|
||||||
|
CDC_DATA_HS_OUT_PACKET_SIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Prepare Out endpoint to receive next packet */
|
||||||
|
USBD_LL_PrepareReceive(pdev,
|
||||||
|
CDC_OUT_EP,
|
||||||
|
hcdc->RxBuffer,
|
||||||
|
CDC_DATA_FS_OUT_PACKET_SIZE);
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return USBD_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,179 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_cdc.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief header file for the usbd_cdc.c file.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USB_CDC_H
|
||||||
|
#define __USB_CDC_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_ioreq.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup usbd_cdc
|
||||||
|
* @brief This file is the Header file for usbd_cdc.c
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup usbd_cdc_Exported_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define CDC_IN_EP 0x81 /* EP1 for data IN */
|
||||||
|
#define CDC_OUT_EP 0x01 /* EP1 for data OUT */
|
||||||
|
#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */
|
||||||
|
|
||||||
|
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
|
||||||
|
#define CDC_DATA_HS_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */
|
||||||
|
#define CDC_DATA_FS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */
|
||||||
|
#define CDC_CMD_PACKET_SIZE 8 /* Control Endpoint Packet size */
|
||||||
|
|
||||||
|
#define USB_CDC_CONFIG_DESC_SIZ 67
|
||||||
|
#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
|
||||||
|
#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
|
||||||
|
|
||||||
|
#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
|
||||||
|
#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
/* CDC definitions */
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
|
||||||
|
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
|
||||||
|
#define CDC_SET_COMM_FEATURE 0x02
|
||||||
|
#define CDC_GET_COMM_FEATURE 0x03
|
||||||
|
#define CDC_CLEAR_COMM_FEATURE 0x04
|
||||||
|
#define CDC_SET_LINE_CODING 0x20
|
||||||
|
#define CDC_GET_LINE_CODING 0x21
|
||||||
|
#define CDC_SET_CONTROL_LINE_STATE 0x22
|
||||||
|
#define CDC_SEND_BREAK 0x23
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t bitrate;
|
||||||
|
uint8_t format;
|
||||||
|
uint8_t paritytype;
|
||||||
|
uint8_t datatype;
|
||||||
|
}USBD_CDC_LineCodingTypeDef;
|
||||||
|
|
||||||
|
typedef struct _USBD_CDC_Itf
|
||||||
|
{
|
||||||
|
int8_t (* Init) (void);
|
||||||
|
int8_t (* DeInit) (void);
|
||||||
|
int8_t (* Control) (uint8_t, uint8_t * , uint16_t);
|
||||||
|
int8_t (* Receive) (uint8_t *, uint32_t *);
|
||||||
|
|
||||||
|
}USBD_CDC_ItfTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */
|
||||||
|
uint8_t CmdOpCode;
|
||||||
|
uint8_t CmdLength;
|
||||||
|
uint8_t *RxBuffer;
|
||||||
|
uint8_t *TxBuffer;
|
||||||
|
uint32_t RxLength;
|
||||||
|
uint32_t TxLength;
|
||||||
|
|
||||||
|
__IO uint32_t TxState;
|
||||||
|
__IO uint32_t RxState;
|
||||||
|
}
|
||||||
|
USBD_CDC_HandleTypeDef;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern USBD_ClassTypeDef USBD_CDC;
|
||||||
|
#define USBD_CDC_CLASS &USBD_CDC
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USB_CORE_Exported_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev,
|
||||||
|
USBD_CDC_ItfTypeDef *fops);
|
||||||
|
|
||||||
|
uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuff,
|
||||||
|
uint16_t length);
|
||||||
|
|
||||||
|
uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuff);
|
||||||
|
|
||||||
|
uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev);
|
||||||
|
|
||||||
|
uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __USB_CDC_H */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,322 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : usbd_cdc_if.c
|
||||||
|
* @brief :
|
||||||
|
******************************************************************************
|
||||||
|
* COPYRIGHT(c) 2016 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_cdc_if.h"
|
||||||
|
/* USER CODE BEGIN INCLUDE */
|
||||||
|
|
||||||
|
//#include "variant.h"
|
||||||
|
/* USER CODE END INCLUDE */
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC
|
||||||
|
* @brief usbd core module
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN PRIVATE_TYPES */
|
||||||
|
/* USER CODE END PRIVATE_TYPES */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN PRIVATE_DEFINES */
|
||||||
|
/* Define size for the receive and transmit buffer over CDC */
|
||||||
|
/* It's up to user to redefine and/or remove those define */
|
||||||
|
#define APP_RX_DATA_SIZE CDC_SERIAL_BUFFER_SIZE
|
||||||
|
#define APP_TX_DATA_SIZE CDC_SERIAL_BUFFER_SIZE
|
||||||
|
/* USER CODE END PRIVATE_DEFINES */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN PRIVATE_MACRO */
|
||||||
|
/* USER CODE END PRIVATE_MACRO */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* Create buffer for reception and transmission */
|
||||||
|
/* It's up to user to redefine and/or remove those define */
|
||||||
|
/* Received Data over USB are stored in this buffer */
|
||||||
|
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
|
||||||
|
|
||||||
|
/* Send Data over USB CDC are stored in this buffer */
|
||||||
|
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
|
||||||
|
|
||||||
|
/* USER CODE BEGIN PRIVATE_VARIABLES */
|
||||||
|
/* USB handler declaration */
|
||||||
|
/* Handle for USB Full Speed IP */
|
||||||
|
//USBD_HandleTypeDef *hUsbDevice_0;
|
||||||
|
/* USER CODE BEGIN PRIVATE_VARIABLES */
|
||||||
|
uint8_t dtr_pin = 0; //DTR pin is disabled
|
||||||
|
/* USER CODE END PRIVATE_VARIABLES */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_IF_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||||
|
/* USER CODE BEGIN EXPORTED_VARIABLES */
|
||||||
|
/* USER CODE END EXPORTED_VARIABLES */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_Private_FunctionPrototypes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
static int8_t CDC_Init_FS (void);
|
||||||
|
static int8_t CDC_DeInit_FS (void);
|
||||||
|
static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length);
|
||||||
|
static int8_t CDC_Receive_FS (uint8_t* pbuf, uint32_t *Len);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
|
||||||
|
/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
|
||||||
|
{
|
||||||
|
CDC_Init_FS,
|
||||||
|
CDC_DeInit_FS,
|
||||||
|
CDC_Control_FS,
|
||||||
|
CDC_Receive_FS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief CDC_Init_FS
|
||||||
|
* Initializes the CDC media low layer over the FS USB IP
|
||||||
|
* @param None
|
||||||
|
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||||
|
*/
|
||||||
|
static int8_t CDC_Init_FS(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 3 */
|
||||||
|
/* Set Application Buffers */
|
||||||
|
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
|
||||||
|
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
|
||||||
|
return (USBD_OK);
|
||||||
|
/* USER CODE END 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CDC_DeInit_FS
|
||||||
|
* DeInitializes the CDC media low layer
|
||||||
|
* @param None
|
||||||
|
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||||
|
*/
|
||||||
|
static int8_t CDC_DeInit_FS(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 4 */
|
||||||
|
return (USBD_OK);
|
||||||
|
/* USER CODE END 4 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CDC_Control_FS
|
||||||
|
* Manage the CDC class requests
|
||||||
|
* @param cmd: Command code
|
||||||
|
* @param pbuf: Buffer containing command data (request parameters)
|
||||||
|
* @param length: Number of data to be sent (in bytes)
|
||||||
|
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||||
|
*/
|
||||||
|
static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 5 */
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case CDC_SEND_ENCAPSULATED_COMMAND:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CDC_GET_ENCAPSULATED_RESPONSE:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CDC_SET_COMM_FEATURE:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CDC_GET_COMM_FEATURE:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CDC_CLEAR_COMM_FEATURE:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* Line Coding Structure */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Offset | Field | Size | Value | Description */
|
||||||
|
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
|
||||||
|
/* 4 | bCharFormat | 1 | Number | Stop bits */
|
||||||
|
/* 0 - 1 Stop bit */
|
||||||
|
/* 1 - 1.5 Stop bits */
|
||||||
|
/* 2 - 2 Stop bits */
|
||||||
|
/* 5 | bParityType | 1 | Number | Parity */
|
||||||
|
/* 0 - None */
|
||||||
|
/* 1 - Odd */
|
||||||
|
/* 2 - Even */
|
||||||
|
/* 3 - Mark */
|
||||||
|
/* 4 - Space */
|
||||||
|
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
|
||||||
|
/*******************************************************************************/
|
||||||
|
case CDC_SET_LINE_CODING:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CDC_GET_LINE_CODING:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CDC_SET_CONTROL_LINE_STATE:
|
||||||
|
dtr_pin++; //DTR pin is enabled
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CDC_SEND_BREAK:
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (USBD_OK);
|
||||||
|
/* USER CODE END 5 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CDC_Receive_FS
|
||||||
|
* Data received over USB OUT endpoint are sent over CDC interface
|
||||||
|
* through this function.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* This function will block any OUT packet reception on USB endpoint
|
||||||
|
* untill exiting this function. If you exit this function before transfer
|
||||||
|
* is complete on CDC interface (ie. using DMA controller) it will result
|
||||||
|
* in receiving more data while previous ones are still not sent.
|
||||||
|
*
|
||||||
|
* @param Buf: Buffer of data to be received
|
||||||
|
* @param Len: Number of data received (in bytes)
|
||||||
|
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
|
||||||
|
*/
|
||||||
|
static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 6 */
|
||||||
|
/* Four byte is the magic pack "1EAF" that puts the MCU into bootloader. */
|
||||||
|
if(*Len >= 4){
|
||||||
|
/**
|
||||||
|
* Check if the incoming contains the string "1EAF".
|
||||||
|
* If yes, check if the DTR has been set, to put the MCU into the bootloader mode.
|
||||||
|
*/
|
||||||
|
if(dtr_pin > 3){
|
||||||
|
if((Buf[0] == '1')&&(Buf[1] == 'E')&&(Buf[2] == 'A')&&(Buf[3] == 'F')){
|
||||||
|
HAL_NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
dtr_pin = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t len = *Len;
|
||||||
|
USBSerial_Rx_Handler((uint8_t *)&Buf[0], len);
|
||||||
|
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
|
||||||
|
|
||||||
|
//USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
|
||||||
|
//USBD_CDC_ReceivePacket(&hUsbDeviceFS);
|
||||||
|
//HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
|
||||||
|
return (USBD_OK);
|
||||||
|
/* USER CODE END 6 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CDC_Transmit_FS
|
||||||
|
* Data send over USB IN endpoint are sent over CDC interface
|
||||||
|
* through this function.
|
||||||
|
* @note
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param Buf: Buffer of data to be send
|
||||||
|
* @param Len: Number of data to be send (in bytes)
|
||||||
|
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
|
||||||
|
*/
|
||||||
|
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
|
||||||
|
{
|
||||||
|
uint8_t result = USBD_OK;
|
||||||
|
/* USER CODE BEGIN 7 */
|
||||||
|
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
|
||||||
|
if (hcdc->TxState != 0){
|
||||||
|
return USBD_BUSY;
|
||||||
|
}
|
||||||
|
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
|
||||||
|
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
|
||||||
|
/* USER CODE END 7 */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
|
||||||
|
/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : usbd_cdc_if.h
|
||||||
|
* @brief : Header for usbd_cdc_if file.
|
||||||
|
******************************************************************************
|
||||||
|
* COPYRIGHT(c) 2016 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USBD_CDC_IF_H
|
||||||
|
#define __USBD_CDC_IF_H
|
||||||
|
|
||||||
|
#define CDC_SERIAL_BUFFER_SIZE 128 //USBSerial buffer data length
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_cdc.h"
|
||||||
|
/* USER CODE BEGIN INCLUDE */
|
||||||
|
/* USER CODE END INCLUDE */
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_IF
|
||||||
|
* @brief header
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_IF_Exported_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN EXPORTED_DEFINES */
|
||||||
|
uint8_t CDC_getTransmitterStatus(void);
|
||||||
|
/* USER CODE END EXPORTED_DEFINES */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_IF_Exported_Types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN EXPORTED_TYPES */
|
||||||
|
/* USER CODE END EXPORTED_TYPES */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_IF_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* USER CODE BEGIN EXPORTED_MACRO */
|
||||||
|
/* USER CODE END EXPORTED_MACRO */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_AUDIO_IF_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
|
||||||
|
|
||||||
|
/* USER CODE BEGIN EXPORTED_VARIABLES */
|
||||||
|
/* USER CODE END EXPORTED_VARIABLES */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN EXPORTED_FUNCTIONS */
|
||||||
|
extern void USBSerial_Rx_Handler(uint8_t *data, uint16_t len);
|
||||||
|
/* USER CODE END EXPORTED_FUNCTIONS */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __USBD_CDC_IF_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,176 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : usbd_conf.h
|
||||||
|
* @version : v1.0_Cube
|
||||||
|
* @brief : Header for usbd_conf file.
|
||||||
|
******************************************************************************
|
||||||
|
* COPYRIGHT(c) 2016 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USBD_CONF__H__
|
||||||
|
#define __USBD_CONF__H__
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "stm32_def.h"
|
||||||
|
|
||||||
|
#include "usbd_def.h"
|
||||||
|
|
||||||
|
/** @addtogroup USBD_OTG_DRIVER
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CONF
|
||||||
|
* @brief usb otg low level driver configuration file
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CONF_Exported_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------- -----------*/
|
||||||
|
#define USBD_MAX_NUM_INTERFACES 1
|
||||||
|
/*---------- -----------*/
|
||||||
|
#define USBD_MAX_NUM_CONFIGURATION 1
|
||||||
|
/*---------- -----------*/
|
||||||
|
#define USBD_MAX_STR_DESC_SIZ 512
|
||||||
|
/*---------- -----------*/
|
||||||
|
#define USBD_SUPPORT_USER_STRING 0
|
||||||
|
/*---------- -----------*/
|
||||||
|
#define USBD_DEBUG_LEVEL 0
|
||||||
|
/*---------- -----------*/
|
||||||
|
#define USBD_SELF_POWERED 1
|
||||||
|
/*---------- -----------*/
|
||||||
|
#define USBD_CDC_INTERVAL 1000
|
||||||
|
/*---------- -----------*/
|
||||||
|
#define MAX_STATIC_ALLOC_SIZE 512
|
||||||
|
/****************************************/
|
||||||
|
/* #define for FS and HS identification */
|
||||||
|
#define DEVICE_FS 0
|
||||||
|
|
||||||
|
/** @defgroup USBD_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory management macros */
|
||||||
|
#define USBD_malloc (uint32_t *)USBD_static_malloc
|
||||||
|
#define USBD_free USBD_static_free
|
||||||
|
#define USBD_memset /* Not used */
|
||||||
|
#define USBD_memcpy /* Not used */
|
||||||
|
|
||||||
|
#define USBD_Delay HAL_Delay
|
||||||
|
|
||||||
|
/* For footprint reasons and since only one allocation is handled in the HID class
|
||||||
|
driver, the malloc/free is changed into a static allocation method */
|
||||||
|
void *USBD_static_malloc(uint32_t size);
|
||||||
|
void USBD_static_free(void *p);
|
||||||
|
|
||||||
|
/* DEBUG macros */
|
||||||
|
#if (USBD_DEBUG_LEVEL > 0)
|
||||||
|
#define USBD_UsrLog(...) printf(__VA_ARGS__);\
|
||||||
|
printf("\n");
|
||||||
|
#else
|
||||||
|
#define USBD_UsrLog(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (USBD_DEBUG_LEVEL > 1)
|
||||||
|
|
||||||
|
#define USBD_ErrLog(...) printf("ERROR: ") ;\
|
||||||
|
printf(__VA_ARGS__);\
|
||||||
|
printf("\n");
|
||||||
|
#else
|
||||||
|
#define USBD_ErrLog(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (USBD_DEBUG_LEVEL > 2)
|
||||||
|
#define USBD_DbgLog(...) printf("DEBUG : ") ;\
|
||||||
|
printf(__VA_ARGS__);\
|
||||||
|
printf("\n");
|
||||||
|
#else
|
||||||
|
#define USBD_DbgLog(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CONF_Exported_Types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CONF_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CONF_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CONF_Exported_FunctionsPrototype
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__USBD_CONF__H__*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
|
@ -0,0 +1,514 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : usbd_conf.c
|
||||||
|
* @version : v1.0_Cube
|
||||||
|
* @brief : This file implements the board support package for the USB device library
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* COPYRIGHT(c) 2016 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef STM32F1
|
||||||
|
|
||||||
|
#include "stm32_def.h"
|
||||||
|
|
||||||
|
#include "usbd_def.h"
|
||||||
|
#include "usbd_core.h"
|
||||||
|
#include "usbd_cdc.h"
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
PCD_HandleTypeDef hpcd_USB_FS;
|
||||||
|
void Error_Handler(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
/* USER CODE END 1 */
|
||||||
|
void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
LL Driver Callbacks (PCD -> USB Device Library)
|
||||||
|
*******************************************************************************/
|
||||||
|
/* MSP Init */
|
||||||
|
|
||||||
|
void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
|
||||||
|
{
|
||||||
|
if(pcdHandle->Instance==USB)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USB_MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_MspInit 0 */
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
__HAL_RCC_USB_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* Peripheral interrupt init */
|
||||||
|
HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||||
|
/* USER CODE BEGIN USB_MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_MspInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
|
||||||
|
{
|
||||||
|
if(pcdHandle->Instance==USB)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USB_MspDeInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_MspDeInit 0 */
|
||||||
|
/* Peripheral clock disable */
|
||||||
|
__HAL_RCC_USB_CLK_DISABLE();
|
||||||
|
|
||||||
|
/* Peripheral interrupt Deinit*/
|
||||||
|
HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USB_MspDeInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_MspDeInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setup Stage callback
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Data Out Stage callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Data In Stage callback..
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SOF callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
|
||||||
|
|
||||||
|
/*Set USB Current Speed*/
|
||||||
|
switch (hpcd->Init.speed)
|
||||||
|
{
|
||||||
|
case PCD_SPEED_FULL:
|
||||||
|
speed = USBD_SPEED_FULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
speed = USBD_SPEED_FULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed);
|
||||||
|
|
||||||
|
/*Reset Device*/
|
||||||
|
USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Suspend callback.
|
||||||
|
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
/* Inform USB library that core enters in suspend Mode */
|
||||||
|
USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
/*Enter in STOP mode */
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
if (hpcd->Init.low_power_enable)
|
||||||
|
{
|
||||||
|
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */
|
||||||
|
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
|
||||||
|
}
|
||||||
|
/* USER CODE END 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resume callback.
|
||||||
|
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 3 */
|
||||||
|
/* USER CODE END 3 */
|
||||||
|
USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISOOUTIncomplete callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISOINIncomplete callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ConnectCallback callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnect callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
LL Driver Interface (USB Device Library --> PCD)
|
||||||
|
*******************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Initializes the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
/* Init USB_IP */
|
||||||
|
/* Link The driver to the stack */
|
||||||
|
hpcd_USB_FS.pData = pdev;
|
||||||
|
pdev->pData = &hpcd_USB_FS;
|
||||||
|
|
||||||
|
hpcd_USB_FS.Instance = USB;
|
||||||
|
hpcd_USB_FS.Init.dev_endpoints = 8;
|
||||||
|
hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
|
||||||
|
hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_8;
|
||||||
|
hpcd_USB_FS.Init.low_power_enable = DISABLE;
|
||||||
|
hpcd_USB_FS.Init.lpm_enable = DISABLE;
|
||||||
|
hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
|
||||||
|
if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0);
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110);
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-Initializes the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_DeInit((PCD_HandleTypeDef*)pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_Start((PCD_HandleTypeDef*)pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stops the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_Stop((PCD_HandleTypeDef*) pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opens an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param ep_type: Endpoint Type
|
||||||
|
* @param ep_mps: Endpoint Max Packet Size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t ep_type,
|
||||||
|
uint16_t ep_mps)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Open((PCD_HandleTypeDef*) pdev->pData,
|
||||||
|
ep_addr,
|
||||||
|
ep_mps,
|
||||||
|
ep_type);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Close((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flushes an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Flush((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_SetStall((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_ClrStall((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns Stall condition.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval Stall (1: Yes, 0: No)
|
||||||
|
*/
|
||||||
|
uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData;
|
||||||
|
|
||||||
|
if((ep_addr & 0x80) == 0x80)
|
||||||
|
{
|
||||||
|
return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Assigns a USB address to the device.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_SetAddress((PCD_HandleTypeDef*) pdev->pData, dev_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Transmits data over an endpoint.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param pbuf: Pointer to data to be sent
|
||||||
|
* @param size: Data size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t size)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Transmit((PCD_HandleTypeDef*) pdev->pData, ep_addr, pbuf, size);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prepares an endpoint for reception.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param pbuf: Pointer to data to be received
|
||||||
|
* @param size: Data size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t size)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Receive((PCD_HandleTypeDef*) pdev->pData, ep_addr, pbuf, size);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the last transfered packet size.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval Recived Data Size
|
||||||
|
*/
|
||||||
|
uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delays routine for the USB Device Library.
|
||||||
|
* @param Delay: Delay in ms
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void USBD_LL_Delay (uint32_t Delay)
|
||||||
|
{
|
||||||
|
HAL_Delay(Delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief static single allocation.
|
||||||
|
* @param size: size of allocated memory
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void *USBD_static_malloc(uint32_t size)
|
||||||
|
{
|
||||||
|
static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dummy memory free
|
||||||
|
* @param *p pointer to allocated memory address
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void USBD_static_free(void *p)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Software Device Connection
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param state: connection state (0 : disconnected / 1: connected)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 5 */
|
||||||
|
if (state == 1)
|
||||||
|
{
|
||||||
|
/* Configure Low Connection State */
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Configure High Connection State */
|
||||||
|
|
||||||
|
}
|
||||||
|
/* USER CODE END 5 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,557 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : usbd_conf.c
|
||||||
|
* @version : v1.0_Cube
|
||||||
|
* @brief : This file implements the board support package for the USB device library
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* COPYRIGHT(c) 2017 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#ifdef STM32F4
|
||||||
|
|
||||||
|
#include "stm32_def.h"
|
||||||
|
|
||||||
|
#include "usbd_def.h"
|
||||||
|
#include "usbd_core.h"
|
||||||
|
#include "usbd_cdc.h"
|
||||||
|
|
||||||
|
PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
||||||
|
void Error_Handler(void);
|
||||||
|
|
||||||
|
/* External functions --------------------------------------------------------*/
|
||||||
|
void SystemClock_Config(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
LL Driver Callbacks (PCD -> USB Device Library)
|
||||||
|
*******************************************************************************/
|
||||||
|
/* MSP Init */
|
||||||
|
|
||||||
|
void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
if(pcdHandle->Instance==USB_OTG_FS)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USB_OTG_FS_MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_OTG_FS_MspInit 0 */
|
||||||
|
|
||||||
|
/**USB_OTG_FS GPIO Configuration
|
||||||
|
PA11 ------> USB_OTG_FS_DM
|
||||||
|
PA12 ------> USB_OTG_FS_DP
|
||||||
|
*/
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||||
|
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* Peripheral interrupt init */
|
||||||
|
HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||||
|
/* USER CODE BEGIN USB_OTG_FS_MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_OTG_FS_MspInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
|
||||||
|
{
|
||||||
|
if(pcdHandle->Instance==USB_OTG_FS)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_OTG_FS_MspDeInit 0 */
|
||||||
|
/* Peripheral clock disable */
|
||||||
|
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
|
||||||
|
|
||||||
|
/**USB_OTG_FS GPIO Configuration
|
||||||
|
PA11 ------> USB_OTG_FS_DM
|
||||||
|
PA12 ------> USB_OTG_FS_DP
|
||||||
|
*/
|
||||||
|
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
|
||||||
|
|
||||||
|
/* Peripheral interrupt Deinit*/
|
||||||
|
HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_OTG_FS_MspDeInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setup stage callback
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_SetupStage(hpcd->pData, (uint8_t *)hpcd->Setup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Data Out stage callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_DataOutStage(hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Data In stage callback..
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_DataInStage(hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SOF callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_SOF(hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
|
||||||
|
|
||||||
|
/*Set USB Current Speed*/
|
||||||
|
switch (hpcd->Init.speed)
|
||||||
|
{
|
||||||
|
case PCD_SPEED_HIGH:
|
||||||
|
speed = USBD_SPEED_HIGH;
|
||||||
|
break;
|
||||||
|
case PCD_SPEED_FULL:
|
||||||
|
speed = USBD_SPEED_FULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
speed = USBD_SPEED_FULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
USBD_LL_SetSpeed(hpcd->pData, speed);
|
||||||
|
|
||||||
|
/*Reset Device*/
|
||||||
|
USBD_LL_Reset(hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Suspend callback.
|
||||||
|
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
/* Inform USB library that core enters in suspend Mode */
|
||||||
|
USBD_LL_Suspend(hpcd->pData);
|
||||||
|
__HAL_PCD_GATE_PHYCLOCK(hpcd);
|
||||||
|
/*Enter in STOP mode */
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
if (hpcd->Init.low_power_enable)
|
||||||
|
{
|
||||||
|
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */
|
||||||
|
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
|
||||||
|
}
|
||||||
|
/* USER CODE END 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resume callback.
|
||||||
|
When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 3 */
|
||||||
|
/* USER CODE END 3 */
|
||||||
|
USBD_LL_Resume(hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISOC Out Incomplete callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_IsoOUTIncomplete(hpcd->pData, epnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISOC In Incomplete callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_IsoINIncomplete(hpcd->pData, epnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Connect callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_DevConnected(hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnect callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_DevDisconnected(hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
LL Driver Interface (USB Device Library --> PCD)
|
||||||
|
*******************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Initializes the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
/* Init USB_IP */
|
||||||
|
if (pdev->id == DEVICE_FS) {
|
||||||
|
/* Link The driver to the stack */
|
||||||
|
hpcd_USB_OTG_FS.pData = pdev;
|
||||||
|
pdev->pData = &hpcd_USB_OTG_FS;
|
||||||
|
|
||||||
|
hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
|
||||||
|
hpcd_USB_OTG_FS.Init.dev_endpoints = 4;
|
||||||
|
hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
|
||||||
|
hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
|
||||||
|
hpcd_USB_OTG_FS.Init.ep0_mps = DEP0CTL_MPS_64;
|
||||||
|
hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
|
||||||
|
hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
|
||||||
|
hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
|
||||||
|
hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
|
||||||
|
hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;
|
||||||
|
hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
|
||||||
|
if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
|
||||||
|
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40);
|
||||||
|
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-Initializes the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_DeInit(pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_Start(pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stops the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_Stop(pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opens an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param ep_type: Endpoint Type
|
||||||
|
* @param ep_mps: Endpoint Max Packet Size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t ep_type,
|
||||||
|
uint16_t ep_mps)
|
||||||
|
{
|
||||||
|
|
||||||
|
HAL_PCD_EP_Open(pdev->pData,
|
||||||
|
ep_addr,
|
||||||
|
ep_mps,
|
||||||
|
ep_type);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
HAL_PCD_EP_Close(pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flushes an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
HAL_PCD_EP_Flush(pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns Stall condition.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval Stall (1: Yes, 0: No)
|
||||||
|
*/
|
||||||
|
uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
PCD_HandleTypeDef *hpcd = pdev->pData;
|
||||||
|
|
||||||
|
if((ep_addr & 0x80) == 0x80)
|
||||||
|
{
|
||||||
|
return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Assigns a USB address to the device.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
HAL_PCD_SetAddress(pdev->pData, dev_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Transmits data over an endpoint.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param pbuf: Pointer to data to be sent
|
||||||
|
* @param size: Data size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prepares an endpoint for reception.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param pbuf: Pointer to data to be received
|
||||||
|
* @param size: Data size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the last transfered packet size.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval Recived Data Size
|
||||||
|
*/
|
||||||
|
uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (USBD_LPM_ENABLED == 1)
|
||||||
|
/**
|
||||||
|
* @brief HAL_PCDEx_LPM_Callback : Send LPM message to user layer
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param msg: LPM message
|
||||||
|
* @retval HAL status
|
||||||
|
*/
|
||||||
|
void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg)
|
||||||
|
{
|
||||||
|
switch ( msg)
|
||||||
|
{
|
||||||
|
case PCD_LPM_L0_ACTIVE:
|
||||||
|
if (hpcd->Init.low_power_enable)
|
||||||
|
{
|
||||||
|
SystemClock_Config();
|
||||||
|
|
||||||
|
/* Reset SLEEPDEEP bit of Cortex System Control Register */
|
||||||
|
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
|
||||||
|
}
|
||||||
|
__HAL_PCD_UNGATE_PHYCLOCK(hpcd);
|
||||||
|
USBD_LL_Resume(hpcd->pData);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCD_LPM_L1_ACTIVE:
|
||||||
|
__HAL_PCD_GATE_PHYCLOCK(hpcd);
|
||||||
|
USBD_LL_Suspend(hpcd->pData);
|
||||||
|
|
||||||
|
/*Enter in STOP mode */
|
||||||
|
if (hpcd->Init.low_power_enable)
|
||||||
|
{
|
||||||
|
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */
|
||||||
|
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief Delays routine for the USB Device Library.
|
||||||
|
* @param Delay: Delay in ms
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void USBD_LL_Delay (uint32_t Delay)
|
||||||
|
{
|
||||||
|
HAL_Delay(Delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void *USBD_static_malloc(uint32_t size)
|
||||||
|
{
|
||||||
|
static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dummy memory free
|
||||||
|
* @param *p pointer to allocated memory address
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void USBD_static_free(void *p)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,536 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : usbd_conf.c
|
||||||
|
* @version : v1.0_Cube
|
||||||
|
* @brief : This file implements the board support package for the USB device library
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* COPYRIGHT(c) 2017 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#ifdef STM32L0
|
||||||
|
|
||||||
|
#include "stm32_def.h"
|
||||||
|
|
||||||
|
#include "usbd_def.h"
|
||||||
|
#include "usbd_core.h"
|
||||||
|
#include "usbd_cdc.h"
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
PCD_HandleTypeDef hpcd_USB_FS;
|
||||||
|
void Error_Handler(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
static void SystemClockConfig_Resume(void);
|
||||||
|
/* USER CODE END 1 */
|
||||||
|
void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state);
|
||||||
|
extern void SystemClock_Config(void);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
LL Driver Callbacks (PCD -> USB Device Library)
|
||||||
|
*******************************************************************************/
|
||||||
|
/* MSP Init */
|
||||||
|
|
||||||
|
void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
|
||||||
|
{
|
||||||
|
if(pcdHandle->Instance==USB)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USB_MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_MspInit 0 */
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
__HAL_RCC_USB_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* Peripheral interrupt init */
|
||||||
|
HAL_NVIC_SetPriority(USB_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(USB_IRQn);
|
||||||
|
/* USER CODE BEGIN USB_MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_MspInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
|
||||||
|
{
|
||||||
|
if(pcdHandle->Instance==USB)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USB_MspDeInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_MspDeInit 0 */
|
||||||
|
/* Disable Peripheral clock */
|
||||||
|
__HAL_RCC_USB_CLK_DISABLE();
|
||||||
|
|
||||||
|
/* Peripheral interrupt Deinit*/
|
||||||
|
HAL_NVIC_DisableIRQ(USB_IRQn);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USB_MspDeInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USB_MspDeInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setup Stage callback
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Data Out Stage callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Data In Stage callback..
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SOF callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
|
||||||
|
|
||||||
|
/*Set USB Current Speed*/
|
||||||
|
switch (hpcd->Init.speed)
|
||||||
|
{
|
||||||
|
case PCD_SPEED_FULL:
|
||||||
|
speed = USBD_SPEED_FULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
speed = USBD_SPEED_FULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed);
|
||||||
|
|
||||||
|
/*Reset Device*/
|
||||||
|
USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Suspend callback.
|
||||||
|
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
/* Inform USB library that core enters in suspend Mode */
|
||||||
|
USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
/*Enter in STOP mode */
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
if (hpcd->Init.low_power_enable)
|
||||||
|
{
|
||||||
|
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */
|
||||||
|
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
|
||||||
|
}
|
||||||
|
/* USER CODE END 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resume callback.
|
||||||
|
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 3 */
|
||||||
|
if (hpcd->Init.low_power_enable)
|
||||||
|
{
|
||||||
|
/* Reset SLEEPDEEP bit of Cortex System Control Register */
|
||||||
|
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
|
||||||
|
SystemClockConfig_Resume();
|
||||||
|
}
|
||||||
|
/* USER CODE END 3 */
|
||||||
|
USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISOOUTIncomplete callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISOINIncomplete callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param epnum: Endpoint Number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
||||||
|
{
|
||||||
|
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ConnectCallback callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnect callback.
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
|
||||||
|
{
|
||||||
|
USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
LL Driver Interface (USB Device Library --> PCD)
|
||||||
|
*******************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Initializes the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
/* Init USB_IP */
|
||||||
|
/* Link The driver to the stack */
|
||||||
|
hpcd_USB_FS.pData = pdev;
|
||||||
|
pdev->pData = &hpcd_USB_FS;
|
||||||
|
|
||||||
|
hpcd_USB_FS.Instance = USB;
|
||||||
|
hpcd_USB_FS.Init.dev_endpoints = 8;
|
||||||
|
hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
|
||||||
|
hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_64;
|
||||||
|
hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
|
||||||
|
hpcd_USB_FS.Init.low_power_enable = DISABLE;
|
||||||
|
hpcd_USB_FS.Init.lpm_enable = DISABLE;
|
||||||
|
hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
|
||||||
|
if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0);
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110);
|
||||||
|
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-Initializes the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_DeInit((PCD_HandleTypeDef*)pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_Start((PCD_HandleTypeDef*)pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stops the Low Level portion of the Device driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
HAL_PCD_Stop((PCD_HandleTypeDef*) pdev->pData);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opens an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param ep_type: Endpoint Type
|
||||||
|
* @param ep_mps: Endpoint Max Packet Size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t ep_type,
|
||||||
|
uint16_t ep_mps)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Open((PCD_HandleTypeDef*) pdev->pData,
|
||||||
|
ep_addr,
|
||||||
|
ep_mps,
|
||||||
|
ep_type);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Close((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flushes an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Flush((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_SetStall((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_ClrStall((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns Stall condition.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval Stall (1: Yes, 0: No)
|
||||||
|
*/
|
||||||
|
uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData;
|
||||||
|
|
||||||
|
if((ep_addr & 0x80) == 0x80)
|
||||||
|
{
|
||||||
|
return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Assigns a USB address to the device.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr)
|
||||||
|
{
|
||||||
|
HAL_PCD_SetAddress((PCD_HandleTypeDef*) pdev->pData, dev_addr);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Transmits data over an endpoint.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param pbuf: Pointer to data to be sent
|
||||||
|
* @param size: Data size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t size)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Transmit((PCD_HandleTypeDef*) pdev->pData, ep_addr, pbuf, size);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prepares an endpoint for reception.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @param pbuf: Pointer to data to be received
|
||||||
|
* @param size: Data size
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t size)
|
||||||
|
{
|
||||||
|
HAL_PCD_EP_Receive((PCD_HandleTypeDef*) pdev->pData, ep_addr, pbuf, size);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the last transfered packet size.
|
||||||
|
* @param pdev: Device handle
|
||||||
|
* @param ep_addr: Endpoint Number
|
||||||
|
* @retval Recived Data Size
|
||||||
|
*/
|
||||||
|
uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delays routine for the USB Device Library.
|
||||||
|
* @param Delay: Delay in ms
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void USBD_LL_Delay (uint32_t Delay)
|
||||||
|
{
|
||||||
|
HAL_Delay(Delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief static single allocation.
|
||||||
|
* @param size: size of allocated memory
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void *USBD_static_malloc(uint32_t size)
|
||||||
|
{
|
||||||
|
static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dummy memory free
|
||||||
|
* @param *p pointer to allocated memory address
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void USBD_static_free(void *p)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 5 */
|
||||||
|
/**
|
||||||
|
* @brief Configures system clock after wake-up from USB Resume CallBack:
|
||||||
|
* enable HSI, PLL and select PLL as system clock source.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void SystemClockConfig_Resume(void)
|
||||||
|
{
|
||||||
|
SystemClock_Config();
|
||||||
|
}
|
||||||
|
/* USER CODE END 5 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Software Device Connection
|
||||||
|
* @param hpcd: PCD handle
|
||||||
|
* @param state: connection state (0 : disconnected / 1: connected)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 6 */
|
||||||
|
if (state == 1)
|
||||||
|
{
|
||||||
|
/* Configure Low Connection State */
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Configure High Connection State */
|
||||||
|
|
||||||
|
}
|
||||||
|
/* USER CODE END 6 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,565 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_core.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief This file provides all the USBD core functions.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_core.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE
|
||||||
|
* @brief usbd core module
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Private_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Private_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Private_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Private_FunctionPrototypes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Private_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_Init
|
||||||
|
* Initializes the device stack and load the class driver
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param pdesc: Descriptor structure address
|
||||||
|
* @param id: Low level core index
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id)
|
||||||
|
{
|
||||||
|
/* Check whether the USB Host handle is valid */
|
||||||
|
if(pdev == NULL)
|
||||||
|
{
|
||||||
|
USBD_ErrLog("Invalid Device handle");
|
||||||
|
return USBD_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlink previous class*/
|
||||||
|
if(pdev->pClass != NULL)
|
||||||
|
{
|
||||||
|
pdev->pClass = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign USBD Descriptors */
|
||||||
|
if(pdesc != NULL)
|
||||||
|
{
|
||||||
|
pdev->pDesc = pdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Device initial State */
|
||||||
|
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||||
|
pdev->id = id;
|
||||||
|
/* Initialize low level driver */
|
||||||
|
USBD_LL_Init(pdev);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_DeInit
|
||||||
|
* Re-Initialize th device library
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status: status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
/* Set Default State */
|
||||||
|
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||||
|
|
||||||
|
/* Free Class Resources */
|
||||||
|
pdev->pClass->DeInit(pdev, pdev->dev_config);
|
||||||
|
|
||||||
|
/* Stop the low level driver */
|
||||||
|
USBD_LL_Stop(pdev);
|
||||||
|
|
||||||
|
/* Initialize low level driver */
|
||||||
|
USBD_LL_DeInit(pdev);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_RegisterClass
|
||||||
|
* Link class driver to Device Core.
|
||||||
|
* @param pDevice : Device Handle
|
||||||
|
* @param pclass: Class handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
|
||||||
|
{
|
||||||
|
USBD_StatusTypeDef status = USBD_OK;
|
||||||
|
if(pclass != 0)
|
||||||
|
{
|
||||||
|
/* link the class to the USB Device handle */
|
||||||
|
pdev->pClass = pclass;
|
||||||
|
status = USBD_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_ErrLog("Invalid Class handle");
|
||||||
|
status = USBD_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_Start
|
||||||
|
* Start the USB Device Core.
|
||||||
|
* @param pdev: Device Handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Start the low level driver */
|
||||||
|
USBD_LL_Start(pdev);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_Stop
|
||||||
|
* Stop the USB Device Core.
|
||||||
|
* @param pdev: Device Handle
|
||||||
|
* @retval USBD Status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
/* Free Class Resources */
|
||||||
|
pdev->pClass->DeInit(pdev, pdev->dev_config);
|
||||||
|
|
||||||
|
/* Stop the low level driver */
|
||||||
|
USBD_LL_Stop(pdev);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_RunTestMode
|
||||||
|
* Launch test mode process
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_SetClassConfig
|
||||||
|
* Configure device and start the interface
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param cfgidx: configuration index
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||||
|
{
|
||||||
|
USBD_StatusTypeDef ret = USBD_FAIL;
|
||||||
|
|
||||||
|
if(pdev->pClass != NULL)
|
||||||
|
{
|
||||||
|
/* Set configuration and Start the Class*/
|
||||||
|
if(pdev->pClass->Init(pdev, cfgidx) == 0)
|
||||||
|
{
|
||||||
|
ret = USBD_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_ClrClassConfig
|
||||||
|
* Clear current configuration
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param cfgidx: configuration index
|
||||||
|
* @retval status: USBD_StatusTypeDef
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||||
|
{
|
||||||
|
/* Clear configuration and De-initialize the Class process*/
|
||||||
|
pdev->pClass->DeInit(pdev, cfgidx);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_SetupStage
|
||||||
|
* Handle the setup stage
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
|
||||||
|
{
|
||||||
|
|
||||||
|
USBD_ParseSetupRequest(&pdev->request, psetup);
|
||||||
|
|
||||||
|
pdev->ep0_state = USBD_EP0_SETUP;
|
||||||
|
pdev->ep0_data_len = pdev->request.wLength;
|
||||||
|
|
||||||
|
switch (pdev->request.bmRequest & 0x1F)
|
||||||
|
{
|
||||||
|
case USB_REQ_RECIPIENT_DEVICE:
|
||||||
|
USBD_StdDevReq (pdev, &pdev->request);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_RECIPIENT_INTERFACE:
|
||||||
|
USBD_StdItfReq(pdev, &pdev->request);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_RECIPIENT_ENDPOINT:
|
||||||
|
USBD_StdEPReq(pdev, &pdev->request);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_DataOutStage
|
||||||
|
* Handle data OUT stage
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param epnum: endpoint index
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata)
|
||||||
|
{
|
||||||
|
USBD_EndpointTypeDef *pep;
|
||||||
|
|
||||||
|
if(epnum == 0)
|
||||||
|
{
|
||||||
|
pep = &pdev->ep_out[0];
|
||||||
|
|
||||||
|
if ( pdev->ep0_state == USBD_EP0_DATA_OUT)
|
||||||
|
{
|
||||||
|
if(pep->rem_length > pep->maxpacket)
|
||||||
|
{
|
||||||
|
pep->rem_length -= pep->maxpacket;
|
||||||
|
|
||||||
|
USBD_CtlContinueRx (pdev,
|
||||||
|
pdata,
|
||||||
|
MIN(pep->rem_length ,pep->maxpacket));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((pdev->pClass->EP0_RxReady != NULL)&&
|
||||||
|
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||||
|
{
|
||||||
|
pdev->pClass->EP0_RxReady(pdev);
|
||||||
|
}
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((pdev->pClass->DataOut != NULL)&&
|
||||||
|
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||||
|
{
|
||||||
|
pdev->pClass->DataOut(pdev, epnum);
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_DataInStage
|
||||||
|
* Handle data in stage
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param epnum: endpoint index
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uint8_t *pdata)
|
||||||
|
{
|
||||||
|
USBD_EndpointTypeDef *pep;
|
||||||
|
|
||||||
|
if(epnum == 0)
|
||||||
|
{
|
||||||
|
pep = &pdev->ep_in[0];
|
||||||
|
|
||||||
|
if ( pdev->ep0_state == USBD_EP0_DATA_IN)
|
||||||
|
{
|
||||||
|
if(pep->rem_length > pep->maxpacket)
|
||||||
|
{
|
||||||
|
pep->rem_length -= pep->maxpacket;
|
||||||
|
|
||||||
|
USBD_CtlContinueSendData (pdev,
|
||||||
|
pdata,
|
||||||
|
pep->rem_length);
|
||||||
|
|
||||||
|
/* Prepare endpoint for premature end of transfer */
|
||||||
|
USBD_LL_PrepareReceive (pdev,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* last packet is MPS multiple, so send ZLP packet */
|
||||||
|
if((pep->total_length % pep->maxpacket == 0) &&
|
||||||
|
(pep->total_length >= pep->maxpacket) &&
|
||||||
|
(pep->total_length < pdev->ep0_data_len ))
|
||||||
|
{
|
||||||
|
|
||||||
|
USBD_CtlContinueSendData(pdev , NULL, 0);
|
||||||
|
pdev->ep0_data_len = 0;
|
||||||
|
|
||||||
|
/* Prepare endpoint for premature end of transfer */
|
||||||
|
USBD_LL_PrepareReceive (pdev,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((pdev->pClass->EP0_TxSent != NULL)&&
|
||||||
|
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||||
|
{
|
||||||
|
pdev->pClass->EP0_TxSent(pdev);
|
||||||
|
}
|
||||||
|
USBD_CtlReceiveStatus(pdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pdev->dev_test_mode == 1)
|
||||||
|
{
|
||||||
|
USBD_RunTestMode(pdev);
|
||||||
|
pdev->dev_test_mode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((pdev->pClass->DataIn != NULL)&&
|
||||||
|
(pdev->dev_state == USBD_STATE_CONFIGURED))
|
||||||
|
{
|
||||||
|
pdev->pClass->DataIn(pdev, epnum);
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_LL_Reset
|
||||||
|
* Handle Reset event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
/* Open EP0 OUT */
|
||||||
|
USBD_LL_OpenEP(pdev,
|
||||||
|
0x00,
|
||||||
|
USBD_EP_TYPE_CTRL,
|
||||||
|
USB_MAX_EP0_SIZE);
|
||||||
|
|
||||||
|
pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
|
||||||
|
|
||||||
|
/* Open EP0 IN */
|
||||||
|
USBD_LL_OpenEP(pdev,
|
||||||
|
0x80,
|
||||||
|
USBD_EP_TYPE_CTRL,
|
||||||
|
USB_MAX_EP0_SIZE);
|
||||||
|
|
||||||
|
pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
|
||||||
|
/* Upon Reset call user call back */
|
||||||
|
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||||
|
|
||||||
|
if (pdev->pClassData)
|
||||||
|
pdev->pClass->DeInit(pdev, pdev->dev_config);
|
||||||
|
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_LL_Reset
|
||||||
|
* Handle Reset event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed)
|
||||||
|
{
|
||||||
|
pdev->dev_speed = speed;
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_Suspend
|
||||||
|
* Handle Suspend event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
pdev->dev_old_state = pdev->dev_state;
|
||||||
|
pdev->dev_state = USBD_STATE_SUSPENDED;
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_Resume
|
||||||
|
* Handle Resume event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
pdev->dev_state = pdev->dev_old_state;
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_SOF
|
||||||
|
* Handle SOF event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
if(pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||||
|
{
|
||||||
|
if(pdev->pClass->SOF != NULL)
|
||||||
|
{
|
||||||
|
pdev->pClass->SOF(pdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_IsoINIncomplete
|
||||||
|
* Handle iso in incomplete event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||||
|
{
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_IsoOUTIncomplete
|
||||||
|
* Handle iso out incomplete event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||||
|
{
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_DevConnected
|
||||||
|
* Handle device connection event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_DevDisconnected
|
||||||
|
* Handle device disconnection event
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
/* Free Class Resources */
|
||||||
|
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||||
|
pdev->pClass->DeInit(pdev, pdev->dev_config);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_core.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief Header file for usbd_core.c file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USBD_CORE_H
|
||||||
|
#define __USBD_CORE_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_conf.h"
|
||||||
|
#include "usbd_def.h"
|
||||||
|
#include "usbd_ioreq.h"
|
||||||
|
#include "usbd_ctlreq.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE
|
||||||
|
* @brief This file is the Header file for usbd_core.c file
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Exported_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Exported_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define USBD_SOF USBD_LL_SOF
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_CORE_Exported_FunctionsPrototype
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id);
|
||||||
|
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||||
|
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup);
|
||||||
|
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata);
|
||||||
|
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed);
|
||||||
|
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||||
|
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev);
|
||||||
|
|
||||||
|
/* USBD Low Level Driver */
|
||||||
|
USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev);
|
||||||
|
USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t ep_type,
|
||||||
|
uint16_t ep_mps);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||||
|
USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||||
|
USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||||
|
USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||||
|
uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||||
|
USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr);
|
||||||
|
USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t size);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t ep_addr,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t size);
|
||||||
|
|
||||||
|
uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr);
|
||||||
|
void USBD_LL_Delay (uint32_t Delay);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __USBD_CORE_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,782 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_req.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief This file provides the standard USB requests following chapter 9.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_ctlreq.h"
|
||||||
|
#include "usbd_ioreq.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ
|
||||||
|
* @brief USB standard requests module
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Private_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Private_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Private_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Private_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Private_FunctionPrototypes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
static void USBD_SetAddress(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
static void USBD_SetConfig(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
static void USBD_GetConfig(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
static void USBD_GetStatus(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
static void USBD_SetFeature(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
static uint8_t USBD_GetLen(uint8_t *buf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_StdDevReq
|
||||||
|
* Handle standard usb device requests
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
USBD_StatusTypeDef ret = USBD_OK;
|
||||||
|
|
||||||
|
switch (req->bRequest)
|
||||||
|
{
|
||||||
|
case USB_REQ_GET_DESCRIPTOR:
|
||||||
|
|
||||||
|
USBD_GetDescriptor (pdev, req) ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_SET_ADDRESS:
|
||||||
|
USBD_SetAddress(pdev, req);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_SET_CONFIGURATION:
|
||||||
|
USBD_SetConfig (pdev , req);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_GET_CONFIGURATION:
|
||||||
|
USBD_GetConfig (pdev , req);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_GET_STATUS:
|
||||||
|
USBD_GetStatus (pdev , req);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case USB_REQ_SET_FEATURE:
|
||||||
|
USBD_SetFeature (pdev , req);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_CLEAR_FEATURE:
|
||||||
|
USBD_ClrFeature (pdev , req);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_StdItfReq
|
||||||
|
* Handle standard usb interface requests
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
USBD_StatusTypeDef ret = USBD_OK;
|
||||||
|
|
||||||
|
switch (pdev->dev_state)
|
||||||
|
{
|
||||||
|
case USBD_STATE_CONFIGURED:
|
||||||
|
|
||||||
|
if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES)
|
||||||
|
{
|
||||||
|
pdev->pClass->Setup (pdev, req);
|
||||||
|
|
||||||
|
if((req->wLength == 0)&& (ret == USBD_OK))
|
||||||
|
{
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_StdEPReq
|
||||||
|
* Handle standard usb endpoint requests
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t ep_addr;
|
||||||
|
USBD_StatusTypeDef ret = USBD_OK;
|
||||||
|
USBD_EndpointTypeDef *pep;
|
||||||
|
ep_addr = LOBYTE(req->wIndex);
|
||||||
|
|
||||||
|
/* Check if it is a class request */
|
||||||
|
if ((req->bmRequest & 0x60) == 0x20)
|
||||||
|
{
|
||||||
|
pdev->pClass->Setup (pdev, req);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (req->bRequest)
|
||||||
|
{
|
||||||
|
|
||||||
|
case USB_REQ_SET_FEATURE :
|
||||||
|
|
||||||
|
switch (pdev->dev_state)
|
||||||
|
{
|
||||||
|
case USBD_STATE_ADDRESSED:
|
||||||
|
if ((ep_addr != 0x00) && (ep_addr != 0x80))
|
||||||
|
{
|
||||||
|
USBD_LL_StallEP(pdev , ep_addr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_STATE_CONFIGURED:
|
||||||
|
if (req->wValue == USB_FEATURE_EP_HALT)
|
||||||
|
{
|
||||||
|
if ((ep_addr != 0x00) && (ep_addr != 0x80))
|
||||||
|
{
|
||||||
|
USBD_LL_StallEP(pdev , ep_addr);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pdev->pClass->Setup (pdev, req);
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_CLEAR_FEATURE :
|
||||||
|
|
||||||
|
switch (pdev->dev_state)
|
||||||
|
{
|
||||||
|
case USBD_STATE_ADDRESSED:
|
||||||
|
if ((ep_addr != 0x00) && (ep_addr != 0x80))
|
||||||
|
{
|
||||||
|
USBD_LL_StallEP(pdev , ep_addr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_STATE_CONFIGURED:
|
||||||
|
if (req->wValue == USB_FEATURE_EP_HALT)
|
||||||
|
{
|
||||||
|
if ((ep_addr & 0x7F) != 0x00)
|
||||||
|
{
|
||||||
|
USBD_LL_ClearStallEP(pdev , ep_addr);
|
||||||
|
pdev->pClass->Setup (pdev, req);
|
||||||
|
}
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_REQ_GET_STATUS:
|
||||||
|
switch (pdev->dev_state)
|
||||||
|
{
|
||||||
|
case USBD_STATE_ADDRESSED:
|
||||||
|
if ((ep_addr & 0x7F) != 0x00)
|
||||||
|
{
|
||||||
|
USBD_LL_StallEP(pdev , ep_addr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_STATE_CONFIGURED:
|
||||||
|
pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\
|
||||||
|
&pdev->ep_out[ep_addr & 0x7F];
|
||||||
|
if(USBD_LL_IsStallEP(pdev, ep_addr))
|
||||||
|
{
|
||||||
|
pep->status = 0x0001;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pep->status = 0x0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
USBD_CtlSendData (pdev,
|
||||||
|
(uint8_t *)&pep->status,
|
||||||
|
2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief USBD_GetDescriptor
|
||||||
|
* Handle Get Descriptor requests
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
uint16_t len;
|
||||||
|
uint8_t *pbuf;
|
||||||
|
|
||||||
|
|
||||||
|
switch (req->wValue >> 8)
|
||||||
|
{
|
||||||
|
#if (USBD_LPM_ENABLED == 1)
|
||||||
|
case USB_DESC_TYPE_BOS:
|
||||||
|
pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case USB_DESC_TYPE_DEVICE:
|
||||||
|
pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_DESC_TYPE_CONFIGURATION:
|
||||||
|
if(pdev->dev_speed == USBD_SPEED_HIGH )
|
||||||
|
{
|
||||||
|
pbuf = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len);
|
||||||
|
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len);
|
||||||
|
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USB_DESC_TYPE_STRING:
|
||||||
|
switch ((uint8_t)(req->wValue))
|
||||||
|
{
|
||||||
|
case USBD_IDX_LANGID_STR:
|
||||||
|
pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_IDX_MFC_STR:
|
||||||
|
pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_IDX_PRODUCT_STR:
|
||||||
|
pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_IDX_SERIAL_STR:
|
||||||
|
pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_IDX_CONFIG_STR:
|
||||||
|
pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_IDX_INTERFACE_STR:
|
||||||
|
pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
#if (USBD_SUPPORT_USER_STRING == 1)
|
||||||
|
pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len);
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case USB_DESC_TYPE_DEVICE_QUALIFIER:
|
||||||
|
|
||||||
|
if(pdev->dev_speed == USBD_SPEED_HIGH )
|
||||||
|
{
|
||||||
|
pbuf = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
|
||||||
|
if(pdev->dev_speed == USBD_SPEED_HIGH )
|
||||||
|
{
|
||||||
|
pbuf = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
|
||||||
|
pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((len != 0)&& (req->wLength != 0))
|
||||||
|
{
|
||||||
|
|
||||||
|
len = MIN(len , req->wLength);
|
||||||
|
|
||||||
|
USBD_CtlSendData (pdev,
|
||||||
|
pbuf,
|
||||||
|
len);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_SetAddress
|
||||||
|
* Set device address
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static void USBD_SetAddress(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
uint8_t dev_addr;
|
||||||
|
|
||||||
|
if ((req->wIndex == 0) && (req->wLength == 0))
|
||||||
|
{
|
||||||
|
dev_addr = (uint8_t)(req->wValue) & 0x7F;
|
||||||
|
|
||||||
|
if (pdev->dev_state == USBD_STATE_CONFIGURED)
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdev->dev_address = dev_addr;
|
||||||
|
USBD_LL_SetUSBAddress(pdev, dev_addr);
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
|
||||||
|
if (dev_addr != 0)
|
||||||
|
{
|
||||||
|
pdev->dev_state = USBD_STATE_ADDRESSED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdev->dev_state = USBD_STATE_DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_SetConfig
|
||||||
|
* Handle Set device configuration request
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static void USBD_SetConfig(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
|
||||||
|
static uint8_t cfgidx;
|
||||||
|
|
||||||
|
cfgidx = (uint8_t)(req->wValue);
|
||||||
|
|
||||||
|
if (cfgidx > USBD_MAX_NUM_CONFIGURATION )
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (pdev->dev_state)
|
||||||
|
{
|
||||||
|
case USBD_STATE_ADDRESSED:
|
||||||
|
if (cfgidx)
|
||||||
|
{
|
||||||
|
pdev->dev_config = cfgidx;
|
||||||
|
pdev->dev_state = USBD_STATE_CONFIGURED;
|
||||||
|
if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_STATE_CONFIGURED:
|
||||||
|
if (cfgidx == 0)
|
||||||
|
{
|
||||||
|
pdev->dev_state = USBD_STATE_ADDRESSED;
|
||||||
|
pdev->dev_config = cfgidx;
|
||||||
|
USBD_ClrClassConfig(pdev , cfgidx);
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (cfgidx != pdev->dev_config)
|
||||||
|
{
|
||||||
|
/* Clear old configuration */
|
||||||
|
USBD_ClrClassConfig(pdev , pdev->dev_config);
|
||||||
|
|
||||||
|
/* set new configuration */
|
||||||
|
pdev->dev_config = cfgidx;
|
||||||
|
if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_GetConfig
|
||||||
|
* Handle Get device configuration request
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static void USBD_GetConfig(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (req->wLength != 1)
|
||||||
|
{
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (pdev->dev_state )
|
||||||
|
{
|
||||||
|
case USBD_STATE_ADDRESSED:
|
||||||
|
pdev->dev_default_config = 0;
|
||||||
|
USBD_CtlSendData (pdev,
|
||||||
|
(uint8_t *)&pdev->dev_default_config,
|
||||||
|
1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case USBD_STATE_CONFIGURED:
|
||||||
|
|
||||||
|
USBD_CtlSendData (pdev,
|
||||||
|
(uint8_t *)&pdev->dev_config,
|
||||||
|
1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_GetStatus
|
||||||
|
* Handle Get Status request
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static void USBD_GetStatus(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
switch (pdev->dev_state)
|
||||||
|
{
|
||||||
|
case USBD_STATE_ADDRESSED:
|
||||||
|
case USBD_STATE_CONFIGURED:
|
||||||
|
|
||||||
|
#if ( USBD_SELF_POWERED == 1)
|
||||||
|
pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
|
||||||
|
#else
|
||||||
|
pdev->dev_config_status = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pdev->dev_remote_wakeup)
|
||||||
|
{
|
||||||
|
pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
USBD_CtlSendData (pdev,
|
||||||
|
(uint8_t *)& pdev->dev_config_status,
|
||||||
|
2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_SetFeature
|
||||||
|
* Handle Set device feature request
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static void USBD_SetFeature(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
|
||||||
|
{
|
||||||
|
pdev->dev_remote_wakeup = 1;
|
||||||
|
pdev->pClass->Setup (pdev, req);
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_ClrFeature
|
||||||
|
* Handle clear device feature request
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
switch (pdev->dev_state)
|
||||||
|
{
|
||||||
|
case USBD_STATE_ADDRESSED:
|
||||||
|
case USBD_STATE_CONFIGURED:
|
||||||
|
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
|
||||||
|
{
|
||||||
|
pdev->dev_remote_wakeup = 0;
|
||||||
|
pdev->pClass->Setup (pdev, req);
|
||||||
|
USBD_CtlSendStatus(pdev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
USBD_CtlError(pdev , req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_ParseSetupRequest
|
||||||
|
* Copy buffer into setup structure
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
|
||||||
|
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
|
||||||
|
{
|
||||||
|
req->bmRequest = *(uint8_t *) (pdata);
|
||||||
|
req->bRequest = *(uint8_t *) (pdata + 1);
|
||||||
|
req->wValue = SWAPBYTE (pdata + 2);
|
||||||
|
req->wIndex = SWAPBYTE (pdata + 4);
|
||||||
|
req->wLength = SWAPBYTE (pdata + 6);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CtlError
|
||||||
|
* Handle USB low level Error
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param req: usb request
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
|
||||||
|
void USBD_CtlError( USBD_HandleTypeDef *pdev ,
|
||||||
|
USBD_SetupReqTypedef *req)
|
||||||
|
{
|
||||||
|
USBD_LL_StallEP(pdev , 0x80);
|
||||||
|
USBD_LL_StallEP(pdev , 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_GetString
|
||||||
|
* Convert Ascii string into unicode one
|
||||||
|
* @param desc : descriptor buffer
|
||||||
|
* @param unicode : Formatted string buffer (unicode)
|
||||||
|
* @param len : descriptor length
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
|
||||||
|
{
|
||||||
|
uint8_t idx = 0;
|
||||||
|
|
||||||
|
if (desc != NULL)
|
||||||
|
{
|
||||||
|
*len = USBD_GetLen(desc) * 2 + 2;
|
||||||
|
unicode[idx++] = *len;
|
||||||
|
unicode[idx++] = USB_DESC_TYPE_STRING;
|
||||||
|
|
||||||
|
while (*desc != '\0')
|
||||||
|
{
|
||||||
|
unicode[idx++] = *desc++;
|
||||||
|
unicode[idx++] = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_GetLen
|
||||||
|
* return the string length
|
||||||
|
* @param buf : pointer to the ascii string buffer
|
||||||
|
* @retval string length
|
||||||
|
*/
|
||||||
|
static uint8_t USBD_GetLen(uint8_t *buf)
|
||||||
|
{
|
||||||
|
uint8_t len = 0;
|
||||||
|
|
||||||
|
while (*buf != '\0')
|
||||||
|
{
|
||||||
|
len++;
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_req.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief Header file for the usbd_req.c file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USB_REQUEST_H
|
||||||
|
#define __USB_REQUEST_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_def.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ
|
||||||
|
* @brief header file for the usbd_req.c file
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Exported_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Exported_Types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_REQ_Exported_FunctionsPrototype
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||||
|
USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||||
|
USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
|
||||||
|
void USBD_CtlError (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
|
||||||
|
|
||||||
|
void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata);
|
||||||
|
|
||||||
|
void USBD_GetString (uint8_t *desc, uint8_t *unicode, uint16_t *len);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __USB_REQUEST_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,330 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_def.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief General defines for the usb device library
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USBD_DEF_H
|
||||||
|
#define __USBD_DEF_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_conf.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USBD_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USB_DEF
|
||||||
|
* @brief general defines for the usb device library file
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USB_DEF_Exported_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define USB_LEN_DEV_QUALIFIER_DESC 0x0A
|
||||||
|
#define USB_LEN_DEV_DESC 0x12
|
||||||
|
#define USB_LEN_CFG_DESC 0x09
|
||||||
|
#define USB_LEN_IF_DESC 0x09
|
||||||
|
#define USB_LEN_EP_DESC 0x07
|
||||||
|
#define USB_LEN_OTG_DESC 0x03
|
||||||
|
#define USB_LEN_LANGID_STR_DESC 0x04
|
||||||
|
#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09
|
||||||
|
|
||||||
|
#define USBD_IDX_LANGID_STR 0x00
|
||||||
|
#define USBD_IDX_MFC_STR 0x01
|
||||||
|
#define USBD_IDX_PRODUCT_STR 0x02
|
||||||
|
#define USBD_IDX_SERIAL_STR 0x03
|
||||||
|
#define USBD_IDX_CONFIG_STR 0x04
|
||||||
|
#define USBD_IDX_INTERFACE_STR 0x05
|
||||||
|
|
||||||
|
#define USB_REQ_TYPE_STANDARD 0x00
|
||||||
|
#define USB_REQ_TYPE_CLASS 0x20
|
||||||
|
#define USB_REQ_TYPE_VENDOR 0x40
|
||||||
|
#define USB_REQ_TYPE_MASK 0x60
|
||||||
|
|
||||||
|
#define USB_REQ_RECIPIENT_DEVICE 0x00
|
||||||
|
#define USB_REQ_RECIPIENT_INTERFACE 0x01
|
||||||
|
#define USB_REQ_RECIPIENT_ENDPOINT 0x02
|
||||||
|
#define USB_REQ_RECIPIENT_MASK 0x03
|
||||||
|
|
||||||
|
#define USB_REQ_GET_STATUS 0x00
|
||||||
|
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||||
|
#define USB_REQ_SET_FEATURE 0x03
|
||||||
|
#define USB_REQ_SET_ADDRESS 0x05
|
||||||
|
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||||
|
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||||
|
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||||
|
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||||
|
#define USB_REQ_GET_INTERFACE 0x0A
|
||||||
|
#define USB_REQ_SET_INTERFACE 0x0B
|
||||||
|
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||||
|
|
||||||
|
#define USB_DESC_TYPE_DEVICE 1
|
||||||
|
#define USB_DESC_TYPE_CONFIGURATION 2
|
||||||
|
#define USB_DESC_TYPE_STRING 3
|
||||||
|
#define USB_DESC_TYPE_INTERFACE 4
|
||||||
|
#define USB_DESC_TYPE_ENDPOINT 5
|
||||||
|
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
|
||||||
|
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
|
||||||
|
#define USB_DESC_TYPE_BOS 0x0F
|
||||||
|
|
||||||
|
#define USB_CONFIG_REMOTE_WAKEUP 2
|
||||||
|
#define USB_CONFIG_SELF_POWERED 1
|
||||||
|
|
||||||
|
#define USB_FEATURE_EP_HALT 0
|
||||||
|
#define USB_FEATURE_REMOTE_WAKEUP 1
|
||||||
|
#define USB_FEATURE_TEST_MODE 2
|
||||||
|
|
||||||
|
#define USB_DEVICE_CAPABITY_TYPE 0x10
|
||||||
|
|
||||||
|
#define USB_HS_MAX_PACKET_SIZE 512
|
||||||
|
#define USB_FS_MAX_PACKET_SIZE 64
|
||||||
|
#define USB_MAX_EP0_SIZE 64
|
||||||
|
|
||||||
|
/* Device Status */
|
||||||
|
#define USBD_STATE_DEFAULT 1
|
||||||
|
#define USBD_STATE_ADDRESSED 2
|
||||||
|
#define USBD_STATE_CONFIGURED 3
|
||||||
|
#define USBD_STATE_SUSPENDED 4
|
||||||
|
|
||||||
|
|
||||||
|
/* EP0 State */
|
||||||
|
#define USBD_EP0_IDLE 0
|
||||||
|
#define USBD_EP0_SETUP 1
|
||||||
|
#define USBD_EP0_DATA_IN 2
|
||||||
|
#define USBD_EP0_DATA_OUT 3
|
||||||
|
#define USBD_EP0_STATUS_IN 4
|
||||||
|
#define USBD_EP0_STATUS_OUT 5
|
||||||
|
#define USBD_EP0_STALL 6
|
||||||
|
|
||||||
|
#define USBD_EP_TYPE_CTRL 0
|
||||||
|
#define USBD_EP_TYPE_ISOC 1
|
||||||
|
#define USBD_EP_TYPE_BULK 2
|
||||||
|
#define USBD_EP_TYPE_INTR 3
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_DEF_Exported_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct usb_setup_req
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t bmRequest;
|
||||||
|
uint8_t bRequest;
|
||||||
|
uint16_t wValue;
|
||||||
|
uint16_t wIndex;
|
||||||
|
uint16_t wLength;
|
||||||
|
}USBD_SetupReqTypedef;
|
||||||
|
|
||||||
|
struct _USBD_HandleTypeDef;
|
||||||
|
|
||||||
|
typedef struct _Device_cb
|
||||||
|
{
|
||||||
|
uint8_t (*Init) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx);
|
||||||
|
uint8_t (*DeInit) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx);
|
||||||
|
/* Control Endpoints*/
|
||||||
|
uint8_t (*Setup) (struct _USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req);
|
||||||
|
uint8_t (*EP0_TxSent) (struct _USBD_HandleTypeDef *pdev );
|
||||||
|
uint8_t (*EP0_RxReady) (struct _USBD_HandleTypeDef *pdev );
|
||||||
|
/* Class Specific Endpoints*/
|
||||||
|
uint8_t (*DataIn) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);
|
||||||
|
uint8_t (*DataOut) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);
|
||||||
|
uint8_t (*SOF) (struct _USBD_HandleTypeDef *pdev);
|
||||||
|
uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);
|
||||||
|
uint8_t (*IsoOUTIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);
|
||||||
|
|
||||||
|
uint8_t *(*GetHSConfigDescriptor)(uint16_t *length);
|
||||||
|
uint8_t *(*GetFSConfigDescriptor)(uint16_t *length);
|
||||||
|
uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length);
|
||||||
|
uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length);
|
||||||
|
#if (USBD_SUPPORT_USER_STRING == 1)
|
||||||
|
uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev ,uint8_t index, uint16_t *length);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} USBD_ClassTypeDef;
|
||||||
|
|
||||||
|
/* Following USB Device Speed */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
USBD_SPEED_HIGH = 0,
|
||||||
|
USBD_SPEED_FULL = 1,
|
||||||
|
USBD_SPEED_LOW = 2,
|
||||||
|
}USBD_SpeedTypeDef;
|
||||||
|
|
||||||
|
/* Following USB Device status */
|
||||||
|
typedef enum {
|
||||||
|
USBD_OK = 0,
|
||||||
|
USBD_BUSY,
|
||||||
|
USBD_FAIL,
|
||||||
|
}USBD_StatusTypeDef;
|
||||||
|
|
||||||
|
/* USB Device descriptors structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t *(*GetDeviceDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t *(*GetLangIDStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t *(*GetManufacturerStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t *(*GetProductStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t *(*GetSerialStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t *(*GetConfigurationStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t *(*GetInterfaceStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
#if (USBD_LPM_ENABLED == 1)
|
||||||
|
uint8_t *(*GetBOSDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
#endif
|
||||||
|
} USBD_DescriptorsTypeDef;
|
||||||
|
|
||||||
|
/* USB Device handle structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t total_length;
|
||||||
|
uint32_t rem_length;
|
||||||
|
uint32_t maxpacket;
|
||||||
|
} USBD_EndpointTypeDef;
|
||||||
|
|
||||||
|
/* USB Device handle structure */
|
||||||
|
typedef struct _USBD_HandleTypeDef
|
||||||
|
{
|
||||||
|
uint8_t id;
|
||||||
|
uint32_t dev_config;
|
||||||
|
uint32_t dev_default_config;
|
||||||
|
uint32_t dev_config_status;
|
||||||
|
USBD_SpeedTypeDef dev_speed;
|
||||||
|
USBD_EndpointTypeDef ep_in[15];
|
||||||
|
USBD_EndpointTypeDef ep_out[15];
|
||||||
|
uint32_t ep0_state;
|
||||||
|
uint32_t ep0_data_len;
|
||||||
|
uint8_t dev_state;
|
||||||
|
uint8_t dev_old_state;
|
||||||
|
uint8_t dev_address;
|
||||||
|
uint8_t dev_connection_status;
|
||||||
|
uint8_t dev_test_mode;
|
||||||
|
uint32_t dev_remote_wakeup;
|
||||||
|
|
||||||
|
USBD_SetupReqTypedef request;
|
||||||
|
USBD_DescriptorsTypeDef *pDesc;
|
||||||
|
USBD_ClassTypeDef *pClass;
|
||||||
|
void *pClassData;
|
||||||
|
void *pUserData;
|
||||||
|
void *pData;
|
||||||
|
} USBD_HandleTypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_DEF_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \
|
||||||
|
(((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
|
||||||
|
|
||||||
|
#define LOBYTE(x) ((uint8_t)(x & 0x00FF))
|
||||||
|
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
|
||||||
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __GNUC__ )
|
||||||
|
#ifndef __weak
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
#endif /* __weak */
|
||||||
|
#ifndef __packed
|
||||||
|
#define __packed __attribute__((__packed__))
|
||||||
|
#endif /* __packed */
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* In HS mode and when the DMA is used, all variables and data structures dealing
|
||||||
|
with the DMA during the transaction process should be 4-bytes aligned */
|
||||||
|
|
||||||
|
#if defined (__GNUC__) /* GNU Compiler */
|
||||||
|
#define __ALIGN_END __attribute__ ((aligned (4)))
|
||||||
|
#define __ALIGN_BEGIN
|
||||||
|
#else
|
||||||
|
#define __ALIGN_END
|
||||||
|
#if defined (__CC_ARM) /* ARM Compiler */
|
||||||
|
#define __ALIGN_BEGIN __align(4)
|
||||||
|
#elif defined (__ICCARM__) /* IAR Compiler */
|
||||||
|
#define __ALIGN_BEGIN
|
||||||
|
#elif defined (__TASKING__) /* TASKING Compiler */
|
||||||
|
#define __ALIGN_BEGIN __align(4)
|
||||||
|
#endif /* __CC_ARM */
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DEF_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DEF_Exported_FunctionsPrototype
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __USBD_DEF_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,297 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : usbd_desc.c
|
||||||
|
* @version : v1.0_Cube
|
||||||
|
* @brief : This file implements the USB Device descriptors
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* COPYRIGHT(c) 2016 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_core.h"
|
||||||
|
#include "usbd_desc.h"
|
||||||
|
#include "usbd_conf.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC
|
||||||
|
* @brief USBD descriptors module
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Private_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Private_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define USBD_VID 1155
|
||||||
|
#define USBD_LANGID_STRING 1033
|
||||||
|
#define USBD_MANUFACTURER_STRING "STMicroelectronics"
|
||||||
|
#define USBD_PID_FS 22336
|
||||||
|
#define USBD_PRODUCT_STRING_FS "STM32 Virtual ComPort"
|
||||||
|
#define USBD_SERIALNUMBER_STRING_FS "00000000001A"
|
||||||
|
#define USBD_CONFIGURATION_STRING_FS "CDC Config"
|
||||||
|
#define USBD_INTERFACE_STRING_FS "CDC Interface"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
/* USER CODE END 0*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Private_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Private_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
uint8_t * USBD_FS_DeviceDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t * USBD_FS_LangIDStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t * USBD_FS_ManufacturerStrDescriptor ( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t * USBD_FS_ProductStrDescriptor ( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t * USBD_FS_SerialStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t * USBD_FS_ConfigStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
uint8_t * USBD_FS_InterfaceStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length);
|
||||||
|
|
||||||
|
#ifdef USB_SUPPORT_USER_STRING_DESC
|
||||||
|
uint8_t * USBD_FS_USRStringDesc (USBD_SpeedTypeDef speed, uint8_t idx , uint16_t *length);
|
||||||
|
#endif /* USB_SUPPORT_USER_STRING_DESC */
|
||||||
|
|
||||||
|
USBD_DescriptorsTypeDef FS_Desc =
|
||||||
|
{
|
||||||
|
USBD_FS_DeviceDescriptor,
|
||||||
|
USBD_FS_LangIDStrDescriptor,
|
||||||
|
USBD_FS_ManufacturerStrDescriptor,
|
||||||
|
USBD_FS_ProductStrDescriptor,
|
||||||
|
USBD_FS_SerialStrDescriptor,
|
||||||
|
USBD_FS_ConfigStrDescriptor,
|
||||||
|
USBD_FS_InterfaceStrDescriptor,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||||
|
#pragma data_alignment=4
|
||||||
|
#endif
|
||||||
|
/* USB Standard Device Descriptor */
|
||||||
|
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
|
||||||
|
{
|
||||||
|
0x12, /*bLength */
|
||||||
|
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
|
||||||
|
0x00, /* bcdUSB */
|
||||||
|
0x02,
|
||||||
|
0x02, /*bDeviceClass*/
|
||||||
|
0x02, /*bDeviceSubClass*/
|
||||||
|
0x00, /*bDeviceProtocol*/
|
||||||
|
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
|
||||||
|
LOBYTE(USBD_VID), /*idVendor*/
|
||||||
|
HIBYTE(USBD_VID), /*idVendor*/
|
||||||
|
LOBYTE(USBD_PID_FS), /*idVendor*/
|
||||||
|
HIBYTE(USBD_PID_FS), /*idVendor*/
|
||||||
|
0x00, /*bcdDevice rel. 2.00*/
|
||||||
|
0x02,
|
||||||
|
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
|
||||||
|
USBD_IDX_PRODUCT_STR, /*Index of product string*/
|
||||||
|
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
|
||||||
|
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
|
||||||
|
} ;
|
||||||
|
/* USB_DeviceDescriptor */
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||||
|
#pragma data_alignment=4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* USB Standard Device Descriptor */
|
||||||
|
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END =
|
||||||
|
{
|
||||||
|
USB_LEN_LANGID_STR_DESC,
|
||||||
|
USB_DESC_TYPE_STRING,
|
||||||
|
LOBYTE(USBD_LANGID_STRING),
|
||||||
|
HIBYTE(USBD_LANGID_STRING),
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||||
|
#pragma data_alignment=4
|
||||||
|
#endif
|
||||||
|
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Private_FunctionPrototypes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_FS_DeviceDescriptor
|
||||||
|
* return the device descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer to data length variable
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
uint8_t * USBD_FS_DeviceDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
|
||||||
|
{
|
||||||
|
*length = sizeof(USBD_FS_DeviceDesc);
|
||||||
|
return USBD_FS_DeviceDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_FS_LangIDStrDescriptor
|
||||||
|
* return the LangID string descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer to data length variable
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
uint8_t * USBD_FS_LangIDStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
|
||||||
|
{
|
||||||
|
*length = sizeof(USBD_LangIDDesc);
|
||||||
|
return USBD_LangIDDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_FS_ProductStrDescriptor
|
||||||
|
* return the product string descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer to data length variable
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
uint8_t * USBD_FS_ProductStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
|
||||||
|
{
|
||||||
|
if(speed == 0)
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
|
||||||
|
}
|
||||||
|
return USBD_StrDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_FS_ManufacturerStrDescriptor
|
||||||
|
* return the manufacturer string descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer to data length variable
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
uint8_t * USBD_FS_ManufacturerStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
|
||||||
|
return USBD_StrDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_FS_SerialStrDescriptor
|
||||||
|
* return the serial number string descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer to data length variable
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
uint8_t * USBD_FS_SerialStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
|
||||||
|
{
|
||||||
|
if(speed == USBD_SPEED_HIGH)
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length);
|
||||||
|
}
|
||||||
|
return USBD_StrDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_FS_ConfigStrDescriptor
|
||||||
|
* return the configuration string descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer to data length variable
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
uint8_t * USBD_FS_ConfigStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
|
||||||
|
{
|
||||||
|
if(speed == USBD_SPEED_HIGH)
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length);
|
||||||
|
}
|
||||||
|
return USBD_StrDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_HS_InterfaceStrDescriptor
|
||||||
|
* return the interface string descriptor
|
||||||
|
* @param speed : current device speed
|
||||||
|
* @param length : pointer to data length variable
|
||||||
|
* @retval pointer to descriptor buffer
|
||||||
|
*/
|
||||||
|
uint8_t * USBD_FS_InterfaceStrDescriptor( USBD_SpeedTypeDef speed , uint16_t *length)
|
||||||
|
{
|
||||||
|
if(speed == 0)
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_INTERFACE_STRING_FS, USBD_StrDesc, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
USBD_GetString (USBD_INTERFACE_STRING_FS, USBD_StrDesc, length);
|
||||||
|
}
|
||||||
|
return USBD_StrDesc;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : usbd_desc.h
|
||||||
|
* @version : v1.0_Cube
|
||||||
|
* @brief : Header for usbd_desc file.
|
||||||
|
******************************************************************************
|
||||||
|
* COPYRIGHT(c) 2016 STMicroelectronics
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USBD_DESC__H__
|
||||||
|
#define __USBD_DESC__H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_def.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USB_DESC
|
||||||
|
* @brief general defines for the usb device library file
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USB_DESC_Exported_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Exported_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
extern USBD_DescriptorsTypeDef FS_Desc;
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_DESC_Exported_FunctionsPrototype
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __USBD_DESC_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,236 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_ioreq.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief This file provides the IO requests APIs for control endpoints.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_ioreq.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ
|
||||||
|
* @brief control I/O requests module
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Private_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Private_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Private_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Private_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Private_FunctionPrototypes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CtlSendData
|
||||||
|
* send data on the ctl pipe
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param buff: pointer to data buffer
|
||||||
|
* @param len: length of data to be sent
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t len)
|
||||||
|
{
|
||||||
|
/* Set EP0 State */
|
||||||
|
pdev->ep0_state = USBD_EP0_DATA_IN;
|
||||||
|
pdev->ep_in[0].total_length = len;
|
||||||
|
pdev->ep_in[0].rem_length = len;
|
||||||
|
/* Start the transfer */
|
||||||
|
USBD_LL_Transmit (pdev, 0x00, pbuf, len);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CtlContinueSendData
|
||||||
|
* continue sending data on the ctl pipe
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param buff: pointer to data buffer
|
||||||
|
* @param len: length of data to be sent
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t len)
|
||||||
|
{
|
||||||
|
/* Start the next transfer */
|
||||||
|
USBD_LL_Transmit (pdev, 0x00, pbuf, len);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CtlPrepareRx
|
||||||
|
* receive data on the ctl pipe
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param buff: pointer to data buffer
|
||||||
|
* @param len: length of data to be received
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t len)
|
||||||
|
{
|
||||||
|
/* Set EP0 State */
|
||||||
|
pdev->ep0_state = USBD_EP0_DATA_OUT;
|
||||||
|
pdev->ep_out[0].total_length = len;
|
||||||
|
pdev->ep_out[0].rem_length = len;
|
||||||
|
/* Start the transfer */
|
||||||
|
USBD_LL_PrepareReceive (pdev,
|
||||||
|
0,
|
||||||
|
pbuf,
|
||||||
|
len);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CtlContinueRx
|
||||||
|
* continue receive data on the ctl pipe
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param buff: pointer to data buffer
|
||||||
|
* @param len: length of data to be received
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
USBD_LL_PrepareReceive (pdev,
|
||||||
|
0,
|
||||||
|
pbuf,
|
||||||
|
len);
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief USBD_CtlSendStatus
|
||||||
|
* send zero lzngth packet on the ctl pipe
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Set EP0 State */
|
||||||
|
pdev->ep0_state = USBD_EP0_STATUS_IN;
|
||||||
|
|
||||||
|
/* Start the transfer */
|
||||||
|
USBD_LL_Transmit (pdev, 0x00, NULL, 0);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_CtlReceiveStatus
|
||||||
|
* receive zero lzngth packet on the ctl pipe
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @retval status
|
||||||
|
*/
|
||||||
|
USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev)
|
||||||
|
{
|
||||||
|
/* Set EP0 State */
|
||||||
|
pdev->ep0_state = USBD_EP0_STATUS_OUT;
|
||||||
|
|
||||||
|
/* Start the transfer */
|
||||||
|
USBD_LL_PrepareReceive ( pdev,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
|
||||||
|
return USBD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief USBD_GetRxCount
|
||||||
|
* returns the received data length
|
||||||
|
* @param pdev: device instance
|
||||||
|
* @param ep_addr: endpoint address
|
||||||
|
* @retval Rx Data blength
|
||||||
|
*/
|
||||||
|
uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev , uint8_t ep_addr)
|
||||||
|
{
|
||||||
|
return USBD_LL_GetRxDataSize(pdev, ep_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usbd_ioreq.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.4.2
|
||||||
|
* @date 11-December-2015
|
||||||
|
* @brief Header file for the usbd_ioreq.c file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||||
|
*
|
||||||
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USBD_IOREQ_H
|
||||||
|
#define __USBD_IOREQ_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usbd_def.h"
|
||||||
|
#include "usbd_core.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ
|
||||||
|
* @brief header file for the usbd_ioreq.c file
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Exported_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Exported_Types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Exported_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *buf,
|
||||||
|
uint16_t len);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t len);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t len);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev,
|
||||||
|
uint8_t *pbuf,
|
||||||
|
uint16_t len);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev);
|
||||||
|
|
||||||
|
USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev);
|
||||||
|
|
||||||
|
uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev ,
|
||||||
|
uint8_t epnum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __USBD_IOREQ_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
Loading…
Reference in New Issue