Код: Выделить всё
#include "stm32f10x.h"
#include "stdbool.h"
#include "string.h"
#include "usb_def.h"
#include "usb_hid.h"
volatile uint32_t g_msTicks = 0;
volatile uint32_t g_times = 0;
volatile uint32_t g_resets = 0;
volatile uint32_t g_controls = 0;
volatile uint32_t g_cntr = 0;
struct History
{
uint16_t EP_before;
uint16_t EP_after;
uint8_t signal;
uint8_t value;
uint16_t sz;
char cmd;
};
struct History history[100];
#define HISTORY_MAX 100
uint32_t historyCntr = 0;
const uint8_t *g_controlBuf = NULL;
uint32_t g_controlSize = 0;
uint8_t g_newAddr = 0;
#define HID_SIZE_DEVICE_DESC 18
#define E0_MAX_PACKET_SIZE 8
#define E1_MAX_PACKET_SIZE 8
#define E2_MAX_PACKET_SIZE 8
#define RHID_SIZ_CONFIG_DESC 41
#define RHID_SIZ_REPORT_DESC 79
#define wMaxPacketSize 8
#define USB_BASE_ADDR 0x40005C00 /* USB Registers Base Address */
#define USB_PMA_ADDR 0x40006000 /* USB Packet Memory Area Address */
#define LOWBYTE(v) ((unsigned char) (v))
#define HIGHBYTE(v) ((unsigned char) (((unsigned int) (v)) >> 8))
/* Common Registers */
#define USB_CNTR *((volatile unsigned int *)(USB_BASE_ADDR + 0x40)) /* Control Register */
#define USB_ISTR *((volatile unsigned int *)(USB_BASE_ADDR + 0x44)) /* Interrupt Status Register */
#define USB_FNR *((volatile unsigned int *)(USB_BASE_ADDR + 0x48)) /* Frame Number Register */
#define USB_DADDR *((volatile unsigned int *)(USB_BASE_ADDR + 0x4C)) /* Device Address Register */
#define USB_BTABLE *((volatile unsigned int *)(USB_BASE_ADDR + 0x50)) /* Buffer Table Address Register */
#define USB_EP0R *((volatile unsigned int *)(USB_BASE_ADDR + 4*0))
#define USB_EP1R *((volatile unsigned int *)(USB_BASE_ADDR + 4*1))
#define USB_EP2R *((volatile unsigned int *)(USB_BASE_ADDR + 4*2))
#define USB_EP3R *((volatile unsigned int *)(USB_BASE_ADDR + 4*3))
#define USB_EP4R *((volatile unsigned int *)(USB_BASE_ADDR + 4*4))
#define USB_EP5R *((volatile unsigned int *)(USB_BASE_ADDR + 4*5))
#define USB_EP6R *((volatile unsigned int *)(USB_BASE_ADDR + 4*6))
#define USB_EP7R *((volatile unsigned int *)(USB_BASE_ADDR + 4*7))
#define USB_CONTROL_TX_ADDR ((void*)(USB_PMA_ADDR + 3*16 + 0))
#define USB_CONTROL_RX_ADDR ((void*)(USB_PMA_ADDR + 3*16 + E0_MAX_PACKET_SIZE * 2))
#define USB_E0_TX_SIZE_ADDR ((void*)(USB_PMA_ADDR + 4))
#define USB_E0_RX_SIZE_ADDR ((void*)(USB_PMA_ADDR + 8 + 4))
#define USB_E1_TX_SIZE_ADDR ((void*)(USB_PMA_ADDR + 16 + 4))
#define USB_E1_RX_SIZE_ADDR ((void*)(USB_PMA_ADDR + 16 + 8 + 4))
#define USB_E1_TX_ADDR ((void*)(USB_PMA_ADDR + 3*16 + E0_MAX_PACKET_SIZE * 4 + 0))
#define USB_E1_RX_ADDR ((void*)(USB_PMA_ADDR + 3*16 + E0_MAX_PACKET_SIZE * 4 + E0_MAX_PACKET_SIZE * 2))
const uint8_t USB_StringSupportedLanguages[] =
{
4, USB_STRING_DESCRIPTOR_TYPE,
0x09, 0x4
};
const uint8_t USB_StringManufacturer[] =
{
12,
USB_STRING_DESCRIPTOR_TYPE,
'A',0,'l',0,'m',0,'a',0,'z',0
};
const uint8_t USB_StringProduct[] =
{
12,
USB_STRING_DESCRIPTOR_TYPE,
'S',0,'T',0,'M',0,'3',0,'2',0
};
const uint8_t USB_StringSerial[] =
{
14,
USB_STRING_DESCRIPTOR_TYPE,
'M',0,'Y',0,'0',0,'0',0,'0',0,'1',0
};
const uint8_t USB_AlternateSetting[1] = { 0 };
/* USB Standard Device Descriptor */
const uint8_t HID_DeviceDescriptor[HID_SIZE_DEVICE_DESC] =
{
HID_SIZE_DEVICE_DESC,
USB_DEVICE_DESCRIPTOR_TYPE, // bDescriptorType - Device descriptor
0x00, 0x02, // bcdUSB
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
E0_MAX_PACKET_SIZE, // bMaxPacketSize - Endpoint 0
0x83, 0x04, // idVendor (0x0483)
0x11, 0x57, // idProduct (0x5711)
0, 1, // bcdDevice rel. DEVICE_VER_H.DEVICE_VER_L
1, // Index of string descriptor describing manufacturer
2, // Index of string descriptor describing product
3, // Index of string descriptor describing the device serial number
1 // bNumConfigurations
};
/* USB Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const uint8_t RHID_ConfigDescriptor[RHID_SIZ_CONFIG_DESC] =
{
0x09, // bLength: ????? ??????????? ????????????
USB_CONFIGURATION_DESCRIPTOR_TYPE, // bDescriptorType: ??? ??????????? - ????????????
RHID_SIZ_CONFIG_DESC, 0x00, // wTotalLength: ????? ?????? ????? ?????? ??? ?????? ????????????? ? ??????
0x01, // bNumInterfaces: ? ???????????? ????? ???? ?????????
0x01, // bConfigurationValue: ?????? ?????? ????????????
0x00, // iConfiguration: ?????? ??????, ??????? ????????? ??? ????????????
0xE0, // bmAttributes: ??????? ????, ??? ?????????? ????? ???????? ?? ???? USB
0x32, // MaxPower 100 mA: ? ??? ?????? 100 ??
/************** ?????????? ?????????? ****************/
0x09, // bLength: ?????? ??????????? ??????????
USB_INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType: ??? ??????????? - ?????????
0x00, // bInterfaceNumber: ?????????? ????? ?????????? - 0
0x00, // bAlternateSetting: ??????? ??????????????? ??????????, ? ??? ?? ????????????
0x02, // bNumEndpoints - ?????????? ??????????.
0x03, // bInterfaceClass: ????? ????????? - HID
// ???? ?? ?? ?????? ??? ??????????? ??????????, ???????? ?????????? ??? ????, ?? ???? ???? ?? ??????? ????????? ????? ? ????????
// ? ??? ? ??? ????? HID-??????????
0x00, // bInterfaceSubClass : ???????? ??????????.
0x00, // nInterfaceProtocol : ???????? ??????????
0, // iInterface: ?????? ??????, ??????????? ?????????
// ?????? ????????? ?????????? ??? ????????? ????, ??? ?????? ????????? - ??? HID ??????????
/******************** HID ?????????? ********************/
0x09, // bLength: ????? HID-???????????
HID_HID_DESCRIPTOR_TYPE, // bDescriptorType: ??? ??????????? - HID
0x01, 0x01, // bcdHID: ????? ?????? HID 1.1
0x00, // bCountryCode: ??? ?????? (???? ?????)
0x01, // bNumDescriptors: ??????? ?????? ????? report ????????????
HID_REPORT_DESCRIPTOR_TYPE, // bDescriptorType: ??? ??????????? - report
RHID_SIZ_REPORT_DESC, 0x00, // wItemLength: ????? report-???????????
/******************** ?????????? ???????? ????? (endpoints) ********************/
0x07, // bLength: ????? ???????????
USB_ENDPOINT_DESCRIPTOR_TYPE, // ??? ??????????? - endpoints
0x81, // bEndpointAddress: ????? ???????? ????? ? ??????????? 1(IN)
0x03, // bmAttributes: ??? ???????? ????? - Interrupt endpoint
wMaxPacketSize, 0x00, // wMaxPacketSize: Bytes max
0x20, // bInterval: Polling Interval (32 ms)
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
/* Endpoint descriptor type */
0x01, /* bEndpointAddress: */
/* Endpoint Address (OUT) */
0x03, /* bmAttributes: Interrupt endpoint */
wMaxPacketSize, /* wMaxPacketSize: Bytes max */
0x00,
0x20, /* bInterval: Polling Interval (32 ms) */
}
; /* RHID_ConfigDescriptor */
#define RPT3_COUNT 0x01 //PC->STM32
#define RPT4_COUNT 0x04 //STM32->PC
const uint8_t RHID_ReportDescriptor[RHID_SIZ_REPORT_DESC] =
{
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x01, // REPORT_ID (1)
0x09, 0x01, // USAGE (Vendor Usage 1)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0xb1, 0x82, // FEATURE (Data,Var,Abs,Vol)
0x85, 0x01, // REPORT_ID (1)
0x09, 0x01, // USAGE (Vendor Usage 1)
0x91, 0x82, // OUTPUT (Data,Var,Abs,Vol)
0x85, 0x02, // REPORT_ID (2)
0x09, 0x02, // USAGE (Vendor Usage 2)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0xb1, 0x82, // FEATURE (Data,Var,Abs,Vol)
0x85, 0x02, // REPORT_ID (2)
0x09, 0x02, // USAGE (Vendor Usage 2)
0x91, 0x82, // OUTPUT (Data,Var,Abs,Vol)
0x85, 0x03, // REPORT_ID (3)
0x09, 0x03, // USAGE (Vendor Usage 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, RPT3_COUNT, // REPORT_COUNT (N)
0xb1, 0x82, // FEATURE (Data,Var,Abs,Vol)
0x85, 0x03, // REPORT_ID (3)
0x09, 0x03, // USAGE (Vendor Usage 3)
0x91, 0x82, // OUTPUT (Data,Var,Abs,Vol)
0x85, 0x04, // REPORT_ID (4)
0x09, 0x04, // USAGE (Vendor Usage 4)
0x75, 0x08, // REPORT_SIZE (8)
0x95, RPT4_COUNT, // REPORT_COUNT (N)
0x81, 0x82, // INPUT (Data,Var,Abs,Vol)
0xc0 // END_COLLECTION
};
enum USB_State
{
USB_StateDefault = 0,
USB_StateAddress,
USB_StateConfigured,
};
enum USB_State g_usbState = USB_StateDefault;
void sup_copy(uint8_t *dst, const uint8_t *src, uint32_t size)
{
for (; size > 1; size -= 2, dst += 4, src += 2)
*(uint16_t*)dst = *(uint16_t*)src;
if (size == 1)
{
uint16_t tmp = *src;
*(uint16_t*)dst = tmp;
}
}
void SendStatusZero()
{
// fix size
*(uint16_t*)USB_E0_TX_SIZE_ADDR = 0;
// send
history[historyCntr % HISTORY_MAX].EP_before = USB_EP0R;
USB_EP0R = (USB_EP0R ^ USB_EP0R_STAT_TX) & (USB_EP0R_STAT_TX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_EA);
history[historyCntr % HISTORY_MAX].EP_after = USB_EP0R;
history[historyCntr++ % HISTORY_MAX].cmd = 'Z';
}
void ProcessData(void)
{
if (USB_EP1R & USB_EP1R_CTR_TX)
{
uint8_t buf[5] = { 4 };
g_cntr++;
buf[1] = g_cntr % 255;
buf[2] = g_cntr / 255 % 255;
buf[3] = g_cntr / 10 & 3;
// *(uint32_t*)&buf[1] = historyCntr;
*(uint16_t*)USB_E1_TX_SIZE_ADDR = 5;
sup_copy(USB_E1_TX_ADDR, buf, 5);
USB_EP1R = (USB_EP1R ^ USB_EP1R_STAT_TX) & (USB_EP1R_STAT_TX | USB_EP1R_EP_TYPE | USB_EP1R_EP_KIND | USB_EP1R_EA);
}
}
void ProcessControl(void)
{
g_controls++;
if (USB_EP0R & USB_EP0R_CTR_RX)
{
if (USB_EP0R & USB_EP0R_SETUP)
{
uint8_t *setup = (uint8_t*)USB_CONTROL_RX_ADDR;
uint16_t wValue, /*wIndex,*/ wLength;
USB_REQUEST_TYPE bmRequestType = *(USB_REQUEST_TYPE*)(setup++);
uint8_t bRequest = *(setup++);
setup += 2;
wValue = *(uint16_t*)setup;
setup += 4;
setup += 4;
wLength = *(uint16_t*)setup;
setup += 4;
history[historyCntr % HISTORY_MAX].EP_before = history[historyCntr % HISTORY_MAX].EP_after = USB_EP0R;
history[historyCntr % HISTORY_MAX].signal = bRequest;
history[historyCntr % HISTORY_MAX].value = HIGHBYTE(wValue);
history[historyCntr % HISTORY_MAX].sz = (*(uint16_t*)USB_E0_RX_SIZE_ADDR) & USB_COUNT0_RX_COUNT0_RX;
history[historyCntr++ % HISTORY_MAX].cmd = 'D';
if (bRequest == USB_REQUEST_GET_DESCRIPTOR)
{
if (HIGHBYTE(wValue) == USB_DEVICE_DESCRIPTOR_TYPE)
{
g_controlBuf = HID_DeviceDescriptor;
g_controlSize = wLength > sizeof(HID_DeviceDescriptor) ? sizeof(HID_DeviceDescriptor) : wLength;
}
else if (HIGHBYTE(wValue) == USB_CONFIGURATION_DESCRIPTOR_TYPE)
{
g_controlBuf = RHID_ConfigDescriptor;
g_controlSize = wLength > sizeof(RHID_ConfigDescriptor) ? sizeof(RHID_ConfigDescriptor) : wLength;
}
else if (HIGHBYTE(wValue) == USB_STRING_DESCRIPTOR_TYPE)
{
if (LOWBYTE(wValue) == 0)
{
g_controlBuf = USB_StringSupportedLanguages;
g_controlSize = wLength > sizeof(USB_StringSupportedLanguages) ? sizeof(USB_StringSupportedLanguages) : wLength;
}
else if (LOWBYTE(wValue) == 1)
{
g_controlBuf = USB_StringManufacturer;
g_controlSize = wLength > sizeof(USB_StringManufacturer) ? sizeof(USB_StringManufacturer) : wLength;
}
else if (LOWBYTE(wValue) == 2)
{
g_controlBuf = USB_StringProduct;
g_controlSize = wLength > sizeof(USB_StringProduct) ? sizeof(USB_StringProduct) : wLength;
}
else if (LOWBYTE(wValue) == 3)
{
g_controlBuf = USB_StringSerial;
g_controlSize = wLength > sizeof(USB_StringSerial) ? sizeof(USB_StringSerial) : wLength;
}
else
{
g_controlSize = 0;
return;
}
}
else if (HIGHBYTE(wValue) == USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE)
{
history[historyCntr % HISTORY_MAX].EP_before = USB_EP0R;
history[historyCntr % HISTORY_MAX].signal = bRequest;
history[historyCntr % HISTORY_MAX].value = HIGHBYTE(wValue);
history[historyCntr % HISTORY_MAX].sz = (*(uint16_t*)USB_E0_RX_SIZE_ADDR) & USB_COUNT0_RX_COUNT0_RX;
// send stall
USB_EP0R = (USB_EP0R ^ USB_EP0R_STAT_TX_0) & (USB_EP0R_STAT_TX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_EA);
history[historyCntr % HISTORY_MAX].EP_after = USB_EP0R;
history[historyCntr++ % HISTORY_MAX].cmd = 'S';
return;
}
else if (HIGHBYTE(wValue) == HID_REPORT_DESCRIPTOR_TYPE)
{
g_controlBuf = RHID_ReportDescriptor;
g_controlSize = wLength > sizeof(RHID_ReportDescriptor) ? sizeof(RHID_ReportDescriptor) : wLength;
}
else
{
g_controlSize = 0;
return;
}
}
else if (bRequest == USB_REQUEST_SET_ADDRESS)
{
g_newAddr = wValue;
SendStatusZero();
//USB_DADDR = wValue | USB_DADDR_EF;
g_controlSize = 0;
return;
}
else if (bRequest == USB_REQUEST_SET_CONFIGURATION)
{
SendStatusZero();
g_controlSize = 0;
g_usbState = USB_StateConfigured;
return;
}
else if (bRequest == USB_REQUEST_GET_INTERFACE)
{
g_controlBuf = USB_AlternateSetting;
g_controlSize = wLength > sizeof(USB_AlternateSetting) ? sizeof(USB_AlternateSetting) : wLength;
}
else if (bRequest == USB_REQUEST_CLEAR_FEATURE)
{
SendStatusZero();
g_controlSize = 0;
return;
}
else
{
g_controlSize = 0;
return;
}
}
else
{
// status zero or data
g_controlSize = 0;
}
}
// TX or TX after RX
if (g_controlSize > 0)
{
uint32_t send = g_controlSize > E0_MAX_PACKET_SIZE ? E0_MAX_PACKET_SIZE : g_controlSize;
// fix size
*(uint16_t*)USB_E0_TX_SIZE_ADDR = send;
sup_copy(USB_CONTROL_TX_ADDR, g_controlBuf, send);
g_controlBuf += send;
g_controlSize -= send;
// send
history[historyCntr % HISTORY_MAX].EP_before = USB_EP0R;
USB_EP0R = (USB_EP0R ^ USB_EP0R_STAT_TX) & (USB_EP0R_STAT_TX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_EA);
history[historyCntr % HISTORY_MAX].EP_after = USB_EP0R;
history[historyCntr++ % HISTORY_MAX].cmd = 'I';
}
else
{
if (g_newAddr > 0)
{
USB_DADDR = g_newAddr | USB_DADDR_EF;
g_usbState = USB_StateAddress;
g_newAddr = 0;
}
// force RX
// receive
history[historyCntr % HISTORY_MAX].EP_before = USB_EP0R;
USB_EP0R = (USB_EP0R ^ USB_EP0R_STAT_RX) & (USB_EP0R_STAT_RX | USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND | USB_EP0R_EA);
history[historyCntr % HISTORY_MAX].EP_after = USB_EP0R;
history[historyCntr++ % HISTORY_MAX].cmd = 'O';
}
}
void ResetUSB()
{
// memory for buffers
uint16_t *usbBufs = (uint16_t*)USB_PMA_ADDR;
uint8_t buf[5] = { 4 };
g_cntr++;
buf[1] = g_cntr % 2 ? 1 : 0;
buf[2] = g_cntr % 2 ? 0 : 1;
buf[3] = 3;
// *(uint32_t*)&buf[1] = historyCntr;
g_usbState = USB_StateDefault;
g_newAddr = 0;
memset(usbBufs, 0, 1024); // remove
*usbBufs = 8 * 3;
usbBufs += 2;
*usbBufs = E0_MAX_PACKET_SIZE;
usbBufs += 2;
*usbBufs = 8 * 3 + E0_MAX_PACKET_SIZE;
usbBufs += 2;
*usbBufs = E0_MAX_PACKET_SIZE / 2 << 10; // 8 byte size
usbBufs += 2;
*usbBufs = 8 * 3 + 2 * E0_MAX_PACKET_SIZE;
usbBufs += 2;
*usbBufs = E1_MAX_PACKET_SIZE;
usbBufs += 2;
*usbBufs = 8 * 3 + 2 * E0_MAX_PACKET_SIZE + E1_MAX_PACKET_SIZE;
usbBufs += 2;
*usbBufs = E1_MAX_PACKET_SIZE / 2 << 10; // 8 byte size
usbBufs += 2;
*usbBufs = 8 * 3 + 2 * E0_MAX_PACKET_SIZE + 2 * E1_MAX_PACKET_SIZE;
usbBufs += 2;
*usbBufs = E2_MAX_PACKET_SIZE;
usbBufs += 2;
*usbBufs = 8 * 3 + 2 * E0_MAX_PACKET_SIZE + 2 * E1_MAX_PACKET_SIZE + E2_MAX_PACKET_SIZE;
usbBufs += 2;
*usbBufs = E2_MAX_PACKET_SIZE / 2 << 10; // 8 byte size
*(uint16_t*)USB_E1_TX_SIZE_ADDR = 5;
sup_copy(USB_E1_TX_ADDR, buf, 5);
USB_EP0R = USB_EP0R_EP_TYPE_0 | USB_EP0R_STAT_RX_0 | USB_EP0R_STAT_RX_1;
USB_EP1R = USB_EP1R_EP_TYPE | USB_EP1R_STAT_TX_0 | USB_EP1R_STAT_TX_1 | 1;
USB_EP2R = USB_EP2R_EP_TYPE | 2;
USB_DADDR = USB_DADDR_EF;
g_resets++;
}
void USB_HP_CAN1_TX_IRQHandler(void)
{
}
void USB_LP_CAN1_RX0_IRQHandler(void)
{
if (USB_ISTR & USB_ISTR_RESET)
{
history[historyCntr++ % HISTORY_MAX].cmd = 'R';
// function
ResetUSB();
// clear all interrupt status
USB_ISTR &= ~USB_ISTR_RESET;
// no more interrupts
return;
}
if (USB_ISTR & USB_ISTR_CTR)
{
// control endpoint
if (USB_EP0R & (USB_EP0R_CTR_RX | USB_EP0R_CTR_TX))
ProcessControl();
if (USB_EP1R & (USB_EP1R_CTR_RX | USB_EP1R_CTR_TX))
ProcessData();
}
}
// SysTick interrupt Handler.
void SysTick_Handler(void)
{
g_msTicks++;
}
void sleep(uint32_t amount)
{
uint32_t need = amount;
g_msTicks = 0;
while (g_msTicks < need)
{
// Wait for next SysTick Interrupt
__WFE(); // Power-Down until next Event/Interrupt
}
}
int main(void)
{
uint32_t sum = 0;
uint32_t waiter = 500;
bool minus = true;
SysTick_Config(SystemCoreClock / 1000);
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0 | GPIO_CRL_MODE1 | GPIO_CRL_CNF1);
GPIOA->CRL |= GPIO_CRL_MODE0_1 | GPIO_CRL_CNF0_0 | GPIO_CRL_MODE1_1;
// printf("Hello, world!");
// GPIOA->BSRR = GPIO_BSRR_BR1;
sleep(2000);
GPIOA->BSRR = GPIO_BSRR_BS1;
// NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn,
NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn);
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
RCC->APB1ENR |= RCC_APB1ENR_USBEN;
// reset power down alone
USB_CNTR &= ~USB_CNTR_PDWN;
sleep(100);
// clear interrupt status
USB_ISTR = 0;
// remove force reset
USB_CNTR = USB_CNTR_RESETM;
// sleep(100);
while(1)
{
sleep(waiter);
GPIOA->BSRR = GPIO_BSRR_BS0;
sleep(waiter);
GPIOA->BSRR = GPIO_BSRR_BR0;
sum += 2 * waiter;
if (sum >= 1000)
{
sum = 0;
if (minus)
{
if (waiter <= 20) waiter = 1, minus = false;
else waiter -= 20;
}
else
{
if (waiter >= 500) waiter = 500, minus = true;
else waiter += 20;
}
}
}
}