fix reset bug on bootloader, refactor USB api preparing for SPI USB proxy
parent
c4d10bc447
commit
efca3f7093
|
@ -19,6 +19,11 @@ all: obj/bootstub.$(PROJ_NAME).bin obj/$(PROJ_NAME).bin
|
|||
./tools/dfu-util-$(MACHINE) -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin
|
||||
./tools/dfu-util-$(MACHINE) --reset-stm32 -a 0 -s 0x08000000
|
||||
|
||||
main: obj/$(PROJ_NAME).bin
|
||||
./tools/enter_download_mode.py
|
||||
./tools/dfu-util-$(MACHINE) -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin
|
||||
./tools/dfu-util-$(MACHINE) --reset-stm32 -a 0 -s 0x08000000
|
||||
|
||||
ota: obj/$(PROJ_NAME).bin
|
||||
./tools/ota.py $<
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef
|
||||
#define POST_BOOTLOADER_MAGIC 0xdeadb111
|
||||
extern uint32_t enter_bootloader_mode;
|
||||
extern void *_app_start[];
|
||||
void *g_pfnVectors;
|
||||
|
@ -25,6 +26,12 @@ inline void detect() {
|
|||
}
|
||||
|
||||
inline void early() {
|
||||
// after it's been in the bootloader, things are initted differently, so we reset
|
||||
if (enter_bootloader_mode == POST_BOOTLOADER_MAGIC) {
|
||||
enter_bootloader_mode = 0;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
volatile int i;
|
||||
// if wrong chip, reboot
|
||||
volatile unsigned int id = DBGMCU->IDCODE;
|
||||
|
@ -78,7 +85,7 @@ inline void early() {
|
|||
#endif
|
||||
|
||||
// do enter bootloader
|
||||
enter_bootloader_mode = 0;
|
||||
enter_bootloader_mode = POST_BOOTLOADER_MAGIC;
|
||||
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004));
|
||||
|
||||
// jump to bootloader
|
||||
|
|
115
board/main.c
115
board/main.c
|
@ -147,6 +147,10 @@ void debug_ring_callback(uart_ring *ring) {
|
|||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
if (rcv == 'x') {
|
||||
// normal reset
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,19 +409,13 @@ void set_fan_speed(int fan_speed) {
|
|||
TIM3->CCR3 = fan_speed;
|
||||
}
|
||||
|
||||
void usb_cb_ep1_in(int len) {
|
||||
int usb_cb_ep1_in(uint8_t *usbdata, int len) {
|
||||
CAN_FIFOMailBox_TypeDef reply[4];
|
||||
|
||||
int ilen = 0;
|
||||
while (ilen < min(len/0x10, 4) && pop(&can_rx_q, &reply[ilen])) ilen++;
|
||||
|
||||
/*#ifdef DEBUG
|
||||
puts("FIFO SENDING ");
|
||||
puth(ilen);
|
||||
puts("\n");
|
||||
#endif*/
|
||||
|
||||
USB_WritePacket((void *)reply, ilen*0x10, 1);
|
||||
return ilen*0x10;
|
||||
}
|
||||
|
||||
// send on serial, first byte to select
|
||||
|
@ -478,37 +476,32 @@ void usb_cb_enumeration_complete() {
|
|||
}
|
||||
|
||||
|
||||
#define MAX_RESP_LEN 0x30
|
||||
void usb_cb_control_msg() {
|
||||
uint8_t resp[MAX_RESP_LEN];
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp) {
|
||||
int resp_len = 0;
|
||||
uart_ring *ur = NULL;
|
||||
int i;
|
||||
switch (setup.b.bRequest) {
|
||||
switch (setup->b.bRequest) {
|
||||
case 0xd1:
|
||||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case 0xd2:
|
||||
resp_len = get_health_pkt(resp);
|
||||
USB_WritePacket(resp, resp_len, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case 0xd3:
|
||||
set_fan_speed(setup.b.wValue.w);
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
set_fan_speed(setup->b.wValue.w);
|
||||
break;
|
||||
case 0xd6: // GET_VERSION
|
||||
USB_WritePacket(gitversion, min(sizeof(gitversion), setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
// assert(sizeof(gitversion) <= MAX_RESP_LEN);
|
||||
memcpy(resp, gitversion, sizeof(gitversion));
|
||||
resp_len = sizeof(gitversion);
|
||||
break;
|
||||
case 0xd8: // RESET
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case 0xda: // ESP RESET
|
||||
// pull low for ESP boot mode
|
||||
if (setup.b.wValue.w == 1) {
|
||||
if (setup->b.wValue.w == 1) {
|
||||
GPIOC->ODR &= ~(1 << 5);
|
||||
}
|
||||
|
||||
|
@ -520,48 +513,26 @@ void usb_cb_control_msg() {
|
|||
|
||||
// reset done, no more boot mode
|
||||
// TODO: ESP doesn't seem to listen here
|
||||
if (setup.b.wValue.w == 1) {
|
||||
if (setup->b.wValue.w == 1) {
|
||||
GPIOC->ODR |= (1 << 5);
|
||||
}
|
||||
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case 0xdb: // toggle GMLAN
|
||||
set_can2_mode(setup.b.wValue.w);
|
||||
|
||||
// null reply
|
||||
USB_WritePacket(resp, resp_len, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
set_can2_mode(setup->b.wValue.w);
|
||||
break;
|
||||
case 0xe0: // uart read
|
||||
ur = get_ring_by_number(setup.b.wValue.w);
|
||||
ur = get_ring_by_number(setup->b.wValue.w);
|
||||
if (!ur) break;
|
||||
if (setup.b.bRequest == 0xe0) {
|
||||
// read
|
||||
while (resp_len < min(setup.b.wLength.w, MAX_RESP_LEN) && getc(ur, &resp[resp_len])) {
|
||||
++resp_len;
|
||||
}
|
||||
/*puts("uart read: ");
|
||||
puth(setup.b.wLength.w);
|
||||
puts(" ");
|
||||
puth(resp_len);
|
||||
puts("\n");*/
|
||||
USB_WritePacket(resp, resp_len, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
// read
|
||||
while (resp_len < min(setup->b.wLength.w, MAX_RESP_LEN) && getc(ur, &resp[resp_len])) {
|
||||
++resp_len;
|
||||
}
|
||||
break;
|
||||
case 0xe1: // uart set baud rate
|
||||
ur = get_ring_by_number(setup.b.wValue.w);
|
||||
uart_set_baud(ur->uart, setup.b.wIndex.w);
|
||||
//puth(ur->uart->BRR); puts("\n");
|
||||
|
||||
// null reply
|
||||
USB_WritePacket(resp, resp_len, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
ur = get_ring_by_number(setup->b.wValue.w);
|
||||
uart_set_baud(ur->uart, setup->b.wIndex.w);
|
||||
break;
|
||||
case 0xf0: // k-line wValue pulse on uart2
|
||||
if (setup.b.wValue.w == 1) {
|
||||
if (setup->b.wValue.w == 1) {
|
||||
GPIOC->ODR &= ~(1 << 10);
|
||||
GPIOC->MODER &= ~GPIO_MODER_MODER10_1;
|
||||
GPIOC->MODER |= GPIO_MODER_MODER10_0;
|
||||
|
@ -571,10 +542,9 @@ void usb_cb_control_msg() {
|
|||
GPIOC->MODER |= GPIO_MODER_MODER12_0;
|
||||
}
|
||||
|
||||
//delay((int)setup.b.wValue.w * 8000);
|
||||
for (i = 0; i < 80; i++) {
|
||||
delay(8000);
|
||||
if (setup.b.wValue.w == 1) {
|
||||
if (setup->b.wValue.w == 1) {
|
||||
GPIOC->ODR |= (1 << 10);
|
||||
GPIOC->ODR &= ~(1 << 10);
|
||||
} else {
|
||||
|
@ -583,7 +553,7 @@ void usb_cb_control_msg() {
|
|||
}
|
||||
}
|
||||
|
||||
if (setup.b.wValue.w == 1) {
|
||||
if (setup->b.wValue.w == 1) {
|
||||
GPIOC->MODER &= ~GPIO_MODER_MODER10_0;
|
||||
GPIOC->MODER |= GPIO_MODER_MODER10_1;
|
||||
} else {
|
||||
|
@ -592,18 +562,14 @@ void usb_cb_control_msg() {
|
|||
}
|
||||
|
||||
delay(140 * 9000);
|
||||
//delay((int)setup.b.wIndex.w * 8000);
|
||||
|
||||
// null reply
|
||||
USB_WritePacket(resp, resp_len, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
default:
|
||||
puts("NO HANDLER ");
|
||||
puth(setup.b.bRequest);
|
||||
puth(setup->b.bRequest);
|
||||
puts("\n");
|
||||
break;
|
||||
}
|
||||
return resp_len;
|
||||
}
|
||||
|
||||
|
||||
|
@ -626,7 +592,7 @@ uint8_t spi_buf[SPI_BUF_SIZE];
|
|||
int spi_buf_count = 0;
|
||||
uint8_t spi_tx_buf[0x10];
|
||||
|
||||
/*void SPI1_IRQHandler(void) {
|
||||
void SPI1_IRQHandler(void) {
|
||||
// status is 0x43
|
||||
if (SPI1->SR & SPI_SR_RXNE) {
|
||||
uint8_t dat = SPI1->DR;
|
||||
|
@ -636,25 +602,26 @@ uint8_t spi_tx_buf[0x10];
|
|||
}
|
||||
}
|
||||
|
||||
if (SPI1->SR & SPI_SR_TXE) {
|
||||
/*if (SPI1->SR & SPI_SR_TXE) {
|
||||
// all i send is U U U no matter what
|
||||
//SPI1->DR = 'U';
|
||||
}
|
||||
}*/
|
||||
|
||||
int stat = SPI1->SR;
|
||||
//if (stat & ((~SPI_SR_RXNE) & (~SPI_SR_TXE) & (~SPI_SR_BSY))) {
|
||||
if (stat & ((~SPI_SR_RXNE) & (~SPI_SR_TXE) & (~SPI_SR_BSY))) {
|
||||
puts("SPI status: ");
|
||||
puth(stat);
|
||||
puts("\n");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void DMA2_Stream3_IRQHandler(void) {
|
||||
// ack
|
||||
DMA2->LIFCR = DMA_LIFCR_CTCIF3;
|
||||
|
||||
// reenable interrupt
|
||||
EXTI->IMR |= (1 << 4);
|
||||
//EXTI->IMR |= (1 << 4);
|
||||
//puts("stop\n");
|
||||
}
|
||||
|
||||
|
@ -662,14 +629,22 @@ void EXTI4_IRQHandler(void) {
|
|||
int pr = EXTI->PR;
|
||||
// SPI CS rising
|
||||
if (pr & (1 << 4)) {
|
||||
if (pop(&can_rx_q, spi_tx_buf)) {
|
||||
puts("exti4\n");
|
||||
memset(spi_tx_buf, 0xaa, 0x10);
|
||||
spi_tx_buf[0] = 1;
|
||||
spi_tx_buf[1] = 2;
|
||||
spi_tx_buf[2] = 3;
|
||||
spi_tx_buf[3] = 4;
|
||||
spi_tx_buf[4] = 5;
|
||||
spi_tx_buf[5] = 6;
|
||||
spi_tx_dma(spi_tx_buf, 0x10);
|
||||
/*if (pop(&can_rx_q, spi_tx_buf)) {
|
||||
spi_tx_dma(spi_tx_buf, 0x10);
|
||||
} else {
|
||||
memset(spi_tx_buf, 0, 0x10);
|
||||
spi_tx_dma(spi_tx_buf, 0x10);
|
||||
}
|
||||
//puts("start\n");
|
||||
EXTI->IMR &= ~(1 << 4);
|
||||
}*/
|
||||
//EXTI->IMR &= ~(1 << 4);
|
||||
}
|
||||
EXTI->PR = pr;
|
||||
}
|
||||
|
@ -769,7 +744,7 @@ int main() {
|
|||
|
||||
#ifdef ENABLE_SPI
|
||||
NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
||||
//NVIC_EnableIRQ(SPI1_IRQn);
|
||||
NVIC_EnableIRQ(SPI1_IRQn);
|
||||
|
||||
// setup interrupt on falling edge of SPI enable (on PA4)
|
||||
SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
void spi_init() {
|
||||
puts("SPI init\n");
|
||||
SPI1->CR1 = SPI_CR1_SPE;
|
||||
|
||||
// enable SPI interrupts
|
||||
//SPI1->CR2 = SPI_CR2_RXNEIE | SPI_CR2_ERRIE | SPI_CR2_TXEIE;
|
||||
SPI1->CR2 = SPI_CR2_RXNEIE;
|
||||
}
|
||||
|
||||
void spi_tx_dma(void *addr, int len) {
|
||||
|
|
71
board/usb.h
71
board/usb.h
|
@ -46,10 +46,41 @@ USB_OTG_GlobalTypeDef *USBx = USB_OTG_FS;
|
|||
|
||||
#define USB_OTG_SPEED_FULL 3
|
||||
|
||||
#define MAX_RESP_LEN 0x80
|
||||
uint8_t resp[MAX_RESP_LEN];
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t w;
|
||||
struct BW
|
||||
{
|
||||
uint8_t msb;
|
||||
uint8_t lsb;
|
||||
}
|
||||
bw;
|
||||
}
|
||||
uint16_t_uint8_t;
|
||||
|
||||
|
||||
typedef union _USB_Setup
|
||||
{
|
||||
uint32_t d8[2];
|
||||
|
||||
struct _SetupPkt_Struc
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t_uint8_t wValue;
|
||||
uint16_t_uint8_t wIndex;
|
||||
uint16_t_uint8_t wLength;
|
||||
} b;
|
||||
}
|
||||
USB_Setup_TypeDef;
|
||||
|
||||
// interfaces
|
||||
void usb_cb_enumeration_complete();
|
||||
void usb_cb_control_msg();
|
||||
void usb_cb_ep1_in(int len);
|
||||
int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *usbdata);
|
||||
int usb_cb_ep1_in(uint8_t *usbdata, int len);
|
||||
void usb_cb_ep2_out(uint8_t *usbdata, int len);
|
||||
void usb_cb_ep3_out(uint8_t *usbdata, int len);
|
||||
|
||||
|
@ -108,34 +139,6 @@ uint16_t string_3_desc[] = {
|
|||
'n', 'o', 'n', 'e'
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t w;
|
||||
struct BW
|
||||
{
|
||||
uint8_t msb;
|
||||
uint8_t lsb;
|
||||
}
|
||||
bw;
|
||||
}
|
||||
uint16_t_uint8_t;
|
||||
|
||||
|
||||
typedef union _USB_Setup
|
||||
{
|
||||
uint32_t d8[2];
|
||||
|
||||
struct _SetupPkt_Struc
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t_uint8_t wValue;
|
||||
uint16_t_uint8_t wIndex;
|
||||
uint16_t_uint8_t wLength;
|
||||
} b;
|
||||
}
|
||||
USB_Setup_TypeDef;
|
||||
|
||||
// current packet
|
||||
USB_Setup_TypeDef setup;
|
||||
uint8_t usbdata[0x100];
|
||||
|
@ -224,7 +227,7 @@ char to_hex_char(int a) {
|
|||
|
||||
void usb_setup() {
|
||||
int i;
|
||||
uint8_t resp[0x80];
|
||||
int resp_len;
|
||||
// setup packet is ready
|
||||
switch (setup.b.bRequest) {
|
||||
case USB_REQ_SET_CONFIGURATION:
|
||||
|
@ -332,7 +335,9 @@ void usb_setup() {
|
|||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
default:
|
||||
usb_cb_control_msg();
|
||||
resp_len = usb_cb_control_msg(&setup, resp);
|
||||
USB_WritePacket(resp, min(resp_len, setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,7 +617,7 @@ void usb_irqhandler(void) {
|
|||
puts(" IN PACKET QUEUE\n");
|
||||
#endif
|
||||
// TODO: always assuming max len, can we get the length?
|
||||
usb_cb_ep1_in(0x40);
|
||||
USB_WritePacket((void *)resp, usb_cb_ep1_in(resp, 0x40), 1);
|
||||
}
|
||||
|
||||
// clear interrupts
|
||||
|
|
|
@ -8,6 +8,16 @@
|
|||
#include "tcp_ota.h"
|
||||
#include "driver/spi_interface.h"
|
||||
|
||||
#define min(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
#define max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
static const int pin = 2;
|
||||
static volatile os_timer_t some_timer;
|
||||
|
||||
|
@ -68,6 +78,40 @@ void ICACHE_FLASH_ATTR some_timerfunc(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR tcp_rx_cb(void *arg, char *data, uint16_t len) {
|
||||
if (GPIO_REG_READ(GPIO_OUT_ADDRESS) & (1 << pin)) {
|
||||
// set gpio low
|
||||
gpio_output_set(0, (1 << pin), 0, 0);
|
||||
} else {
|
||||
// set gpio high
|
||||
gpio_output_set((1 << pin), 0, 0, 0);
|
||||
}
|
||||
|
||||
uint32_t value = 0xD3D4D5D6;
|
||||
uint32_t sendData[8] = {0};
|
||||
|
||||
SpiData spiData;
|
||||
|
||||
spiData.cmd = 2;
|
||||
spiData.cmdLen = 0;
|
||||
spiData.addr = NULL;
|
||||
spiData.addrLen = 0;
|
||||
|
||||
// manual CS pin
|
||||
gpio_output_set(0, (1 << 5), 0, 0);
|
||||
memcpy(sendData, data, len);
|
||||
spiData.data = sendData;
|
||||
spiData.dataLen = len;
|
||||
SPIMasterSendData(SpiNum_HSPI, &spiData);
|
||||
|
||||
spiData.data = sendData;
|
||||
spiData.dataLen = 16;
|
||||
SPIMasterRecvData(SpiNum_HSPI, &spiData);
|
||||
gpio_output_set((1 << 5), 0, 0, 0);
|
||||
|
||||
espconn_send(&tcp_conn, sendData, 0x10);
|
||||
}
|
||||
|
||||
int did_start_timer = 0;
|
||||
|
||||
void ICACHE_FLASH_ATTR tcp_connect_cb(void *arg) {
|
||||
|
@ -78,13 +122,14 @@ void ICACHE_FLASH_ATTR tcp_connect_cb(void *arg) {
|
|||
uint16_t len = strlen(message);
|
||||
espconn_send (&tcp_conn, message, len);*/
|
||||
|
||||
if (!did_start_timer) {
|
||||
/*if (!did_start_timer) {
|
||||
// not atomic!
|
||||
did_start_timer = 1;
|
||||
// setup timer (100ms, repeating)
|
||||
os_timer_setfn(&some_timer, (os_timer_func_t *)some_timerfunc, NULL);
|
||||
os_timer_arm(&some_timer, 50, 1);
|
||||
}
|
||||
}*/
|
||||
espconn_regist_recvcb(conn, tcp_rx_cb);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR wifi_init() {
|
||||
|
|
Loading…
Reference in New Issue