fix reset bug on bootloader, refactor USB api preparing for SPI USB proxy

master
Firmware Batman 2017-04-17 18:17:34 -07:00
parent c4d10bc447
commit efca3f7093
6 changed files with 146 additions and 106 deletions

View File

@ -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 $<

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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() {