diff --git a/board/build.mk b/board/build.mk index 6dffbb86..1efa5f43 100644 --- a/board/build.mk +++ b/board/build.mk @@ -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 $< diff --git a/board/early.h b/board/early.h index ce850cbc..04c6ee74 100644 --- a/board/early.h +++ b/board/early.h @@ -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 diff --git a/board/main.c b/board/main.c index 89015010..e2ab0e1d 100644 --- a/board/main.c +++ b/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; diff --git a/board/spi.h b/board/spi.h index 5b2844e9..26717bbe 100644 --- a/board/spi.h +++ b/board/spi.h @@ -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) { diff --git a/board/usb.h b/board/usb.h index 0e48a571..38ab9812 100644 --- a/board/usb.h +++ b/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 diff --git a/boardesp/proxy.c b/boardesp/proxy.c index 842ef234..c617b440 100644 --- a/boardesp/proxy.c +++ b/boardesp/proxy.c @@ -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() {