add cdc usart
This commit is contained in:
parent
b345a72511
commit
07c30fffc8
16 changed files with 620 additions and 0 deletions
89
V203/usb/ch32v203/usart.cpp
Normal file
89
V203/usb/ch32v203/usart.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
#include "system.h"
|
||||
#include "../common/usart.h"
|
||||
static Usart * pInstance = nullptr;
|
||||
|
||||
extern "C" {
|
||||
[[gnu::interrupt]] void USART1_IRQHandler (void);
|
||||
};
|
||||
void USART1_IRQHandler (void) {
|
||||
if (pInstance) pInstance->irq();
|
||||
};
|
||||
|
||||
Usart::Usart(const uint32_t _baud) noexcept : BaseLayer (), tx_ring () {
|
||||
pInstance = this;
|
||||
// 1. Clock Enable
|
||||
RCC.APB2PCENR.modify([](RCC_Type::APB2PCENR_DEF & r) -> auto {
|
||||
r.B.USART1EN = SET;
|
||||
r.B.IOPAEN = SET;
|
||||
//r.B.AFIOEN = SET; // není nutné
|
||||
return r.R;
|
||||
});
|
||||
// 2. GPIO Alternate Config - default TX/PA9, RX/PA10
|
||||
GPIOA.CFGHR.modify([](GPIOA_Type::CFGHR_DEF & r) -> auto {
|
||||
r.B.MODE9 = 1u;
|
||||
r.B.CNF9 = 2u; // or 3u for open drain
|
||||
r.B.MODE10 = 0u;
|
||||
r.B.CNF10 = 1u; // floating input
|
||||
return r.R;
|
||||
});
|
||||
RCC.APB2PRSTR.B.USART1RST = SET;
|
||||
RCC.APB2PRSTR.B.USART1RST = RESET;
|
||||
// 5. USART registry 8.bit bez parity
|
||||
USART1.CTLR1.modify([] (USART1_Type::CTLR1_DEF & r) -> auto {
|
||||
r.B.RE = SET;
|
||||
r.B.TE = SET;
|
||||
r.B.RXNEIE = SET;
|
||||
return r.R;
|
||||
});
|
||||
USART1.CTLR2.modify ([](USART1_Type::CTLR2_DEF & r) -> auto {
|
||||
r.B.STOP = 0u;
|
||||
return r.R;
|
||||
});
|
||||
SetBaud(_baud);
|
||||
// NVIC
|
||||
NVIC.EnableIRQ (USART1_IRQn);
|
||||
USART1.CTLR1.B.UE = SET; // nakonec povolit globálně
|
||||
}
|
||||
void Usart::irq () {
|
||||
volatile USART1_Type::STATR_DEF status (USART1.STATR); // načti status přerušení
|
||||
char rdata, tdata;
|
||||
|
||||
if (status.B.TXE) { // od vysílače
|
||||
if (tx_ring.Read (tdata)) { // pokud máme data
|
||||
USART1.DATAR.B.DR = (uint8_t) tdata; // zapíšeme do výstupu
|
||||
} else { // pokud ne
|
||||
USART1.CTLR1.B.TXEIE = RESET;
|
||||
}
|
||||
}
|
||||
if (status.B.RXNE) { // od přijímače
|
||||
rdata = (USART1.DATAR.B.DR); // načteme data
|
||||
Up (&rdata, 1u); // a pošleme dál
|
||||
}
|
||||
}
|
||||
uint32_t Usart::Down(const char * data, const uint32_t len) {
|
||||
unsigned n = 0u;
|
||||
for (n=0u; n<len; n++) {
|
||||
if (!tx_ring.Write(data[n])) break;
|
||||
}
|
||||
USART1.CTLR1.B.TXEIE = SET; // po povolení přerušení okamžitě přeruší
|
||||
return n;
|
||||
}
|
||||
void Usart::SetBaud (const uint32_t _baud) const {
|
||||
const ONE_BIT b = USART1.CTLR1.B.UE;
|
||||
if (b == SET) USART1.CTLR1.B.UE = RESET;
|
||||
const uint32_t HCLK = SystemCoreClock; // hodiny pro USART zde nejsou děleny
|
||||
const uint32_t tmp = HCLK / _baud; // lze je tedy zapsat přímo
|
||||
USART1.BRR.R = tmp;
|
||||
if (b == SET) USART1.CTLR1.B.UE = SET;
|
||||
}
|
||||
bool Usart::IOCtrl (const CTRL_TYPES_DEF type, const void * data, const uint32_t len) {
|
||||
switch (type) {
|
||||
case USB_USART_SET_PARAM : {
|
||||
const USB_CDC_LineCoding * lc = reinterpret_cast<const USB_CDC_LineCoding *>(data);
|
||||
SetBaud(lc->baud); // Pouze změníme rychlost, ostatní parametry ingorujme
|
||||
} return true;
|
||||
// Ostatní IOCtrl zatím nebudeme obsluhovat, je to celkem zbytečné
|
||||
default : break;
|
||||
};
|
||||
return false;
|
||||
}
|
|
@ -7,6 +7,7 @@ enum CTRL_TYPES_DEF {
|
|||
USB_USART_SET_DTR_RTS,
|
||||
USB_USART_INIT,
|
||||
};
|
||||
static_assert (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__, "Bad ENDIAN");
|
||||
struct USB_CDC_LineCoding {
|
||||
uint32_t baud;
|
||||
uint8_t stop, parity, data;
|
||||
|
|
60
V203/usb/common/mirror.h
Normal file
60
V203/usb/common/mirror.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef MIRROR_H
|
||||
#define MIRROR_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "baselayer.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Obraceč datového toku.
|
||||
* @class Mirror
|
||||
* @brief Obraceč datového toku má 2 třídy.
|
||||
*
|
||||
* TwoTop je vlastní obraceč, dědí vlastnosti BaseLayer, pouze metoda Up je přetížena -
|
||||
* to je to vlastní převrácení. Hlavní třída Mirror, jejíž instance je pak v kódu použita
|
||||
* obsahuje 2 rovnocenné instance třídy TwoTop, které musí být ve stacku vždy navrchu.
|
||||
* První část stacku volá Up jedné instance, druhá Up té druhé. Proto tam musí být dvě.
|
||||
* Podobně by šel udělat něco jako Fork, odbočení datového toku.
|
||||
|
||||
* A zase - všechny metody jsou tak jednoduché, že jsou celé v hlavičce, tedy inline.
|
||||
*
|
||||
* @class TwoTop
|
||||
* @brief Vlastní obraceč.
|
||||
* Ono to vypadá hodně zmateně, ale používá se to snadno - dokonce to funguje.
|
||||
*
|
||||
*/
|
||||
|
||||
class TwoTop : public BaseLayer {
|
||||
public:
|
||||
/// Konstruktor
|
||||
explicit TwoTop () noexcept : BaseLayer (), x (nullptr) {};
|
||||
/// Setter pro x
|
||||
void setX (BaseLayer & bl) { x = & bl; };
|
||||
/// Přetížení metody Up, nic jiného není potřeba
|
||||
uint32_t Up (const char* data, uint32_t len) {
|
||||
if (!x) return 0; // pro jistotu
|
||||
// To, co přišlo zespoda, pošlu druhou instancí zase dolů
|
||||
return x->Down (data, len);
|
||||
};
|
||||
private:
|
||||
/// Fakticky ukazatel na druhou instanci TwoTop
|
||||
BaseLayer * x;
|
||||
};
|
||||
|
||||
class Mirror {
|
||||
public:
|
||||
/// Konstruktor
|
||||
explicit Mirror () noexcept : L(), R() {
|
||||
L.setX (R); R.setX (L);
|
||||
};
|
||||
/**
|
||||
Zřetězení voláme 2x. Poprvé pro jednu +=, podruhé -= pro druhou instanci TwoTop.
|
||||
Protože je tato třída navrchu (vlevo), operátor nic nevrací.
|
||||
*/
|
||||
void operator += (BaseLayer& bl) { L += bl; return; };
|
||||
void operator -= (BaseLayer& bl) { R += bl; return; };
|
||||
private:
|
||||
TwoTop L, R; //!< 2 instance Top
|
||||
};
|
||||
|
||||
#endif // MIRROR_H
|
22
V203/usb/common/usart.h
Normal file
22
V203/usb/common/usart.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef USART_H
|
||||
#define USART_H
|
||||
#include "fifo.h"
|
||||
#include "baselayer.h"
|
||||
#include "ctrlinterface.h"
|
||||
/** @class Usart
|
||||
* @brief Sériový port.
|
||||
*
|
||||
*/
|
||||
class Usart : public BaseLayer, public CDC_CtrlInterface {
|
||||
FIFO<char, 64> tx_ring;
|
||||
public:
|
||||
explicit Usart (const uint32_t baud = 9600) noexcept;
|
||||
uint32_t Down (const char * data, const uint32_t len) override;
|
||||
void SetBaud (const uint32_t baud) const;
|
||||
// Obsluha přerušení musí být veřejná.
|
||||
void irq (void);
|
||||
// Přetížení pro CDC.
|
||||
bool IOCtrl (const CTRL_TYPES_DEF type, const void * data, const uint32_t len) override;
|
||||
};
|
||||
|
||||
#endif // USART_H
|
52
V203/usb/usart/Makefile
Normal file
52
V203/usb/usart/Makefile
Normal file
|
@ -0,0 +1,52 @@
|
|||
TARGET?= ch32v203
|
||||
TOOL ?= gcc
|
||||
#TOOL ?= clang
|
||||
|
||||
PRJ = example
|
||||
|
||||
VPATH = . ./$(TARGET) ./common
|
||||
BLD = ./build/
|
||||
DFLAGS = -d
|
||||
LFLAGS = -g
|
||||
LDLIBS =
|
||||
BFLAGS = --strip-unneeded
|
||||
|
||||
CFLAGS = -MMD -Wall -Wno-parentheses -ggdb -fno-exceptions -ffunction-sections -fdata-sections
|
||||
CFLAGS+= -I. -I./$(TARGET) -I./common
|
||||
DEL = rm -f
|
||||
|
||||
# zdrojaky
|
||||
OBJS = main.o hack.o
|
||||
OBJS += usb_desc.o cdc_class.o usart.o
|
||||
|
||||
include $(TARGET)/$(TOOL).mk
|
||||
BOBJS = $(addprefix $(BLD),$(OBJS))
|
||||
|
||||
all: $(BLD) $(PRJ).elf
|
||||
# ... atd.
|
||||
-include $(BLD)*.d
|
||||
# linker
|
||||
$(PRJ).elf: $(BOBJS)
|
||||
-@echo [LD $(TOOL),$(TARGET)] $@
|
||||
@$(LD) $(LFLAGS) -o $(PRJ).elf $(BOBJS) $(LDLIBS)
|
||||
-@echo "size:"
|
||||
@$(SIZE) $(PRJ).elf
|
||||
-@echo "listing:"
|
||||
$(DUMP) $(DFLAGS) $(PRJ).elf > $(PRJ).lst
|
||||
-@echo "OK."
|
||||
$(COPY) $(BFLAGS) -O binary $(PRJ).elf $(PRJ).bin
|
||||
# preloz co je potreba
|
||||
$(BLD)%.o: %.c
|
||||
-@echo [CC $(TOOL),$(TARGET)] $@
|
||||
@$(CC) -std=gnu99 -c $(CFLAGS) $< -o $@
|
||||
$(BLD)%.o: %.cpp
|
||||
-@echo [CX $(TOOL),$(TARGET)] $@
|
||||
@$(CXX) -std=c++17 -fno-rtti -c $(CFLAGS) $< -o $@
|
||||
$(BLD):
|
||||
mkdir $(BLD)
|
||||
flash: $(PRJ).elf
|
||||
minichlink -w $(PRJ).bin flash -b
|
||||
# vycisti
|
||||
clean:
|
||||
$(DEL) $(BLD)* *.lst *.bin *.elf *.map *~
|
||||
.PHONY: all clean flash run
|
1
V203/usb/usart/ch32v203
Symbolic link
1
V203/usb/usart/ch32v203
Symbolic link
|
@ -0,0 +1 @@
|
|||
../ch32v203/
|
1
V203/usb/usart/common
Symbolic link
1
V203/usb/usart/common
Symbolic link
|
@ -0,0 +1 @@
|
|||
../common/
|
21
V203/usb/usart/hack.c
Normal file
21
V203/usb/usart/hack.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
size_t strlen (const char *s) {
|
||||
size_t l = 0;
|
||||
while (*s++) l++;
|
||||
return l;
|
||||
}
|
||||
void *memcpy (void *dest, const void *src, size_t n) {
|
||||
const char *s = (const char *) src;
|
||||
char *d = (char *) dest;
|
||||
int i;
|
||||
for (i=0; i<n; i++) d[i] = s[i];
|
||||
return dest;
|
||||
}
|
||||
void *memset (void *s, int c, size_t n) {
|
||||
char *p = (char *) s;
|
||||
int i;
|
||||
for (i=0; i<n; i++) p[i] = c;
|
||||
return s;
|
||||
}
|
25
V203/usb/usart/main.cpp
Normal file
25
V203/usb/usart/main.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "cdc_class.h"
|
||||
#include "usart.h"
|
||||
#include "mirror.h"
|
||||
/** Převodník USB_CDC - USART
|
||||
* Datový formát je pevný - 8 bit, 1 stop bit, bez parity.
|
||||
* Změnu po USB by šlo dost jednoduše dodělat, ale nepovažoval jsem to za nutné.
|
||||
* Baudová rychlost se dá po USB změnit na libovolnou hodnotu.
|
||||
*
|
||||
* Výhoda tohoto řešení je, že nad USARTem může běžet nějaký protokol
|
||||
* přímo v tomto čipu. Jinak je to asi nejlevnější řešení. Zřejmě to
|
||||
* nebude snášet velké rychlosti (nad 115200 Bd).
|
||||
* */
|
||||
static cdc_class cdc;
|
||||
static Usart usart;
|
||||
static Mirror top;
|
||||
int main () {
|
||||
cdc.init();
|
||||
top += cdc;
|
||||
top -= usart;
|
||||
cdc.attach(usart);
|
||||
for (;;) {
|
||||
/* Vše probíhá v přerušení */
|
||||
}
|
||||
return 0;
|
||||
}
|
24
V203/usb/usart/test/Makefile
Normal file
24
V203/usb/usart/test/Makefile
Normal file
|
@ -0,0 +1,24 @@
|
|||
PR = test.elf
|
||||
CC = gcc
|
||||
CXX= g++ -std=c++17
|
||||
AS = as
|
||||
CFLAGS = -Wall -Os
|
||||
MFLAGS = -o $(PR)
|
||||
LFLAGS = -lpthread
|
||||
|
||||
all : $(PR)
|
||||
|
||||
OBJECTS = main.o usart.o baud.o
|
||||
|
||||
$(PR) : $(OBJECTS)
|
||||
$(CXX) $(MFLAGS) $(OBJECTS) $(LFLAGS)
|
||||
clean:
|
||||
rm -f *.o *~
|
||||
%.o : %.c
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
%.o : %.cpp
|
||||
$(CXX) -c $(CFLAGS) -o $@ $<
|
||||
%.o : %.s
|
||||
$(AS) -o $@ $<
|
||||
|
||||
.PHONY : all clean
|
14
V203/usb/usart/test/baud.cpp
Normal file
14
V203/usb/usart/test/baud.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include <asm/termbits.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "usart.h"
|
||||
|
||||
void UsartClass::setBaud (int baud) {
|
||||
struct termios2 tio;
|
||||
|
||||
ioctl(fd, TCGETS2, &tio);
|
||||
tio.c_cflag &= ~CBAUD;
|
||||
tio.c_cflag |= BOTHER;
|
||||
tio.c_ispeed = baud;
|
||||
tio.c_ospeed = baud;
|
||||
ioctl(fd, TCSETS2, &tio);
|
||||
}
|
45
V203/usb/usart/test/main.cpp
Normal file
45
V203/usb/usart/test/main.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include "usart.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <signal.h>
|
||||
|
||||
class Top : public BaseLayer {
|
||||
static constexpr int max = 1024;
|
||||
volatile unsigned index;
|
||||
int passcnt;
|
||||
char buffer [max];
|
||||
public:
|
||||
explicit Top () : BaseLayer(), index(0u), passcnt(0) {}
|
||||
void puts (const char * str) {
|
||||
const unsigned l = strlen(str);
|
||||
Down(str, l);
|
||||
}
|
||||
uint32_t Up(const char * data, const uint32_t len) override {
|
||||
for (unsigned n=0; n<len; n++) {
|
||||
const char c = data [n];
|
||||
buffer [index++] = c;
|
||||
if (c == '\n') {
|
||||
buffer [index - 2] = '\0';
|
||||
printf("Rx (%d) %s\n", passcnt++, buffer);
|
||||
index = 0u;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
};
|
||||
static const char * TestString = "THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG'S BACK 1234567890\r\n";
|
||||
static volatile bool loop = false;
|
||||
static void Handler (int) {
|
||||
loop = false;
|
||||
}
|
||||
int main (void) {
|
||||
loop = true;
|
||||
signal (SIGINT, Handler);
|
||||
UsartClass usart ("/dev/serial/by-id/usb-Kizarm_Labs._USB__=__USART_0002-if00", 9600);
|
||||
Top top;
|
||||
top += usart;
|
||||
while (loop) {
|
||||
top.puts(TestString);
|
||||
}
|
||||
return 0;
|
||||
}
|
84
V203/usb/usart/test/usart.cpp
Normal file
84
V203/usb/usart/test/usart.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "usart.h"
|
||||
|
||||
UsartClass::UsartClass (const char * name, const int baudrate) : BaseLayer() {
|
||||
id = name;
|
||||
running = false;
|
||||
fd = ::open (id, O_RDWR);
|
||||
if (fd < 0) return;
|
||||
|
||||
timeout = 12'000'000 / baudrate; // cca pro 1 byte
|
||||
|
||||
struct termios LineFlags;
|
||||
int attr = tcgetattr (fd, &LineFlags);
|
||||
if (attr) {
|
||||
printf ("Nelze zjistit parametry portu %s\r\n", name);
|
||||
::close (fd);
|
||||
return;
|
||||
}
|
||||
// nastaveni komunikacnich parametru do struct termios
|
||||
LineFlags.c_iflag = IGNPAR /* | IXON | IXOFF*/; // ignoruj chyby parity
|
||||
LineFlags.c_oflag = 0; // normalni nastaveni
|
||||
LineFlags.c_cflag = CS8 | CREAD | CLOCAL; // 8-bit, povol prijem
|
||||
LineFlags.c_lflag = 0; // Raw input bez echa
|
||||
LineFlags.c_cc [VMIN] = 1; // minimalni pocet znaku pro cteni
|
||||
LineFlags.c_cc [VTIME] = 1; // read timeout 0.1 s
|
||||
|
||||
tcsetattr (fd, TCSANOW, &LineFlags);
|
||||
fcntl (fd, F_SETFL, 0);
|
||||
|
||||
int flag = TIOCM_DTR;
|
||||
ioctl(fd, TIOCMBIS, & flag);
|
||||
|
||||
setBaud(baudrate);
|
||||
|
||||
printf ("Port %s opened (%d) at %d Bd\r\n", id, fd, baudrate);
|
||||
usleep (10000);
|
||||
running = true;
|
||||
pthread_create (&rc, NULL, UsartClass::UsartHandler, this);
|
||||
}
|
||||
|
||||
UsartClass::~UsartClass() {
|
||||
running = false;
|
||||
pthread_cancel (rc);
|
||||
|
||||
int flag = TIOCM_DTR;
|
||||
ioctl(fd, TIOCMBIC, & flag);
|
||||
|
||||
::close (fd);
|
||||
printf ("Port %s closed\r\n", id);
|
||||
}
|
||||
uint32_t UsartClass::Up (const char * data, uint32_t len) {
|
||||
return BaseLayer::Up (data, len);
|
||||
}
|
||||
|
||||
uint32_t UsartClass::Down (const char * data, uint32_t len) {
|
||||
if (!running) return 0;
|
||||
const unsigned maxchunk = 32; // USB bulk len (64) je moc
|
||||
unsigned offset = 0, remain = len;
|
||||
while (remain) {
|
||||
const unsigned chunk = remain > maxchunk ? maxchunk : remain;
|
||||
const unsigned writn = ::write (fd, data + offset, chunk);
|
||||
usleep (timeout * writn); // závisí na baud rate
|
||||
offset += writn;
|
||||
remain -= writn;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
void UsartClass::ReadLoop (void) {
|
||||
int n;
|
||||
while (running) {
|
||||
// Nutno číst po jednom nebo použít timer, jinak to po prvním čtení zdechne.
|
||||
n = ::read (fd, rxbuf, 1);
|
||||
if (!n) continue;
|
||||
Up (rxbuf, n);
|
||||
}
|
||||
}
|
32
V203/usb/usart/test/usart.h
Normal file
32
V203/usb/usart/test/usart.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef USARTCLASS_H
|
||||
#define USARTCLASS_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include "../common/baselayer.h"
|
||||
|
||||
static constexpr unsigned BUFLEN = 1024u;
|
||||
// Bottom
|
||||
class UsartClass : public BaseLayer {
|
||||
public:
|
||||
UsartClass (const char* name, const int baudrate);
|
||||
uint32_t Up (const char* data, uint32_t len);
|
||||
uint32_t Down(const char* data, uint32_t len);
|
||||
virtual ~UsartClass ();
|
||||
protected:
|
||||
void ReadLoop (void);
|
||||
static void* UsartHandler (void* p) {
|
||||
UsartClass* inst = (UsartClass*) p;
|
||||
inst->ReadLoop();
|
||||
return nullptr;
|
||||
};
|
||||
void setBaud (int baud);
|
||||
public:
|
||||
bool running;
|
||||
private:
|
||||
const char * id; //!< Identifikátor třídy pro ladění
|
||||
char rxbuf[BUFLEN];
|
||||
int fd;
|
||||
int timeout;
|
||||
pthread_t rc;
|
||||
};
|
||||
#endif // USARTCLASS_H
|
83
V203/usb/usart/usb_desc.cpp
Normal file
83
V203/usb/usart/usb_desc.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : usb_desc.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/08/20
|
||||
* Description : usb device descriptor,configuration descriptor,
|
||||
* string descriptors and other descriptors.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "usb_desc.h"
|
||||
|
||||
/* Device Descriptor */
|
||||
const uint8_t MyDevDescr[] =
|
||||
{
|
||||
0x12, // bLength
|
||||
0x01, // bDescriptorType (Device)
|
||||
0x10, 0x01, // bcdUSB 1.10
|
||||
0x02, // bDeviceClass
|
||||
0x00, // bDeviceSubClass
|
||||
0x00, // bDeviceProtocol
|
||||
DEF_USBD_UEP0_SIZE, // bMaxPacketSize0 64
|
||||
(uint8_t)DEF_USB_VID, (uint8_t)(DEF_USB_VID >> 8), // idVendor 0x1A86
|
||||
(uint8_t)DEF_USB_PID, (uint8_t)(DEF_USB_PID >> 8), // idProduct 0x5537
|
||||
DEF_IC_PRG_VER, 0x00, // bcdDevice 0.01
|
||||
0x01, // iManufacturer (String Index)
|
||||
0x02, // iProduct (String Index)
|
||||
0x03, // iSerialNumber (String Index)
|
||||
0x01, // bNumConfigurations 1
|
||||
};
|
||||
|
||||
/* Configuration Descriptor */
|
||||
const uint8_t MyCfgDescr[] =
|
||||
{
|
||||
/* Configure descriptor */
|
||||
0x09, 0x02, 0x43, 0x00, 0x02, 0x01, 0x00, 0x80, 0x32,
|
||||
|
||||
/* Interface 0 (CDC) descriptor */
|
||||
0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x00,
|
||||
|
||||
/* Functional Descriptors */
|
||||
0x05, 0x24, 0x00, 0x10, 0x01,
|
||||
|
||||
/* Length/management descriptor (data class interface 1) */
|
||||
0x05, 0x24, 0x01, 0x00, 0x01,
|
||||
0x04, 0x24, 0x02, 0x02,
|
||||
0x05, 0x24, 0x06, 0x00, 0x01,
|
||||
|
||||
/* Interrupt upload endpoint descriptor */
|
||||
0x07, 0x05, 0x81, 0x03, (uint8_t)DEF_USBD_ENDP1_SIZE, (uint8_t)( DEF_USBD_ENDP1_SIZE >> 8 ), 0x01,
|
||||
|
||||
/* Interface 1 (data interface) descriptor */
|
||||
0x09, 0x04, 0x01, 0x00, 0x02, 0x0A, 0x00, 0x00, 0x00,
|
||||
|
||||
/* Endpoint descriptor */
|
||||
0x07, 0x05, 0x02, 0x02, (uint8_t)DEF_USBD_ENDP2_SIZE, (uint8_t)( DEF_USBD_ENDP2_SIZE >> 8 ), 0x00,
|
||||
|
||||
/* Endpoint descriptor */
|
||||
0x07, 0x05, 0x83, 0x02, (uint8_t)DEF_USBD_ENDP3_SIZE, (uint8_t)( DEF_USBD_ENDP3_SIZE >> 8 ), 0x00,
|
||||
};
|
||||
#define DEF_STRDESC(p,n) w_text<(sizeof(p)>>1)>n={sizeof(n)-2u,3u,{p}}
|
||||
template<const unsigned N> struct w_text {
|
||||
uint8_t len, typ;
|
||||
const char16_t str [N];
|
||||
};
|
||||
static const DEF_STRDESC((u"Kizarm Labs."), str_1);
|
||||
static const DEF_STRDESC((u"USB <=> USART"),str_2);
|
||||
static const DEF_STRDESC((u"0002"), str_3);
|
||||
/* Language Descriptor */
|
||||
static const uint8_t LangDescr[] = {
|
||||
0x04, 0x03, 0x09, 0x04
|
||||
};
|
||||
const uint8_t * StringDescArray [DEF_MAX_STRINGS] = {
|
||||
LangDescr,
|
||||
reinterpret_cast<const uint8_t*> (&str_1),
|
||||
reinterpret_cast<const uint8_t*> (&str_2),
|
||||
reinterpret_cast<const uint8_t*> (&str_3),
|
||||
};
|
||||
|
||||
|
66
V203/usb/usart/usb_desc.h
Normal file
66
V203/usb/usart/usb_desc.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : usb_desc.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2022/08/20
|
||||
* Description : header file of usb_desc.c
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef USER_USB_DESC_H_
|
||||
#define USER_USB_DESC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/******************************************************************************/
|
||||
/* global define */
|
||||
/* file version */
|
||||
#define DEF_FILE_VERSION 0x01
|
||||
/* usb device info define */
|
||||
#define DEF_USB_VID 0x1A86
|
||||
#define DEF_USB_PID 0xFE0C
|
||||
/* USB device descriptor, device serial number(bcdDevice) */
|
||||
#define DEF_IC_PRG_VER DEF_FILE_VERSION
|
||||
|
||||
/******************************************************************************/
|
||||
/* usb device endpoint size define */
|
||||
#define DEF_USBD_UEP0_SIZE 64 /* usb hs/fs device end-point 0 size */
|
||||
/* FS */
|
||||
#define DEF_USBD_FS_PACK_SIZE 64 /* usb fs device max bluk/int pack size */
|
||||
#define DEF_USBD_FS_ISO_PACK_SIZE 1023 /* usb fs device max iso pack size */
|
||||
/* LS */
|
||||
#define DEF_USBD_LS_UEP0_SIZE 8 /* usb ls device end-point 0 size */
|
||||
#define DEF_USBD_LS_PACK_SIZE 64 /* usb ls device max int pack size */
|
||||
|
||||
/* Pack size */
|
||||
#define DEF_USBD_ENDP1_SIZE DEF_USBD_FS_PACK_SIZE
|
||||
#define DEF_USBD_ENDP2_SIZE DEF_USBD_FS_PACK_SIZE
|
||||
#define DEF_USBD_ENDP3_SIZE DEF_USBD_FS_PACK_SIZE
|
||||
#define DEF_USBD_ENDP4_SIZE DEF_USBD_FS_PACK_SIZE
|
||||
#define DEF_USBD_ENDP5_SIZE DEF_USBD_FS_PACK_SIZE
|
||||
#define DEF_USBD_ENDP6_SIZE DEF_USBD_FS_PACK_SIZE
|
||||
#define DEF_USBD_ENDP7_SIZE DEF_USBD_FS_PACK_SIZE
|
||||
|
||||
/******************************************************************************/
|
||||
/* usb device Descriptor length, length of usb descriptors, if one descriptor not
|
||||
* exists , set the length to 0 */
|
||||
#define DEF_USBD_DEVICE_DESC_LEN ((uint8_t)MyDevDescr[0])
|
||||
#define DEF_USBD_CONFIG_DESC_LEN ((uint16_t)MyCfgDescr[2] + (uint16_t)(MyCfgDescr[3] << 8))
|
||||
#define DEF_USBD_REPORT_DESC_LEN 0
|
||||
|
||||
#define DEF_MAX_STRINGS (4)
|
||||
/******************************************************************************/
|
||||
/* external variables */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
extern const uint8_t MyDevDescr[ ];
|
||||
extern const uint8_t MyCfgDescr[ ];
|
||||
extern const uint8_t * StringDescArray [DEF_MAX_STRINGS];
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // __cplusplus
|
||||
#endif /* USER_USB_DESC_H_ */
|
Loading…
Reference in a new issue