Compare commits
10 Commits
6093e588f3
...
caaa1758a0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
caaa1758a0 | ||
|
|
5df3122a75 | ||
|
|
1d46c5edd1 | ||
|
|
9db6a55518 | ||
|
|
13fcf9232b | ||
|
|
267dcfd475 | ||
|
|
a794becdb9 | ||
|
|
72b3310851 | ||
|
|
11c0e31f3f | ||
|
|
d8606ef0d9 |
4
.github/workflows/build.yaml
vendored
4
.github/workflows/build.yaml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
branches: [master]
|
||||
|
||||
env:
|
||||
MRS_TOOLCHAIN: MRS_Toolchain_Linux_x64_V1.91
|
||||
MRS_TOOLCHAIN: MRS_Toolchain_Linux_x64_V1.92
|
||||
USBC_BUILD_DIR: usb-c
|
||||
MICROB_BUILD_DIR: micro-b
|
||||
BIN_TYPES: '{.bin,.elf}'
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
- if: ${{ steps.cache-toolchain.outputs.cache-hit != 'true' }}
|
||||
name: Download toolchain
|
||||
run: |
|
||||
wget http://file-oss.mounriver.com/tools/${{ env.MRS_TOOLCHAIN }}.tar.xz
|
||||
wget https://github.com/ch32-riscv-ug/MounRiver_Studio_Community_miror/releases/download/1.92-toolchain/${{ env.MRS_TOOLCHAIN }}.tar.xz
|
||||
tar -xvf ${{ env.MRS_TOOLCHAIN }}.tar.xz
|
||||
|
||||
- name: Build firmware
|
||||
|
||||
@@ -81,7 +81,7 @@ void I2C_Init(I2C_ModeTypeDef I2C_Mode, UINT32 I2C_ClockSpeed, I2C_DutyTypeDef I
|
||||
R16_I2C_CTRL1 &= ~(RB_I2C_SMBUS | RB_I2C_SMBTYPE | RB_I2C_ACK);
|
||||
R16_I2C_CTRL1 |= I2C_Mode | I2C_Ack;
|
||||
|
||||
R16_I2C_OADDR1 &= ~0xFFFF;
|
||||
R16_I2C_OADDR1 &= ~0xFFFFU;
|
||||
R16_I2C_OADDR1 |= I2C_AckAddr | I2C_OwnAddress1;
|
||||
}
|
||||
|
||||
|
||||
7
Makefile
7
Makefile
@@ -56,7 +56,6 @@ CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_usb2dev.c \
|
||||
CH5xx_ble_firmware_library/StdPeriphDriver/CH58x_spi1.c \
|
||||
CH5xx_ble_firmware_library/RVMSIS/core_riscv.c \
|
||||
src/main.c \
|
||||
src/debug.c \
|
||||
src/leddrv.c \
|
||||
src/button.c \
|
||||
src/bmlist.c \
|
||||
@@ -74,7 +73,6 @@ src/data.c \
|
||||
src/usb/utils.c \
|
||||
src/usb/setup.c \
|
||||
src/usb/ctrl.c \
|
||||
src/usb/debug.c \
|
||||
src/usb/dev.c \
|
||||
src/usb/composite/hiddev.c \
|
||||
src/usb/composite/cdc-serial.c \
|
||||
@@ -84,6 +82,11 @@ src/animation.c \
|
||||
src/font.c \
|
||||
src/power.c \
|
||||
|
||||
ifdef DEBUG
|
||||
C_SOURCES += \
|
||||
src/debug.c \
|
||||
src/usb/debug.c
|
||||
endif
|
||||
|
||||
# ASM sources
|
||||
ASM_SOURCES = \
|
||||
|
||||
17
README.md
17
README.md
@@ -16,10 +16,9 @@ the boot pin is pulled down in one of two ways:
|
||||
- Alternatively, connect the USB, press and hold KEY2, then short and release
|
||||
the C3 capacitor.
|
||||
|
||||
If the badge has succesfully entered ISP mode, a single pixel roughly in the middle of the display will be lit. The badge will stay in ISP mode for approximately ten seconds before rebooting into normal mode.
|
||||
If the badge has successfully entered ISP mode, a single pixel roughly in the middle of the display will be lit. The badge will stay in ISP mode for approximately ten seconds before rebooting into normal mode.
|
||||
|
||||
You can also check `dmesg` if the chip has entered the ISP mode with idVendor=4348 and
|
||||
idProduct=55e0.
|
||||
On Linux, you can also check `dmesg` if the chip has entered the ISP mode with idVendor=4348 and idProduct=55e0.
|
||||
|
||||

