mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 07:28:10 +00:00
bootloader: enable MPU, introduce delays to USB stack
This commit is contained in:
parent
5560a35af7
commit
828ba7b5b0
@ -83,6 +83,7 @@ SOURCE_TREZORHAL = [
|
|||||||
'embed/trezorhal/image.c',
|
'embed/trezorhal/image.c',
|
||||||
'embed/trezorhal/flash.c',
|
'embed/trezorhal/flash.c',
|
||||||
'embed/trezorhal/mini_printf.c',
|
'embed/trezorhal/mini_printf.c',
|
||||||
|
'embed/trezorhal/mpu.c',
|
||||||
'embed/trezorhal/rng.c',
|
'embed/trezorhal/rng.c',
|
||||||
'embed/trezorhal/stm32.c',
|
'embed/trezorhal/stm32.c',
|
||||||
'embed/trezorhal/touch.c',
|
'embed/trezorhal/touch.c',
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "mpu.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
@ -224,6 +225,8 @@ static void check_bootloader_version(void)
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
mpu_config_bootloader();
|
||||||
|
|
||||||
main_start:
|
main_start:
|
||||||
display_clear();
|
display_clear();
|
||||||
|
|
||||||
@ -379,9 +382,10 @@ main_start:
|
|||||||
ui_fadeout();
|
ui_fadeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
// mpu_config();
|
// mpu_config_firmware();
|
||||||
// jump_to_unprivileged(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);
|
// jump_to_unprivileged(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);
|
||||||
|
|
||||||
|
mpu_config_off();
|
||||||
jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);
|
jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -54,7 +54,7 @@ int main(void)
|
|||||||
#if TREZOR_MODEL == T
|
#if TREZOR_MODEL == T
|
||||||
check_and_replace_bootloader();
|
check_and_replace_bootloader();
|
||||||
// Enable MPU
|
// Enable MPU
|
||||||
mpu_config();
|
mpu_config_firmware();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init peripherals
|
// Init peripherals
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
|
|
||||||
#include "stm32f4xx_ll_utils.h"
|
#include "stm32f4xx_ll_utils.h"
|
||||||
|
|
||||||
void shutdown(void);
|
// from util.s
|
||||||
|
extern void shutdown(void);
|
||||||
|
|
||||||
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
|
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
|
||||||
|
|
||||||
@ -115,6 +116,24 @@ void hal_delay(uint32_t ms)
|
|||||||
HAL_Delay(ms);
|
HAL_Delay(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delay_random(void)
|
||||||
|
{
|
||||||
|
int wait = rng_get() & 0xff;
|
||||||
|
volatile int i = 0;
|
||||||
|
volatile int j = wait;
|
||||||
|
while (i < wait) {
|
||||||
|
if (i + j != wait) {
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
--j;
|
||||||
|
}
|
||||||
|
// Double-check loop completion.
|
||||||
|
if (i != wait || j != 0) {
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// reference RM0090 section 35.12.1 Figure 413
|
// reference RM0090 section 35.12.1 Figure 413
|
||||||
#define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U)
|
#define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U)
|
||||||
#define USB_OTG_HS_DATA_FIFO_SIZE (4096U)
|
#define USB_OTG_HS_DATA_FIFO_SIZE (4096U)
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
#define XSTR(s) STR(s)
|
#define XSTR(s) STR(s)
|
||||||
#define STR(s) #s
|
#define STR(s) #s
|
||||||
|
|
||||||
|
#ifndef MIN_8bits
|
||||||
|
#define MIN_8bits(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? (_a & 0xFF) : (_b & 0xFF); })
|
||||||
|
#endif
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
|
||||||
#endif
|
#endif
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);
|
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);
|
||||||
@ -40,6 +43,8 @@ void __attribute__((noreturn)) error_shutdown(const char *line1, const char *lin
|
|||||||
|
|
||||||
void hal_delay(uint32_t ms);
|
void hal_delay(uint32_t ms);
|
||||||
|
|
||||||
|
void delay_random(void);
|
||||||
|
|
||||||
void clear_otg_hs_memory(void);
|
void clear_otg_hs_memory(void);
|
||||||
|
|
||||||
extern uint32_t __stack_chk_guard;
|
extern uint32_t __stack_chk_guard;
|
||||||
|
@ -27,10 +27,61 @@
|
|||||||
|
|
||||||
#define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos)
|
#define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos)
|
||||||
|
|
||||||
void mpu_config(void)
|
void mpu_config_off(void)
|
||||||
{
|
{
|
||||||
// Disable MPU
|
// Disable MPU
|
||||||
HAL_MPU_Disable();
|
HAL_MPU_Disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpu_config_bootloader(void)
|
||||||
|
{
|
||||||
|
// Disable MPU
|
||||||
|
HAL_MPU_Disable();
|
||||||
|
|
||||||
|
// Note: later entries overwrite previous ones
|
||||||
|
|
||||||
|
// Flash (0x08000000 - 0x081FFFFF, 2 MiB, read-write)
|
||||||
|
MPU->RBAR = FLASH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER0;
|
||||||
|
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_2MB | LL_MPU_REGION_PRIV_RO_URO;
|
||||||
|
|
||||||
|
// Flash (0x0800C000 - 0x0800FFFF, 16 KiB, no access)
|
||||||
|
MPU->RBAR = FLASH_BASE | 0xC000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER1;
|
||||||
|
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;
|
||||||
|
|
||||||
|
// Flash (0x0810C000 - 0x0810FFFF, 16 KiB, no access)
|
||||||
|
MPU->RBAR = FLASH_BASE | 0x10C000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER2;
|
||||||
|
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;
|
||||||
|
|
||||||
|
// SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, read-write, execute never)
|
||||||
|
MPU->RBAR = SRAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER3;
|
||||||
|
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);
|
||||||
|
|
||||||
|
// Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never)
|
||||||
|
// External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never)
|
||||||
|
MPU->RBAR = PERIPH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER4;
|
||||||
|
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
|
||||||
|
|
||||||
|
#ifdef STM32F427xx
|
||||||
|
// CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never)
|
||||||
|
MPU->RBAR = CCMDATARAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER5;
|
||||||
|
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
|
||||||
|
#elif STM32F405xx
|
||||||
|
// no CCMRAM
|
||||||
|
#else
|
||||||
|
#error Unsupported MCU
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enable MPU
|
||||||
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mpu_config_firmware(void)
|
||||||
|
{
|
||||||
|
// Disable MPU
|
||||||
|
HAL_MPU_Disable();
|
||||||
|
|
||||||
|
// Note: later entries overwrite previous ones
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never)
|
// Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never)
|
||||||
@ -77,5 +128,5 @@ void mpu_config(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable MPU
|
// Enable MPU
|
||||||
HAL_MPU_Enable(0);
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#ifndef __MPU_H__
|
#ifndef __MPU_H__
|
||||||
#define __MPU_H__
|
#define __MPU_H__
|
||||||
|
|
||||||
void mpu_config(void);
|
void mpu_config_off(void);
|
||||||
|
void mpu_config_bootloader(void);
|
||||||
|
void mpu_config_firmware(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -79,7 +79,8 @@ void SysTick_Handler(void)
|
|||||||
uwTick++;
|
uwTick++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown(void);
|
// from util.s
|
||||||
|
extern void shutdown(void);
|
||||||
|
|
||||||
void PVD_IRQHandler(void)
|
void PVD_IRQHandler(void)
|
||||||
{
|
{
|
||||||
|
@ -314,6 +314,7 @@ static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
|
|||||||
#define USB_WEBUSB_URL_SCHEME_HTTPS 1
|
#define USB_WEBUSB_URL_SCHEME_HTTPS 1
|
||||||
|
|
||||||
static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) {
|
static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) {
|
||||||
|
delay_random();
|
||||||
if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) &&
|
if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) &&
|
||||||
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) &&
|
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) &&
|
||||||
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_VENDOR)) {
|
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_VENDOR)) {
|
||||||
@ -330,7 +331,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
|||||||
USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme
|
USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme
|
||||||
't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[]
|
't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[]
|
||||||
};
|
};
|
||||||
USBD_CtlSendData(dev, UNCONST(webusb_url), MIN(req->wLength, sizeof(webusb_url)));
|
USBD_CtlSendData(dev, UNCONST(webusb_url), MIN_8bits(req->wLength, sizeof(webusb_url)));
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
} else {
|
} else {
|
||||||
USBD_CtlError(dev, req);
|
USBD_CtlError(dev, req);
|
||||||
@ -354,7 +355,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
|
||||||
};
|
};
|
||||||
USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN(req->wLength, sizeof(winusb_wcid)));
|
USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN_8bits(req->wLength, sizeof(winusb_wcid)));
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
} else {
|
} else {
|
||||||
USBD_CtlError(dev, req);
|
USBD_CtlError(dev, req);
|
||||||
@ -380,7 +381,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
|||||||
0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength
|
0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength
|
||||||
'{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData
|
'{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData
|
||||||
};
|
};
|
||||||
USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN(req->wLength, sizeof(winusb_guid)));
|
USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN_8bits(req->wLength, sizeof(winusb_guid)));
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
} else {
|
} else {
|
||||||
USBD_CtlError(dev, req);
|
USBD_CtlError(dev, req);
|
||||||
@ -410,6 +411,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
|
static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
|
||||||
|
delay_random();
|
||||||
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
|
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
|
||||||
switch (usb_ifaces[i].type) {
|
switch (usb_ifaces[i].type) {
|
||||||
case USB_IFACE_TYPE_HID:
|
case USB_IFACE_TYPE_HID:
|
||||||
@ -429,6 +431,7 @@ static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
|
static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
|
||||||
|
delay_random();
|
||||||
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
|
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
|
||||||
switch (usb_ifaces[i].type) {
|
switch (usb_ifaces[i].type) {
|
||||||
case USB_IFACE_TYPE_HID:
|
case USB_IFACE_TYPE_HID:
|
||||||
@ -448,6 +451,7 @@ static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) {
|
static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) {
|
||||||
|
delay_random();
|
||||||
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
|
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
|
||||||
switch (usb_ifaces[i].type) {
|
switch (usb_ifaces[i].type) {
|
||||||
case USB_IFACE_TYPE_VCP:
|
case USB_IFACE_TYPE_VCP:
|
||||||
|
@ -254,7 +254,6 @@ static void usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) {
|
static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) {
|
||||||
|
|
||||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||||
|
|
||||||
// Class request
|
// Class request
|
||||||
@ -302,11 +301,11 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
|
|||||||
switch (req->wValue >> 8) {
|
switch (req->wValue >> 8) {
|
||||||
|
|
||||||
case USB_DESC_TYPE_HID:
|
case USB_DESC_TYPE_HID:
|
||||||
USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN(req->wLength, sizeof(state->desc_block->hid)));
|
USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN_8bits(req->wLength, sizeof(state->desc_block->hid)));
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
|
|
||||||
case USB_DESC_TYPE_REPORT:
|
case USB_DESC_TYPE_REPORT:
|
||||||
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len));
|
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN_8bits(req->wLength, state->report_desc_len));
|
||||||
return USBD_OK;
|
return USBD_OK;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -364,13 +364,13 @@ static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
|
|||||||
|
|
||||||
if ((req->bmRequest & USB_REQ_DIR_MASK) == USB_REQ_DIR_D2H) {
|
if ((req->bmRequest & USB_REQ_DIR_MASK) == USB_REQ_DIR_D2H) {
|
||||||
if (req->bRequest == USB_CDC_GET_LINE_CODING) {
|
if (req->bRequest == USB_CDC_GET_LINE_CODING) {
|
||||||
USBD_CtlSendData(dev, UNCONST(&line_coding), MIN(req->wLength, sizeof(line_coding)));
|
USBD_CtlSendData(dev, UNCONST(&line_coding), MIN_8bits(req->wLength, sizeof(line_coding)));
|
||||||
} else {
|
} else {
|
||||||
USBD_CtlSendData(dev, state->cmd_buffer, MIN(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
|
USBD_CtlSendData(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
|
||||||
}
|
}
|
||||||
} else { // USB_REQ_DIR_H2D
|
} else { // USB_REQ_DIR_H2D
|
||||||
if (req->wLength > 0) {
|
if (req->wLength > 0) {
|
||||||
USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
|
USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,9 +263,12 @@ typedef struct _USBD_HandleTypeDef
|
|||||||
|
|
||||||
#define LOBYTE(x) ((uint8_t)(x & 0x00FF))
|
#define LOBYTE(x) ((uint8_t)(x & 0x00FF))
|
||||||
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
|
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
|
||||||
|
#ifndef MIN
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
#ifndef MAX
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined ( __GNUC__ )
|
#if defined ( __GNUC__ )
|
||||||
#ifndef __weak
|
#ifndef __weak
|
||||||
|
@ -27,10 +27,10 @@
|
|||||||
#define STR(s) #s
|
#define STR(s) #s
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
|
||||||
#endif
|
#endif
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);
|
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);
|
||||||
|
Loading…
Reference in New Issue
Block a user