Merge panda subtree

This commit is contained in:
Vehicle Researcher
2019-07-22 19:15:27 +00:00
78 changed files with 6702 additions and 5856 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ void adc_init(void) {
ADC1->SMPR1 = ADC_SMPR1_SMP12 | ADC_SMPR1_SMP13;
}
uint32_t adc_get(int channel) {
uint32_t adc_get(unsigned int channel) {
// includes length
//ADC1->SQR1 = 0;
+59 -53
View File
@@ -9,11 +9,14 @@ typedef struct {
CAN_FIFOMailBox_TypeDef *elems;
} can_ring;
#define CAN_BUS_RET_FLAG 0x80
#define CAN_BUS_NUM_MASK 0x7F
#define CAN_BUS_RET_FLAG 0x80U
#define CAN_BUS_NUM_MASK 0x7FU
#define BUS_MAX 4
#define BUS_MAX 4U
uint32_t can_send_errs = 0;
uint32_t can_fwd_errs = 0;
uint32_t gmlan_send_errs = 0;
extern int can_live, pending_can_live;
// must reinit after changing these
@@ -63,8 +66,11 @@ bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
enter_critical_section();
if (q->w_ptr != q->r_ptr) {
*elem = q->elems[q->r_ptr];
if ((q->r_ptr + 1) == q->fifo_size) q->r_ptr = 0;
else q->r_ptr += 1;
if ((q->r_ptr + 1U) == q->fifo_size) {
q->r_ptr = 0;
} else {
q->r_ptr += 1U;
}
ret = 1;
}
exit_critical_section();
@@ -72,20 +78,23 @@ bool can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
return ret;
}
int can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
int ret = 0;
bool can_push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
bool ret = false;
uint32_t next_w_ptr;
enter_critical_section();
if ((q->w_ptr + 1) == q->fifo_size) next_w_ptr = 0;
else next_w_ptr = q->w_ptr + 1;
if ((q->w_ptr + 1U) == q->fifo_size) {
next_w_ptr = 0;
} else {
next_w_ptr = q->w_ptr + 1U;
}
if (next_w_ptr != q->r_ptr) {
q->elems[q->w_ptr] = *elem;
q->w_ptr = next_w_ptr;
ret = 1;
ret = true;
}
exit_critical_section();
if (ret == 0) {
if (!ret) {
can_overflow_cnt++;
#ifdef DEBUG
puts("can_push failed!\n");
@@ -130,7 +139,7 @@ void can_set_speed(uint8_t can_number) {
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
if (!llcan_set_speed(CAN, can_speed[bus_number], can_loopback, can_silent & (1 << can_number))) {
if (!llcan_set_speed(CAN, can_speed[bus_number], can_loopback, (unsigned int)(can_silent) & (1U << can_number))) {
puts("CAN init FAILED!!!!!\n");
puth(can_number); puts(" ");
puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n");
@@ -138,7 +147,7 @@ void can_set_speed(uint8_t can_number) {
}
void can_init(uint8_t can_number) {
if (can_number != 0xff) {
if (can_number != 0xffU) {
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
set_can_enable(CAN, 1);
can_set_speed(can_number);
@@ -156,48 +165,45 @@ void can_init_all(void) {
}
}
void can_set_gmlan(int bus) {
if ((bus == -1) || (bus != can_num_lookup[3])) {
// GMLAN OFF
switch (can_num_lookup[3]) {
void can_set_gmlan(uint8_t bus) {
// first, disable GMLAN on prev bus
uint8_t prev_bus = can_num_lookup[3];
if (bus != prev_bus) {
switch (prev_bus) {
case 1:
puts("disable GMLAN on CAN2\n");
set_can_mode(1, 0);
bus_lookup[1] = 1;
can_num_lookup[1] = 1;
can_num_lookup[3] = -1;
can_init(1);
break;
case 2:
puts("disable GMLAN on CAN3\n");
set_can_mode(2, 0);
bus_lookup[2] = 2;
can_num_lookup[2] = 2;
puts("Disable GMLAN on CAN");
puth(prev_bus + 1U);
puts("\n");
set_can_mode(prev_bus, 0);
bus_lookup[prev_bus] = prev_bus;
can_num_lookup[prev_bus] = prev_bus;
can_num_lookup[3] = -1;
can_init(2);
can_init(prev_bus);
break;
default:
puts("GMLAN bus value invalid\n");
// GMLAN was not set on either BUS 1 or 2
break;
}
}
if (bus == 1) {
puts("GMLAN on CAN2\n");
// GMLAN on CAN2
set_can_mode(1, 1);
bus_lookup[1] = 3;
can_num_lookup[1] = -1;
can_num_lookup[3] = 1;
can_init(1);
} else if (bus == 2) {
puts("GMLAN on CAN3\n");
// GMLAN on CAN3
set_can_mode(2, 1);
bus_lookup[2] = 3;
can_num_lookup[2] = -1;
can_num_lookup[3] = 2;
can_init(2);
// now enable GMLAN on the new bus
switch (bus) {
case 1:
case 2:
puts("Enable GMLAN on CAN");
puth(bus + 1U);
puts("\n");
set_can_mode(bus, 1);
bus_lookup[bus] = 3;
can_num_lookup[bus] = -1;
can_num_lookup[3] = bus;
can_init(bus);
break;
default:
puts("GMLAN can only be set on CAN2 or CAN3");
break;
}
}
@@ -232,7 +238,7 @@ void can_sce(CAN_TypeDef *CAN) {
// ***************************** CAN *****************************
void process_can(uint8_t can_number) {
if (can_number != 0xff) {
if (can_number != 0xffU) {
enter_critical_section();
@@ -249,10 +255,10 @@ void process_can(uint8_t can_number) {
if ((CAN->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) {
CAN_FIFOMailBox_TypeDef to_push;
to_push.RIR = CAN->sTxMailBox[0].TIR;
to_push.RDTR = (CAN->sTxMailBox[0].TDTR & 0xFFFF000F) | ((CAN_BUS_RET_FLAG | bus_number) << 4);
to_push.RDTR = (CAN->sTxMailBox[0].TDTR & 0xFFFF000FU) | ((CAN_BUS_RET_FLAG | bus_number) << 4);
to_push.RDLR = CAN->sTxMailBox[0].TDLR;
to_push.RDHR = CAN->sTxMailBox[0].TDHR;
can_push(&can_rx_q, &to_push);
can_send_errs += !can_push(&can_rx_q, &to_push);
}
if ((CAN->TSR & CAN_TSR_TERR0) == CAN_TSR_TERR0) {
@@ -321,7 +327,7 @@ void can_rx(uint8_t can_number) {
safety_rx_hook(&to_push);
set_led(LED_BLUE, 1);
can_push(&can_rx_q, &to_push);
can_send_errs += !can_push(&can_rx_q, &to_push);
// next
CAN->RF0R |= CAN_RF0R_RFOM0;
@@ -346,11 +352,11 @@ void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) {
// add CAN packet to send queue
// bus number isn't passed through
to_push->RDTR &= 0xF;
if ((bus_number == 3) && (can_num_lookup[3] == 0xFF)) {
if ((bus_number == 3U) && (can_num_lookup[3] == 0xFFU)) {
// TODO: why uint8 bro? only int8?
bitbang_gmlan(to_push);
gmlan_send_errs += !bitbang_gmlan(to_push);
} else {
can_push(can_queues[bus_number], to_push);
can_fwd_errs += !can_push(can_queues[bus_number], to_push);
process_can(CAN_NUM_FROM_BUS_NUM(bus_number));
}
}
+1 -1
View File
@@ -3,7 +3,7 @@ void clock_init(void) {
RCC->CR |= RCC_CR_HSEON;
while ((RCC->CR & RCC_CR_HSERDY) == 0);
// divide shit
// divide things
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4;
// 16mhz crystal
+8 -1
View File
@@ -1,4 +1,7 @@
void dac_init() {
void puth(unsigned int i);
void puts(const char *a);
void dac_init(void) {
// no buffers required since we have an opamp
//DAC->CR = DAC_CR_EN1 | DAC_CR_BOFF1 | DAC_CR_EN2 | DAC_CR_BOFF2;
DAC->DHR12R1 = 0;
@@ -11,6 +14,10 @@ void dac_set(int channel, uint32_t value) {
DAC->DHR12R1 = value;
} else if (channel == 1) {
DAC->DHR12R2 = value;
} else {
puts("Failed to set DAC: invalid channel value: ");
puth(value);
puts("\n");
}
}
+33 -26
View File
@@ -41,35 +41,38 @@ int do_bitstuff(char *out, char *in, int in_len) {
}
int append_crc(char *in, int in_len) {
int crc = 0;
unsigned int crc = 0;
for (int i = 0; i < in_len; i++) {
crc <<= 1;
if ((in[i] ^ ((crc >> 15) & 1)) != 0) {
crc = crc ^ 0x4599;
if (((unsigned int)(in[i]) ^ ((crc >> 15) & 1U)) != 0U) {
crc = crc ^ 0x4599U;
}
crc &= 0x7fff;
crc &= 0x7fffU;
}
int in_len_copy = in_len;
for (int i = 14; i >= 0; i--) {
in[in_len] = (crc>>i)&1;
in_len++;
in[in_len_copy] = (crc >> (unsigned int)(i)) & 1U;
in_len_copy++;
}
return in_len;
return in_len_copy;
}
int append_bits(char *in, int in_len, char *app, int app_len) {
int in_len_copy = in_len;
for (int i = 0; i < app_len; i++) {
in[in_len] = app[i];
in_len++;
in[in_len_copy] = app[i];
in_len_copy++;
}
return in_len;
return in_len_copy;
}
int append_int(char *in, int in_len, int val, int val_len) {
for (int i = val_len-1; i >= 0; i--) {
in[in_len] = (val&(1<<i)) != 0;
in_len++;
int in_len_copy = in_len;
for (int i = val_len - 1; i >= 0; i--) {
in[in_len_copy] = ((unsigned int)(val) & (1U << (unsigned int)(i))) != 0U;
in_len_copy++;
}
return in_len;
return in_len_copy;
}
int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) {
@@ -92,7 +95,7 @@ int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) {
// extended identifier
len = append_int(pkt, len, to_bang->RIR >> 21, 11); // Identifier
len = append_int(pkt, len, 3, 2); // SRR+IDE
len = append_int(pkt, len, (to_bang->RIR >> 3) & ((1<<18)-1), 18); // Identifier
len = append_int(pkt, len, (to_bang->RIR >> 3) & ((1U << 18) - 1U), 18); // Identifier
len = append_int(pkt, len, 0, 3); // RTR+r1+r0
} else {
// standard identifier
@@ -168,15 +171,16 @@ void reset_gmlan_switch_timeout(void) {
void set_bitbanged_gmlan(int val) {
if (val != 0) {
GPIOB->ODR |= (1 << 13);
GPIOB->ODR |= (1U << 13);
} else {
GPIOB->ODR &= ~(1 << 13);
GPIOB->ODR &= ~(1U << 13);
}
}
char pkt_stuffed[MAX_BITS_CAN_PACKET];
int gmlan_sending = -1;
int gmlan_sendmax = -1;
bool gmlan_send_ok = true;
int gmlan_silent_count = 0;
int gmlan_fail_count = 0;
@@ -193,7 +197,7 @@ void TIM4_IRQHandler(void) {
} else {
gmlan_silent_count++;
}
} else if (gmlan_silent_count == REQUIRED_SILENT_TIME) {
} else {
bool retry = 0;
// in send loop
if ((gmlan_sending > 0) && // not first bit
@@ -206,6 +210,8 @@ void TIM4_IRQHandler(void) {
} else if ((read == 1) && (gmlan_sending == (gmlan_sendmax - 11))) { // recessive during ACK
puts("GMLAN ERR: didn't recv ACK\n");
retry = 1;
} else {
// do not retry
}
if (retry) {
// reset sender (retry after 7 silent)
@@ -215,6 +221,7 @@ void TIM4_IRQHandler(void) {
gmlan_fail_count++;
if (gmlan_fail_count == MAX_FAIL_COUNT) {
puts("GMLAN ERR: giving up send\n");
gmlan_send_ok = false;
}
} else {
set_bitbanged_gmlan(pkt_stuffed[gmlan_sending]);
@@ -230,9 +237,7 @@ void TIM4_IRQHandler(void) {
}
}
TIM4->SR = 0;
} //bit bang mode
else if (gmlan_alt_mode == GPIO_SWITCH) {
} else if (gmlan_alt_mode == GPIO_SWITCH) {
if ((TIM4->SR & TIM_SR_UIF) && (gmlan_switch_below_timeout != -1)) {
if ((can_timeout_counter == 0) && gmlan_switch_timeout_enable) {
//it has been more than 1 second since timeout was reset; disable timer and restore the GMLAN output
@@ -255,25 +260,27 @@ void TIM4_IRQHandler(void) {
}
}
TIM4->SR = 0;
} //gmlan switch mode
} else {
puts("invalid gmlan_alt_mode\n");
}
}
void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) {
bool bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) {
gmlan_send_ok = true;
gmlan_alt_mode = BITBANG;
// TODO: make failure less silent
if (gmlan_sendmax == -1) {
if (gmlan_sendmax == -1) {
int len = get_bit_message(pkt_stuffed, to_bang);
gmlan_fail_count = 0;
gmlan_silent_count = 0;
gmlan_sending = 0;
gmlan_sendmax = len;
// setup for bitbang loop
set_bitbanged_gmlan(1); // recessive
set_gpio_mode(GPIOB, 13, MODE_OUTPUT);
setup_timer4();
}
return gmlan_send_ok;
}
+41 -28
View File
@@ -1,38 +1,48 @@
// this is needed for 1 mbps support
#define CAN_QUANTA 8
#define CAN_QUANTA 8U
#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1;
#define CAN_SEQ2 1 // roundf(quanta * 0.125f);
#define CAN_PCLK 24000
#define CAN_PCLK 24000U
// 333 = 33.3 kbps
// 5000 = 500 kbps
#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10 / (x))
#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10U / (x))
bool llcan_set_speed(CAN_TypeDef *CAN, uint32_t speed, bool loopback, bool silent) {
#define GET_BUS(msg) (((msg)->RDTR >> 4) & 0xFF)
#define GET_LEN(msg) ((msg)->RDTR & 0xF)
#define GET_ADDR(msg) ((((msg)->RIR & 4) != 0) ? ((msg)->RIR >> 3) : ((msg)->RIR >> 21))
#define GET_BYTE(msg, b) (((int)(b) > 3) ? (((msg)->RDHR >> (8U * ((unsigned int)(b) % 4U))) & 0XFFU) : (((msg)->RDLR >> (8U * (unsigned int)(b))) & 0xFFU))
#define GET_BYTES_04(msg) ((msg)->RDLR)
#define GET_BYTES_48(msg) ((msg)->RDHR)
void puts(const char *a);
bool llcan_set_speed(CAN_TypeDef *CAN_obj, uint32_t speed, bool loopback, bool silent) {
// initialization mode
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
CAN_obj->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
while((CAN_obj->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
// set time quanta from defines
CAN->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
CAN_obj->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) |
(CAN_BTR_TS2_0 * (CAN_SEQ2-1)) |
(can_speed_to_prescaler(speed) - 1);
(can_speed_to_prescaler(speed) - 1U);
// silent loopback mode for debugging
if (loopback) {
CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
CAN_obj->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
}
if (silent) {
CAN->BTR |= CAN_BTR_SILM;
CAN_obj->BTR |= CAN_BTR_SILM;
}
// reset
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM;
// cppcheck-suppress redundantAssignment ; it's a register
CAN_obj->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM;
#define CAN_TIMEOUT 1000000
int tmp = 0;
bool ret = false;
while(((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (tmp < CAN_TIMEOUT)) tmp++;
while(((CAN_obj->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (tmp < CAN_TIMEOUT)) tmp++;
if (tmp < CAN_TIMEOUT) {
ret = true;
}
@@ -40,42 +50,45 @@ bool llcan_set_speed(CAN_TypeDef *CAN, uint32_t speed, bool loopback, bool silen
return ret;
}
void llcan_init(CAN_TypeDef *CAN) {
void llcan_init(CAN_TypeDef *CAN_obj) {
// accept all filter
CAN->FMR |= CAN_FMR_FINIT;
CAN_obj->FMR |= CAN_FMR_FINIT;
// no mask
CAN->sFilterRegister[0].FR1 = 0;
CAN->sFilterRegister[0].FR2 = 0;
CAN->sFilterRegister[14].FR1 = 0;
CAN->sFilterRegister[14].FR2 = 0;
CAN->FA1R |= 1 | (1U << 14);
CAN_obj->sFilterRegister[0].FR1 = 0;
CAN_obj->sFilterRegister[0].FR2 = 0;
CAN_obj->sFilterRegister[14].FR1 = 0;
CAN_obj->sFilterRegister[14].FR2 = 0;
CAN_obj->FA1R |= 1U | (1U << 14);
CAN->FMR &= ~(CAN_FMR_FINIT);
CAN_obj->FMR &= ~(CAN_FMR_FINIT);
// enable certain CAN interrupts
CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE;
CAN_obj->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE;
if (CAN == CAN1) {
if (CAN_obj == CAN1) {
NVIC_EnableIRQ(CAN1_TX_IRQn);
NVIC_EnableIRQ(CAN1_RX0_IRQn);
NVIC_EnableIRQ(CAN1_SCE_IRQn);
} else if (CAN == CAN2) {
} else if (CAN_obj == CAN2) {
NVIC_EnableIRQ(CAN2_TX_IRQn);
NVIC_EnableIRQ(CAN2_RX0_IRQn);
NVIC_EnableIRQ(CAN2_SCE_IRQn);
#ifdef CAN3
} else if (CAN == CAN3) {
} else if (CAN_obj == CAN3) {
NVIC_EnableIRQ(CAN3_TX_IRQn);
NVIC_EnableIRQ(CAN3_RX0_IRQn);
NVIC_EnableIRQ(CAN3_SCE_IRQn);
#endif
} else {
puts("Invalid CAN: initialization failed\n");
}
}
void llcan_clear_send(CAN_TypeDef *CAN) {
CAN->TSR |= CAN_TSR_ABRQ0;
CAN->MSR &= ~(CAN_MSR_ERRI);
CAN->MSR = CAN->MSR;
void llcan_clear_send(CAN_TypeDef *CAN_obj) {
CAN_obj->TSR |= CAN_TSR_ABRQ0;
CAN_obj->MSR &= ~(CAN_MSR_ERRI);
// cppcheck-suppress selfAssignment ; needed to clear the register
CAN_obj->MSR = CAN_obj->MSR;
}
+15 -15
View File
@@ -7,38 +7,38 @@
#define PULL_UP 1
#define PULL_DOWN 2
void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode) {
void set_gpio_mode(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) {
uint32_t tmp = GPIO->MODER;
tmp &= ~(3 << (pin*2));
tmp |= (mode << (pin*2));
tmp &= ~(3U << (pin * 2U));
tmp |= (mode << (pin * 2U));
GPIO->MODER = tmp;
}
void set_gpio_output(GPIO_TypeDef *GPIO, int pin, bool enabled) {
void set_gpio_output(GPIO_TypeDef *GPIO, unsigned int pin, bool enabled) {
if (enabled) {
GPIO->ODR |= (1 << pin);
GPIO->ODR |= (1U << pin);
} else {
GPIO->ODR &= ~(1 << pin);
GPIO->ODR &= ~(1U << pin);
}
set_gpio_mode(GPIO, pin, MODE_OUTPUT);
}
void set_gpio_alternate(GPIO_TypeDef *GPIO, int pin, int mode) {
uint32_t tmp = GPIO->AFR[pin>>3];
tmp &= ~(0xF << ((pin&7)*4));
tmp |= mode << ((pin&7)*4);
GPIO->AFR[pin>>3] = tmp;
void set_gpio_alternate(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) {
uint32_t tmp = GPIO->AFR[pin >> 3U];
tmp &= ~(0xFU << ((pin & 7U) * 4U));
tmp |= mode << ((pin & 7U) * 4U);
GPIO->AFR[pin >> 3] = tmp;
set_gpio_mode(GPIO, pin, MODE_ALTERNATE);
}
void set_gpio_pullup(GPIO_TypeDef *GPIO, int pin, int mode) {
void set_gpio_pullup(GPIO_TypeDef *GPIO, unsigned int pin, unsigned int mode) {
uint32_t tmp = GPIO->PUPDR;
tmp &= ~(3 << (pin*2));
tmp |= (mode << (pin*2));
tmp &= ~(3U << (pin * 2U));
tmp |= (mode << (pin * 2U));
GPIO->PUPDR = tmp;
}
int get_gpio_input(GPIO_TypeDef *GPIO, int pin) {
int get_gpio_input(GPIO_TypeDef *GPIO, unsigned int pin) {
return (GPIO->IDR & (1U << pin)) == (1U << pin);
}
+5 -5
View File
@@ -28,8 +28,8 @@ void spi_init(void) {
// setup interrupt on falling edge of SPI enable (on PA4)
SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA;
EXTI->IMR |= (1 << 4);
EXTI->FTSR |= (1 << 4);
EXTI->IMR |= (1U << 4);
EXTI->FTSR |= (1U << 4);
NVIC_EnableIRQ(EXTI4_IRQn);
}
@@ -85,7 +85,7 @@ uint8_t spi_tx_buf[0x44];
// SPI RX
void DMA2_Stream2_IRQHandler(void) {
int *resp_len = (int*)spi_tx_buf;
memset(spi_tx_buf, 0xaa, 0x44);
(void)memset(spi_tx_buf, 0xaa, 0x44);
*resp_len = spi_cb_rx(spi_buf, 0x14, spi_tx_buf+4);
#ifdef DEBUG_SPI
puts("SPI write: ");
@@ -113,12 +113,12 @@ void DMA2_Stream3_IRQHandler(void) {
}
void EXTI4_IRQHandler(void) {
volatile int pr = EXTI->PR & (1 << 4);
volatile unsigned int pr = EXTI->PR & (1U << 4);
#ifdef DEBUG_SPI
puts("exti4\n");
#endif
// SPI CS falling
if ((pr & (1 << 4)) != 0) {
if ((pr & (1U << 4)) != 0U) {
spi_total_count = 0;
spi_rx_dma(spi_buf, 0x14);
}
+31 -30
View File
@@ -1,6 +1,6 @@
// IRQs: USART1, USART2, USART3, UART5
#define FIFO_SIZE 0x400
#define FIFO_SIZE 0x400U
typedef struct uart_ring {
volatile uint16_t w_ptr_tx;
volatile uint16_t r_ptr_tx;
@@ -81,7 +81,7 @@ void uart_ring_process(uart_ring *q) {
if (q->w_ptr_tx != q->r_ptr_tx) {
if ((sr & USART_SR_TXE) != 0) {
q->uart->DR = q->elems_tx[q->r_ptr_tx];
q->r_ptr_tx = (q->r_ptr_tx + 1) % FIFO_SIZE;
q->r_ptr_tx = (q->r_ptr_tx + 1U) % FIFO_SIZE;
}
// there could be more to send
q->uart->CR1 |= USART_CR1_TXEIE;
@@ -93,7 +93,7 @@ void uart_ring_process(uart_ring *q) {
if ((sr & USART_SR_RXNE) || (sr & USART_SR_ORE)) {
uint8_t c = q->uart->DR; // TODO: can drop packets
if (q != &esp_ring) {
uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
uint16_t next_w_ptr = (q->w_ptr_rx + 1U) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = c;
q->w_ptr_rx = next_w_ptr;
@@ -124,7 +124,7 @@ bool getc(uart_ring *q, char *elem) {
enter_critical_section();
if (q->w_ptr_rx != q->r_ptr_rx) {
if (elem != NULL) *elem = q->elems_rx[q->r_ptr_rx];
q->r_ptr_rx = (q->r_ptr_rx + 1) % FIFO_SIZE;
q->r_ptr_rx = (q->r_ptr_rx + 1U) % FIFO_SIZE;
ret = true;
}
exit_critical_section();
@@ -137,7 +137,7 @@ bool injectc(uart_ring *q, char elem) {
uint16_t next_w_ptr;
enter_critical_section();
next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
next_w_ptr = (q->w_ptr_rx + 1U) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = elem;
q->w_ptr_rx = next_w_ptr;
@@ -153,7 +153,7 @@ bool putc(uart_ring *q, char elem) {
uint16_t next_w_ptr;
enter_critical_section();
next_w_ptr = (q->w_ptr_tx + 1) % FIFO_SIZE;
next_w_ptr = (q->w_ptr_tx + 1U) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_tx) {
q->elems_tx[q->w_ptr_tx] = elem;
q->w_ptr_tx = next_w_ptr;
@@ -195,17 +195,17 @@ void clear_uart_buff(uart_ring *q) {
// ***************************** start UART code *****************************
#define __DIV(_PCLK_, _BAUD_) (((_PCLK_) * 25) / (4 * (_BAUD_)))
#define __DIVMANT(_PCLK_, _BAUD_) (__DIV((_PCLK_), (_BAUD_)) / 100)
#define __DIVFRAQ(_PCLK_, _BAUD_) ((((__DIV((_PCLK_), (_BAUD_)) - (__DIVMANT((_PCLK_), (_BAUD_)) * 100)) * 16) + 50) / 100)
#define __USART_BRR(_PCLK_, _BAUD_) ((__DIVMANT((_PCLK_), (_BAUD_)) << 4) | (__DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0F))
#define __DIV(_PCLK_, _BAUD_) (((_PCLK_) * 25U) / (4U * (_BAUD_)))
#define __DIVMANT(_PCLK_, _BAUD_) (__DIV((_PCLK_), (_BAUD_)) / 100U)
#define __DIVFRAQ(_PCLK_, _BAUD_) ((((__DIV((_PCLK_), (_BAUD_)) - (__DIVMANT((_PCLK_), (_BAUD_)) * 100U)) * 16U) + 50U) / 100U)
#define __USART_BRR(_PCLK_, _BAUD_) ((__DIVMANT((_PCLK_), (_BAUD_)) << 4) | (__DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0FU))
void uart_set_baud(USART_TypeDef *u, int baud) {
void uart_set_baud(USART_TypeDef *u, unsigned int baud) {
if (u == USART1) {
// USART1 is on APB2
u->BRR = __USART_BRR(48000000, baud);
u->BRR = __USART_BRR(48000000U, baud);
} else {
u->BRR = __USART_BRR(24000000, baud);
u->BRR = __USART_BRR(24000000U, baud);
}
}
@@ -226,7 +226,7 @@ void uart_dma_drain(void) {
unsigned int i;
for (i = 0; i < (USART1_DMA_LEN - DMA2_Stream5->NDTR); i++) {
char c = usart1_dma[i];
uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
uint16_t next_w_ptr = (q->w_ptr_rx + 1U) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = c;
q->w_ptr_rx = next_w_ptr;
@@ -289,6 +289,8 @@ void uart_init(USART_TypeDef *u, int baud) {
NVIC_EnableIRQ(USART3_IRQn);
} else if (u == UART5) {
NVIC_EnableIRQ(UART5_IRQn);
} else {
// USART type undefined, skip
}
}
@@ -302,49 +304,48 @@ void putch(const char a) {
//putc(&debug_ring, a);
} else {
injectc(&debug_ring, a);
// misra-c2012-17.7: serial debug function, ok to ignore output
(void)injectc(&debug_ring, a);
}
}
void puts(const char *a) {
for (;*a;a++) {
if (*a == '\n') putch('\r');
putch(*a);
for (const char *in = a; *in; in++) {
if (*in == '\n') putch('\r');
putch(*in);
}
}
void putui(uint32_t i) {
uint32_t i_copy = i;
char str[11];
uint8_t idx = 10;
str[idx] = '\0';
idx--;
do {
str[idx] = (i % 10) + 0x30;
str[idx] = (i_copy % 10U) + 0x30U;
idx--;
i /= 10;
} while (i != 0);
puts(str + idx + 1);
i_copy /= 10;
} while (i_copy != 0U);
puts(str + idx + 1U);
}
void puth(unsigned int i) {
int pos;
char c[] = "0123456789abcdef";
for (pos = 28; pos != -4; pos -= 4) {
putch(c[(i >> pos) & 0xF]);
for (int pos = 28; pos != -4; pos -= 4) {
putch(c[(i >> (unsigned int)(pos)) & 0xFU]);
}
}
void puth2(unsigned int i) {
int pos;
char c[] = "0123456789abcdef";
for (pos = 4; pos != -4; pos -= 4) {
putch(c[(i >> pos) & 0xF]);
for (int pos = 4; pos != -4; pos -= 4) {
putch(c[(i >> (unsigned int)(pos)) & 0xFU]);
}
}
void hexdump(const void *a, int l) {
int i;
for (i=0;i<l;i++) {
for (int i=0; i < l; i++) {
if ((i != 0) && ((i & 0xf) == 0)) puts("\n");
puth2(((const unsigned char*)a)[i]);
puts(" ");
+58 -54
View File
@@ -25,9 +25,9 @@ USB_Setup_TypeDef;
void usb_init(void);
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, bool hardwired);
int usb_cb_ep1_in(uint8_t *usbdata, int len, bool hardwired);
void usb_cb_ep2_out(uint8_t *usbdata, int len, bool hardwired);
void usb_cb_ep3_out(uint8_t *usbdata, int len, bool hardwired);
int usb_cb_ep1_in(void *usbdata, int len, bool hardwired);
void usb_cb_ep2_out(void *usbdata, int len, bool hardwired);
void usb_cb_ep3_out(void *usbdata, int len, bool hardwired);
void usb_cb_enumeration_complete(void);
// **** supporting defines ****
@@ -96,7 +96,7 @@ USB_OTG_GlobalTypeDef *USBx = USB_OTG_FS;
#define STS_SETUP_COMP 4
#define STS_SETUP_UPDT 6
#define USBD_FS_TRDT_VALUE 5
#define USBD_FS_TRDT_VALUE 5U
#define USB_OTG_SPEED_FULL 3
@@ -125,7 +125,7 @@ uint8_t resp[MAX_RESP_LEN];
// Convert machine byte order to USB byte order
#define TOUSBORDER(num)\
((num) & 0xFF), (((num) >> 8) & 0xFF)
((num) & 0xFFU), (((num) >> 8) & 0xFFU)
// take in string length and return the first 2 bytes of a string descriptor
#define STRING_DESCRIPTOR_HEADER(size)\
@@ -158,7 +158,7 @@ uint8_t device_qualifier[] = {
uint8_t configuration_desc[] = {
DSCR_CONFIG_LEN, USB_DESC_TYPE_CONFIGURATION, // Length, Type,
TOUSBORDER(0x0045), // Total Len (uint16)
TOUSBORDER(0x0045U), // Total Len (uint16)
0x01, 0x01, STRING_OFFSET_ICONFIGURATION, // Num Interface, Config Value, Configuration
0xc0, 0x32, // Attributes, Max Power
// interface 0 ALT 0
@@ -169,17 +169,17 @@ uint8_t configuration_desc[] = {
// endpoint 1, read CAN
DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type
ENDPOINT_RCV | 1, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type
TOUSBORDER(0x0040), // Max Packet (0x0040)
TOUSBORDER(0x0040U), // Max Packet (0x0040)
0x00, // Polling Interval (NA)
// endpoint 2, send serial
DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type
ENDPOINT_SND | 2, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type
TOUSBORDER(0x0040), // Max Packet (0x0040)
TOUSBORDER(0x0040U), // Max Packet (0x0040)
0x00, // Polling Interval
// endpoint 3, send CAN
DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type
ENDPOINT_SND | 3, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type
TOUSBORDER(0x0040), // Max Packet (0x0040)
TOUSBORDER(0x0040U), // Max Packet (0x0040)
0x00, // Polling Interval
// interface 0 ALT 1
DSCR_INTERFACE_LEN, USB_DESC_TYPE_INTERFACE, // Length, Type
@@ -189,17 +189,17 @@ uint8_t configuration_desc[] = {
// endpoint 1, read CAN
DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type
ENDPOINT_RCV | 1, ENDPOINT_TYPE_INT, // Endpoint Num/Direction, Type
TOUSBORDER(0x0040), // Max Packet (0x0040)
TOUSBORDER(0x0040U), // Max Packet (0x0040)
0x05, // Polling Interval (5 frames)
// endpoint 2, send serial
DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type
ENDPOINT_SND | 2, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type
TOUSBORDER(0x0040), // Max Packet (0x0040)
TOUSBORDER(0x0040U), // Max Packet (0x0040)
0x00, // Polling Interval
// endpoint 3, send CAN
DSCR_ENDPOINT_LEN, USB_DESC_TYPE_ENDPOINT, // Length, Type
ENDPOINT_SND | 3, ENDPOINT_TYPE_BULK, // Endpoint Num/Direction, Type
TOUSBORDER(0x0040), // Max Packet (0x0040)
TOUSBORDER(0x0040U), // Max Packet (0x0040)
0x00, // Polling Interval
};
@@ -394,36 +394,36 @@ int current_int0_alt_setting = 0;
// packet read and write
void *USB_ReadPacket(void *dest, uint16_t len) {
uint32_t i=0;
uint32_t count32b = (len + 3) / 4;
uint32_t *dest_copy = (uint32_t *)dest;
uint32_t count32b = (len + 3U) / 4U;
for ( i = 0; i < count32b; i++) {
// packed?
*(__attribute__((__packed__)) uint32_t *)dest = USBx_DFIFO(0);
dest += 4;
for (uint32_t i = 0; i < count32b; i++) {
*dest_copy = USBx_DFIFO(0);
dest_copy++;
}
return ((void *)dest);
return ((void *)dest_copy);
}
void USB_WritePacket(const uint8_t *src, uint16_t len, uint32_t ep) {
void USB_WritePacket(const void *src, uint16_t len, uint32_t ep) {
#ifdef DEBUG_USB
puts("writing ");
hexdump(src, len);
#endif
uint8_t numpacket = (len+(MAX_RESP_LEN-1))/MAX_RESP_LEN;
uint32_t count32b = 0, i = 0;
count32b = (len + 3) / 4;
uint8_t numpacket = (len + (MAX_RESP_LEN - 1U)) / MAX_RESP_LEN;
uint32_t count32b = 0;
count32b = (len + 3U) / 4U;
// bullshit
// TODO: revisit this
USBx_INEP(ep)->DIEPTSIZ = ((numpacket << 19) & USB_OTG_DIEPTSIZ_PKTCNT) |
(len & USB_OTG_DIEPTSIZ_XFRSIZ);
USBx_INEP(ep)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
// load the FIFO
for (i = 0; i < count32b; i++) {
USBx_DFIFO(ep) = *((__attribute__((__packed__)) uint32_t *)src);
src += 4;
const uint32_t *src_copy = (const uint32_t *)src;
for (uint32_t i = 0; i < count32b; i++) {
USBx_DFIFO(ep) = *src_copy;
src_copy++;
}
}
@@ -471,10 +471,10 @@ void usb_reset(void) {
USBx->GRXFSIZ = 0x40;
// 0x100 to offset past GRXFSIZ
USBx->DIEPTXF0_HNPTXFSIZ = (0x40 << 16) | 0x40;
USBx->DIEPTXF0_HNPTXFSIZ = (0x40U << 16) | 0x40U;
// EP1, massive
USBx->DIEPTXF[0] = (0x40 << 16) | 0x80;
USBx->DIEPTXF[0] = (0x40U << 16) | 0x80U;
// flush TX fifo
USBx->GRSTCTL = USB_OTG_GRSTCTL_TXFFLSH | USB_OTG_GRSTCTL_TXFNUM_4;
@@ -487,7 +487,7 @@ void usb_reset(void) {
USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
// ready to receive setup packets
USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) | (3 * 8);
USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)) | (3U << 3);
}
char to_hex_char(int a) {
@@ -506,17 +506,17 @@ void usb_setup(void) {
switch (setup.b.bRequest) {
case USB_REQ_SET_CONFIGURATION:
// enable other endpoints, has to be here?
USBx_INEP(1)->DIEPCTL = (0x40 & USB_OTG_DIEPCTL_MPSIZ) | (2 << 18) | (1 << 22) |
USBx_INEP(1)->DIEPCTL = (0x40U & USB_OTG_DIEPCTL_MPSIZ) | (2U << 18) | (1U << 22) |
USB_OTG_DIEPCTL_SD0PID_SEVNFRM | USB_OTG_DIEPCTL_USBAEP;
USBx_INEP(1)->DIEPINT = 0xFF;
USBx_OUTEP(2)->DOEPTSIZ = (1 << 19) | 0x40;
USBx_OUTEP(2)->DOEPCTL = (0x40 & USB_OTG_DOEPCTL_MPSIZ) | (2 << 18) |
USBx_OUTEP(2)->DOEPTSIZ = (1U << 19) | 0x40U;
USBx_OUTEP(2)->DOEPCTL = (0x40U & USB_OTG_DOEPCTL_MPSIZ) | (2U << 18) |
USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP;
USBx_OUTEP(2)->DOEPINT = 0xFF;
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
USBx_OUTEP(3)->DOEPCTL = (0x40 & USB_OTG_DOEPCTL_MPSIZ) | (2 << 18) |
USBx_OUTEP(3)->DOEPTSIZ = (1U << 19) | 0x40U;
USBx_OUTEP(3)->DOEPCTL = (0x40U & USB_OTG_DOEPCTL_MPSIZ) | (2U << 18) |
USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP;
USBx_OUTEP(3)->DOEPINT = 0xFF;
@@ -529,7 +529,7 @@ void usb_setup(void) {
break;
case USB_REQ_SET_ADDRESS:
// set now?
USBx_DEVICE->DCFG |= ((setup.b.wValue.w & 0x7f) << 4);
USBx_DEVICE->DCFG |= ((setup.b.wValue.w & 0x7fU) << 4);
#ifdef DEBUG_USB
puts(" set address\n");
@@ -575,16 +575,16 @@ void usb_setup(void) {
break;
case STRING_OFFSET_ISERIAL:
#ifdef UID_BASE
resp[0] = 0x02 + 12*4;
resp[0] = 0x02 + (12 * 4);
resp[1] = 0x03;
// 96 bits = 12 bytes
for (int i = 0; i < 12; i++){
uint8_t cc = ((uint8_t *)UID_BASE)[i];
resp[2 + i*4 + 0] = to_hex_char((cc>>4)&0xF);
resp[2 + i*4 + 1] = '\0';
resp[2 + i*4 + 2] = to_hex_char((cc>>0)&0xF);
resp[2 + i*4 + 3] = '\0';
resp[2 + (i * 4) + 0] = to_hex_char((cc >> 4) & 0xFU);
resp[2 + (i * 4) + 1] = '\0';
resp[2 + (i * 4) + 2] = to_hex_char((cc >> 0) & 0xFU);
resp[2 + (i * 4) + 3] = '\0';
}
USB_WritePacket(resp, MIN(resp[0], setup.b.wLength.w), 0);
@@ -683,7 +683,7 @@ void usb_init(void) {
USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_FDMOD;
// slowest timings
USBx->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
USBx->GUSBCFG |= ((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
// power up the PHY
#ifdef STM32F4
@@ -732,7 +732,6 @@ void usb_init(void) {
USBx->GAHBCFG = USB_OTG_GAHBCFG_GINT;
// DCTL startup value is 2 on new chip, 0 on old chip
// THIS IS FUCKING BULLSHIT
USBx_DEVICE->DCTL = 0;
// enable the IRQ
@@ -793,21 +792,22 @@ void usb_irqhandler(void) {
if ((gintsts & USB_OTG_GINTSTS_RXFLVL) != 0) {
// 1. Read the Receive status pop register
volatile unsigned int rxst = USBx->GRXSTSP;
int status = (rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17;
#ifdef DEBUG_USB
puts(" RX FIFO:");
puth(rxst);
puts(" status: ");
puth((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17);
puth(status);
puts(" len: ");
puth((rxst & USB_OTG_GRXSTSP_BCNT) >> 4);
puts("\n");
#endif
if (((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) {
if (status == STS_DATA_UPDT) {
int endpoint = (rxst & USB_OTG_GRXSTSP_EPNUM);
int len = (rxst & USB_OTG_GRXSTSP_BCNT) >> 4;
USB_ReadPacket(&usbdata, len);
(void)USB_ReadPacket(&usbdata, len);
#ifdef DEBUG_USB
puts(" data ");
puth(len);
@@ -822,13 +822,15 @@ void usb_irqhandler(void) {
if (endpoint == 3) {
usb_cb_ep3_out(usbdata, len, 1);
}
} else if (((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) {
USB_ReadPacket(&setup, 8);
} else if (status == STS_SETUP_UPDT) {
(void)USB_ReadPacket(&setup, 8);
#ifdef DEBUG_USB
puts(" setup ");
hexdump(&setup, 8);
puts("\n");
#endif
} else {
// status is neither STS_DATA_UPDT or STS_SETUP_UPDT, skip
}
}
@@ -882,7 +884,7 @@ void usb_irqhandler(void) {
#ifdef DEBUG_USB
puts(" OUT2 PACKET XFRC\n");
#endif
USBx_OUTEP(2)->DOEPTSIZ = (1 << 19) | 0x40;
USBx_OUTEP(2)->DOEPTSIZ = (1U << 19) | 0x40U;
USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
}
@@ -890,24 +892,26 @@ void usb_irqhandler(void) {
#ifdef DEBUG_USB
puts(" OUT3 PACKET XFRC\n");
#endif
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
USBx_OUTEP(3)->DOEPTSIZ = (1U << 19) | 0x40U;
USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
} else if ((USBx_OUTEP(3)->DOEPINT & 0x2000) != 0) {
#ifdef DEBUG_USB
puts(" OUT3 PACKET WTF\n");
#endif
// if NAK was set trigger this, unknown interrupt
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
USBx_OUTEP(3)->DOEPTSIZ = (1U << 19) | 0x40U;
USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
} else if ((USBx_OUTEP(3)->DOEPINT) != 0) {
puts("OUTEP3 error ");
puth(USBx_OUTEP(3)->DOEPINT);
puts("\n");
} else {
// USBx_OUTEP(3)->DOEPINT is 0, ok to skip
}
if ((USBx_OUTEP(0)->DOEPINT & USB_OTG_DIEPINT_XFRC) != 0) {
// ready for next packet
USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) | (1 * 8);
USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)) | (1U << 3);
}
// respond to setup packets
@@ -978,12 +982,12 @@ void usb_irqhandler(void) {
puts(" IN PACKET QUEUE\n");
#endif
if ((ep0_txlen != 0) && ((USBx_INEP(0)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40)) {
if ((ep0_txlen != 0U) && ((USBx_INEP(0)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40U)) {
uint16_t len = MIN(ep0_txlen, 0x40);
USB_WritePacket(ep0_txdata, len, 0);
ep0_txdata += len;
ep0_txlen -= len;
if (ep0_txlen == 0) {
if (ep0_txlen == 0U) {
ep0_txdata = NULL;
USBx_DEVICE->DIEPEMPMSK &= ~1;
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;