|
||||
|
||||
@@ -41,6 +40,14 @@ Select the `badgemagic-ch582.bin` file and click 'Download'.
|
||||
Where badgemagic-ch582.bin is the binary downloaded above, the .elf file also
|
||||
works.
|
||||
|
||||
### Updating
|
||||
|
||||
Once the open source firmware is installed, there is no further need to remove the battery or short-circuit C3 to enter ISP mode. Simply long-press KEY2 to enter ISP mode. Then, flash updated firmware with
|
||||
|
||||
```sh
|
||||
wchisp config reset
|
||||
wchisp flash badgemagic-ch582.bin
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -99,7 +106,9 @@ version repeatedly.
|
||||
### Tools
|
||||
|
||||
- [GNU make](https://www.gnu.org/software/make/)
|
||||
- [MounRiver Toolchain](http://file-oss.mounriver.com/tools/MRS_Toolchain_Linux_x64_V1.91.tar.xz)
|
||||
- ~[MounRiver Toolchain (removed)](http://file-oss.mounriver.com/tools/MRS_Toolchain_Linux_x64_V1.91.tar.xz)~
|
||||
- [MounRiver Toolchain (community mirror)](https://github.com/ch32-riscv-ug/MounRiver_Studio_Community_miror/releases), specifically:
|
||||
- [MRS_Toolchain_Linux_x64_V1.92.tar.xz](https://github.com/ch32-riscv-ug/MounRiver_Studio_Community_miror/releases/download/1.92-toolchain/MRS_Toolchain_Linux_x64_V1.92.tar.xz)
|
||||
- [wchisp](https://github.com/ch32-rs/wchisp)
|
||||
|
||||
### Build
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t *bytes;
|
||||
const uint8_t *bytes;
|
||||
int size;
|
||||
} byte_t;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "bmlist.h"
|
||||
#include <memory.h>
|
||||
|
||||
volatile static bm_t *current, *head, *tail;
|
||||
static bm_t *current, *head, *tail;
|
||||
|
||||
static void bm_add(bm_t *new, bm_t *prev, bm_t *next)
|
||||
{
|
||||
@@ -63,13 +63,14 @@ static void list_del(bm_t *prev, bm_t *next)
|
||||
|
||||
bm_t *bmlist_drop(bm_t *bm)
|
||||
{
|
||||
bm_t *next = bm->next;
|
||||
list_del(bm->prev, bm->next);
|
||||
if (bm == head)
|
||||
head = bm->next;
|
||||
if (bm == tail)
|
||||
tail = bm->prev;
|
||||
free(bm);
|
||||
return bm->next;
|
||||
return next;
|
||||
}
|
||||
|
||||
bm_t *bm_new(uint16_t width)
|
||||
|
||||
59
src/button.c
59
src/button.c
@@ -1,4 +1,6 @@
|
||||
#include "CH58xBLE_LIB.h"
|
||||
#include "button.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DEBOUNCE_HIGH_THRES (200) // 0-255
|
||||
#define DEBOUNCE_LOW_THRES (55) // 0-255
|
||||
@@ -8,6 +10,13 @@
|
||||
static volatile void (*onePressHandler[KEY_INDEX])(void) = { NULL };
|
||||
static volatile void (*longPressHandler[KEY_INDEX])(void) = { NULL };
|
||||
|
||||
static volatile bool onePressPending[KEY_INDEX] = { false };
|
||||
static volatile bool longPressPending[KEY_INDEX] = { false };
|
||||
|
||||
static tmosTaskID button_task_id = INVALID_TASK_ID;
|
||||
#define BTN_PRESS (1 << 0)
|
||||
static uint16_t btn_task(tmosTaskID, uint16_t);
|
||||
|
||||
void btn_init()
|
||||
{
|
||||
GPIOA_ModeCfg(KEY1_PIN, GPIO_ModeIN_PD);
|
||||
@@ -18,6 +27,11 @@ void btn_init()
|
||||
PFIC_EnableIRQ(TMR3_IRQn);
|
||||
}
|
||||
|
||||
void btn_init_task(void)
|
||||
{
|
||||
button_task_id = TMOS_ProcessEventRegister(btn_task);
|
||||
}
|
||||
|
||||
void btn_onOnePress(int key, void (*handler)(void))
|
||||
{
|
||||
if (key >= KEY_INDEX) return;
|
||||
@@ -30,6 +44,41 @@ void btn_onLongPress(int key, void (*handler)(void))
|
||||
longPressHandler[key] = handler;
|
||||
}
|
||||
|
||||
void btn_tick(void)
|
||||
{
|
||||
for (int i = 0; i < KEY_INDEX; i++) {
|
||||
if (onePressPending[i]) {
|
||||
onePressPending[i] = false;
|
||||
if (onePressHandler[i]) onePressHandler[i]();
|
||||
}
|
||||
if (longPressPending[i]) {
|
||||
longPressPending[i] = false;
|
||||
if (longPressHandler[i]) longPressHandler[i]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t btn_task(tmosTaskID id, uint16_t events)
|
||||
{
|
||||
|
||||
if(events & SYS_EVENT_MSG) {
|
||||
uint8 *pMsg = tmos_msg_receive(button_task_id);
|
||||
if(pMsg != NULL)
|
||||
{
|
||||
tmos_msg_deallocate(pMsg);
|
||||
}
|
||||
return (events ^ SYS_EVENT_MSG);
|
||||
}
|
||||
|
||||
if (events & BTN_PRESS) {
|
||||
btn_tick();
|
||||
return (events ^ BTN_PRESS);
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
|
||||
__HIGH_CODE
|
||||
static int debounce(int key, int is_press)
|
||||
{
|
||||
@@ -59,11 +108,17 @@ static void check(int k)
|
||||
hold[k]++;
|
||||
if (hold[k] >= LONGPRESS_THRES && is_longpress[k] == 0) {
|
||||
is_longpress[k] = 1;
|
||||
if (longPressHandler[k]) longPressHandler[k]();
|
||||
longPressPending[k] = true;
|
||||
if (button_task_id != INVALID_TASK_ID) {
|
||||
tmos_set_event(button_task_id, BTN_PRESS);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (hold[k] > 0 && hold[k] < LONGPRESS_THRES) {
|
||||
if (onePressHandler[k]) onePressHandler[k]();
|
||||
onePressPending[k] = true;
|
||||
if (button_task_id != INVALID_TASK_ID) {
|
||||
tmos_set_event(button_task_id, BTN_PRESS);
|
||||
}
|
||||
}
|
||||
is_longpress[k] = 0;
|
||||
hold[k] = 0;
|
||||
|
||||
@@ -19,5 +19,7 @@ enum keys {
|
||||
void btn_onOnePress(int key, void (*handler)(void));
|
||||
void btn_onLongPress(int key, void (*handler)(void));
|
||||
void btn_init();
|
||||
void btn_init_task(void);
|
||||
void btn_tick(void);
|
||||
|
||||
#endif /* __BUTTON_H__ */
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "resource.h"
|
||||
#include "res/foss-asia-2.xbm"
|
||||
#include "debug.h"
|
||||
#include "util/crc.h"
|
||||
|
||||
|
||||
11
src/data.c
11
src/data.c
@@ -7,11 +7,16 @@
|
||||
#include "data.h"
|
||||
#include "leddrv.h"
|
||||
|
||||
uint32_t bigendian16_sum(uint16_t *s, int len)
|
||||
uint32_t bigendian16_sum(const uint8_t *s, int len)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
while (len-- > 0) {
|
||||
sum += bswap16(s[len]);
|
||||
// Read the big-endian bytes for this uint16_t
|
||||
uint8_t high = s[len * 2]; // MSB (most significant byte)
|
||||
uint8_t low = s[len * 2 + 1]; // LSB (least significant byte)
|
||||
// Reconstruct the uint16_t value (big-endian to little-endian equivalent)
|
||||
uint16_t val = (high << 8) | low;
|
||||
sum += val;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
@@ -42,7 +47,7 @@ uint16_t data_flash2newmem(uint8_t **chunk, uint32_t n)
|
||||
return 0;
|
||||
|
||||
uint16_t offs = LEGACY_HEADER_SIZE
|
||||
+ bigendian16_sum(header.sizes, n) * LED_ROWS;
|
||||
+ bigendian16_sum((const uint8_t*)header.sizes, n) * LED_ROWS;
|
||||
|
||||
*chunk = malloc(size);
|
||||
EEPROM_READ(offs, *chunk, size);
|
||||
|
||||
@@ -42,7 +42,7 @@ enum ANIMATION_MODES {
|
||||
static inline uint16_t bswap16(uint16_t i) {
|
||||
return (i >> 8) | (i << 8);
|
||||
}
|
||||
uint32_t bigendian16_sum(uint16_t *s, int len);
|
||||
uint32_t bigendian16_sum(const uint8_t *s, int len);
|
||||
|
||||
uint32_t data_flatSave(uint8_t *data, uint32_t len);
|
||||
uint16_t data_flash2newmem(uint8_t **chunk, uint32_t n);
|
||||
|
||||
@@ -50,7 +50,7 @@ int legacy_ble_rx(uint8_t *val, uint16_t len)
|
||||
|
||||
if (c == 1) {
|
||||
data_legacy_t *d = (data_legacy_t *)data;
|
||||
n = bigendian16_sum(d->sizes, 8);
|
||||
n = bigendian16_sum((uint8_t*)d->sizes, 8);
|
||||
data_len = LEGACY_HEADER_SIZE + LED_ROWS * n;
|
||||
PRINT("Data len: %d\n", data_len);
|
||||
data = realloc(data, data_len);
|
||||
@@ -96,7 +96,7 @@ int legacy_usb_rx(uint8_t *buf, uint16_t len)
|
||||
|
||||
if (!data_len) {
|
||||
data_legacy_t *d = (data_legacy_t *)data;
|
||||
uint16_t n = bigendian16_sum(d->sizes, 8);
|
||||
uint16_t n = bigendian16_sum((uint8_t*)d->sizes, 8);
|
||||
data_len = LEGACY_HEADER_SIZE + LED_ROWS * n;
|
||||
data = realloc(data, data_len);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ enum MODES {
|
||||
|
||||
static tmosTaskID common_taskid = INVALID_TASK_ID ;
|
||||
|
||||
volatile uint16_t fb[LED_COLS] = {0};
|
||||
uint16_t fb[LED_COLS] = {0};
|
||||
volatile int mode, is_play_sequentially = 1;
|
||||
|
||||
__HIGH_CODE
|
||||
@@ -344,6 +344,7 @@ static void disp_charging()
|
||||
{
|
||||
int blink = 0;
|
||||
while (mode == BOOT) {
|
||||
btn_tick();
|
||||
int percent = batt_raw2percent(batt_raw());
|
||||
|
||||
if (charging_status()) {
|
||||
@@ -434,7 +435,7 @@ int main()
|
||||
disp_charging();
|
||||
cfg_init();
|
||||
xbm_t spl = {
|
||||
.bits = &(badge_cfg.splash_bm_bits),
|
||||
.bits = badge_cfg.splash_bm_bits,
|
||||
.w = badge_cfg.splash_bm_w,
|
||||
.h = badge_cfg.splash_bm_h,
|
||||
.fh = badge_cfg.splash_bm_fh,
|
||||
@@ -446,6 +447,7 @@ int main()
|
||||
ble_setup();
|
||||
|
||||
spawn_tasks();
|
||||
btn_init_task();
|
||||
|
||||
mode = NORMAL;
|
||||
while (1) {
|
||||
|
||||
@@ -125,7 +125,7 @@ uint8_t load_fallback_cfg(uint8_t *val, uint16_t len)
|
||||
{
|
||||
PRINT(__func__);
|
||||
PRINT("\n");
|
||||
cfg_fallback(&badge_cfg);
|
||||
cfg_fallback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ void power_init()
|
||||
GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_Floating);
|
||||
ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);
|
||||
|
||||
int16_t adc_calib = ADC_DataCalib_Rough();
|
||||
PRINT("RoughCalib_Value = %d \n", adc_calib);
|
||||
PRINT("RoughCalib_Value = %d \n", ADC_DataCalib_Rough());
|
||||
|
||||
ADC_ChannelCfg(1);
|
||||
}
|
||||
@@ -38,7 +37,6 @@ int batt_raw()
|
||||
int ret = 0;
|
||||
|
||||
PRINT("ADC reading: \n");
|
||||
uint16_t buf[20];
|
||||
for(int i = 0; i < 20; i++) {
|
||||
uint16_t adc = ADC_ExcutSingleConver();
|
||||
ret += adc;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define foss_asia_2_width 44
|
||||
#define foss_asia_2_height 22
|
||||
static unsigned char foss_asia_2_bits[] = {
|
||||
unsigned const char foss_asia_2_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf9, 0x8f, 0xff, 0xfc, 0x07,
|
||||
0xfe, 0xfd, 0xdf, 0xff, 0xfe, 0x07, 0x06, 0x0c, 0xd8, 0x00, 0x06, 0x00,
|
||||
0xff, 0x0d, 0xd8, 0x7f, 0xfe, 0x03, 0xff, 0x0d, 0x98, 0xff, 0xfc, 0x07,
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#define USB_DESCTYPE_CS_INTERFACE 0x24
|
||||
|
||||
static __attribute__((aligned(4))) uint8_t noti_ep_buf[64 + 64];
|
||||
static uint8_t *const noti_ep_out = noti_ep_buf;
|
||||
static uint8_t *const noti_ep_in = noti_ep_buf + 64;
|
||||
|
||||
static __attribute__((aligned(4))) uint8_t data_ep_buf[64 + 64];
|
||||
static uint8_t *const data_ep_out = data_ep_buf;
|
||||
|
||||
@@ -19,7 +19,7 @@ void usb_set_address(uint8_t ad)
|
||||
address = ad;
|
||||
}
|
||||
|
||||
void ctrl_start_load_block(void *buf, uint16_t len)
|
||||
void ctrl_start_load_block(const void *buf, uint16_t len)
|
||||
{
|
||||
usb_start_load_block(ep0buf, buf, len, 1);
|
||||
}
|
||||
@@ -53,7 +53,9 @@ static void ep_handler()
|
||||
switch(token) {
|
||||
|
||||
case UIS_TOKEN_SETUP:
|
||||
print_setuppk(req);
|
||||
#ifdef DEBUG
|
||||
print_setuppk(request);
|
||||
#endif
|
||||
|
||||
if (recip == USB_REQ_RECIP_DEVICE) {
|
||||
handle_devreq(request);
|
||||
@@ -128,12 +130,16 @@ __HIGH_CODE
|
||||
void USB_IRQHandler(void) {
|
||||
uint8_t intflag = R8_USB_INT_FG;
|
||||
clear_handshake_sent_flag();
|
||||
#ifdef DEBUG
|
||||
PRINT("\nusb: new interrupt\n");
|
||||
print_intflag_reg();
|
||||
#endif
|
||||
|
||||
if (intflag & RB_UIF_TRANSFER) {
|
||||
#ifdef DEBUG
|
||||
PRINT("usb: RX Length reg: %d\n", R8_USB_RX_LEN);
|
||||
print_status_reg();
|
||||
#endif
|
||||
|
||||
route_enpoints();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ USB_DEV_DESCR dev_desc = {
|
||||
};
|
||||
|
||||
/* String Descriptor Zero, Specifying Languages Supported by the Device */
|
||||
static uint8_t lang_desc[] = {
|
||||
static uint16_t lang_desc[] = {
|
||||
0x04, /* bLength */
|
||||
0x03, /* bDescriptorType */
|
||||
0x09, 0x04 /* wLANGID - en-US */
|
||||
@@ -91,7 +91,7 @@ static void desc_config(USB_SETUP_REQ *request)
|
||||
|
||||
static void desc_string(USB_SETUP_REQ *request)
|
||||
{
|
||||
uint8_t *string_index[32] = {
|
||||
uint16_t *string_index[32] = {
|
||||
lang_desc,
|
||||
vendor_info,
|
||||
product_info,
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
|
||||
void cdc_fill_IN(uint8_t *buf, uint8_t len);
|
||||
int cdc_tx_poll(uint8_t *buf, int len, uint16_t timeout_ms);
|
||||
void cdc_onWrite(void (*cb)(uint8_t *buf, uint16_t len));
|
||||
void cdc_onWrite(int (*cb)(uint8_t *buf, uint16_t len));
|
||||
|
||||
void hiddev_fill_IN(uint8_t *buf, uint8_t len);
|
||||
int hiddev_tx_poll(uint8_t *buf, int len, uint16_t timeout_ms);
|
||||
void hiddev_onWrite(void (*cb)(uint8_t *buf, uint16_t len));
|
||||
void hiddev_onWrite(int (*cb)(uint8_t *buf, uint16_t len));
|
||||
|
||||
void usb_start();
|
||||
|
||||
|
||||
@@ -35,9 +35,8 @@ static void __handshake(uint8_t ep_num, int dir, int type, int tog, uint8_t len)
|
||||
if (ep_num > 7)
|
||||
return;
|
||||
|
||||
char *type_mean[] = { "ACK", "NO_RESP", "NAK", "STALL"};
|
||||
PRINT("Loaded %d byte, DATA%d with an %s to EP%dIN.\n",
|
||||
len, tog != 0, type_mean[type], ep_num);
|
||||
len, tog != 0, ((char *[]){ "ACK", "NO_RESP", "NAK", "STALL"})[type], ep_num);
|
||||
|
||||
uint8_t ctrl = type << (dir ? 0 : 2);
|
||||
ctrl |= (tog) ? RB_UEP_T_TOG : RB_UEP_R_TOG;
|
||||
@@ -69,11 +68,11 @@ int handshake_sent()
|
||||
return res_sent;
|
||||
}
|
||||
|
||||
static uint8_t *p_buf;
|
||||
static const uint8_t *p_buf;
|
||||
static uint16_t remain_len, req_len, _tog;
|
||||
|
||||
static uint16_t
|
||||
load_chunk(void *ep_buf, void *block, uint16_t block_len, uint16_t req_len,
|
||||
load_chunk(void *ep_buf, const void *block, uint16_t block_len, uint16_t req_len,
|
||||
int tog)
|
||||
{
|
||||
_TRACE();
|
||||
@@ -119,7 +118,7 @@ int usb_load_next_chunk()
|
||||
}
|
||||
|
||||
uint16_t
|
||||
usb_start_load_block(void *ep_IN_buf, void *buf, uint16_t len, int tog)
|
||||
usb_start_load_block(void *ep_IN_buf, const void *buf, uint16_t len, int tog)
|
||||
{
|
||||
_TRACE();
|
||||
req_len = len;
|
||||
|
||||
@@ -16,8 +16,8 @@ int if_cb_register(uint8_t if_num, void (*cb)(USB_SETUP_REQ *request));
|
||||
void dma_register(uint8_t endpoint_number, void *buf_addr);
|
||||
|
||||
uint16_t
|
||||
usb_start_load_block(void *ep_IN_buf, void *buf, uint16_t len, int tog);
|
||||
void ctrl_start_load_block(void *buf, uint16_t len);
|
||||
usb_start_load_block(void *ep_IN_buf, const void *buf, uint16_t len, int tog);
|
||||
void ctrl_start_load_block(const void *buf, uint16_t len);
|
||||
int usb_load_next_chunk();
|
||||
void usb_flush();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user