// USB-Gerät: Maus + CDC + WebUSB
#pragma once
#include <stdint.h> // uint32_t
#include <inc/hw_types.h> // uint8_t
#include <inc/hw_memmap.h> // USBA_BASE
namespace usb{
#ifdef __TMS320C28XX__
//const uint32_t INT_USB = INT_USBA;
const uint32_t BASE = USBA_BASE; // USB Define for C28x.
#else
//const uint32_t INT_USB = INT_USB0;
const uint32_t BASE = USB0_BASE; // USB Define for CM.
#endif
struct Regs{//C28-View, nicht CM-View!
uint8_t FADDR;
uint8_t POWER;
uint16_t TXIS,TXISH,RXIS,RXISH;
uint16_t TXIE,TXIEH,RXIE,RXIEH;
uint8_t IS,IE;
uint16_t FRAME,FRAMEH;
};
extern volatile Regs RegsA;
// USB-Request als Byte-struct erspart Alignment-Probleme
struct tRequest{
uint8_t bmRequestType,// Determines the type and direction of the request.
bRequest, // Identifies the specific request being made.
wValueL, wValueH, // Word-sized field that varies according to the request.
wIndexL, wIndexH, // Word-sized field that varies according to the request.
wLengthL, wLengthH; // The number of bytes to transfer if there is a data stage to the request.
uint16_t wRequest() const {return bRequest<<8|bmRequestType;}
uint16_t wValue() const {return wValueH<<8|wValueL;}
uint16_t wIndex() const {return wIndexH<<8|wIndexL;}
uint16_t wLength() const {return wLengthH<<8|wLengthL;}
void limitLength(unsigned&l) const {if (l>wLength()) l=wLength();}
void limitLength(volatile unsigned&l) const {if (l>wLength()) l=wLength();}
operator uint8_t*() {return &bmRequestType;}
};
// Generate two-byte, three-byte, and four-byte value for USB descriptors
#define USB2(v) (v) & 0xff, (v) >> 8
#define USB3(v) USB2((v)&0xFFFF), (v)>> 16
#define USB4(v) USB2((v)&0xFFFF), USB2((v)>>16)
struct tDevice {
virtual ~tDevice() {}
virtual void idle() {}
virtual bool cbGetDescriptor(const tRequest&) {return false;}
virtual bool cbRequestHandler(const tRequest&) {return false;}
virtual void onReset() {devstat &= ~2; config=0;}
virtual void onDisconnect() {onReset();}
virtual void onSOF() {}
uint8_t config; // 0 = unconfigured, 1 = configured
uint8_t devstat; // Bit 0: SelfPower, Bit 1: RemoteWakeupEnabled
// USB-Peripheriefreigabe, Taktung und GPIO müssen vorher eingestellt werden.
// Interrupts und DMA werden nicht benötigt
bool Init();
void Term();
bool SendDataEP0(const uint8_t*,unsigned, const tRequest&);
// synchron, kehrt bei Abarbeitung aller Bytes zurück, ruft idle() wenn zu warten ist
// liefert false nur wenn etwas katastrophales wie USB-Busreset dazwischenfunkt, sonst stets true
void PowerStatusSet(bool selfpower) {if (selfpower) devstat|=1; else devstat&=~1;}
// zyklisch aufzurufen, erspart Interrupts (die mit wichtigeren Dingen beschäftigt sind)
void poll();
private:
void pollEP0();
bool SendDataEP0(const uint8_t*,unsigned);
};
#pragma diag_suppress 2827 // override is C++11
struct tMyDevice:public tDevice{
// Nur für Interface 0 = Maus
bool StateChange(uint8_t ui8Buttons, int8_t i8DeltaX,int8_t i8DeltaY);
private:
bool SendReport(uint8_t *pi8Data, unsigned len); // hier: len <= 64!
uint8_t inrep[3];
virtual bool cbRequestHandler(const tRequest&) override;
virtual bool cbGetDescriptor(const tRequest&rq) override;
};
}
Detected encoding: UTF-8 | 0
|