diff --git a/board/main.c b/board/main.c index caa0246..2066d0d 100644 --- a/board/main.c +++ b/board/main.c @@ -410,7 +410,7 @@ void set_fan_speed(int fan_speed) { } int usb_cb_ep1_in(uint8_t *usbdata, int len) { - CAN_FIFOMailBox_TypeDef reply[4]; + CAN_FIFOMailBox_TypeDef *reply = (CAN_FIFOMailBox_TypeDef *)usbdata;; int ilen = 0; while (ilen < min(len/0x10, 4) && pop(&can_rx_q, &reply[ilen])) ilen++; @@ -592,23 +592,37 @@ void ADC_IRQHandler(void) { uint8_t spi_buf[SPI_BUF_SIZE]; int spi_buf_count = 0; int spi_total_count = 0; -uint8_t spi_tx_buf[0x40]; +uint8_t spi_tx_buf[0x44]; void handle_spi(uint8_t *data, int len) { - 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); - - // last thing - hexdump(data, len); + memset(spi_tx_buf, 0xaa, 0x44); + // data[0] = endpoint + // data[2] = length + // data[4:] = data + int *resp_len = (int*)spi_tx_buf; + *resp_len = 0; + switch (data[0]) { + case 0: + // control transfer + *resp_len = usb_cb_control_msg(data+4, spi_tx_buf+4); + break; + case 1: + // ep 1, read + *resp_len = usb_cb_ep1_in(spi_tx_buf+4, 0x40); + break; + case 2: + // ep 2, send serial + usb_cb_ep2_out(data+4, data[2]); + break; + case 3: + // ep 3, send CAN + usb_cb_ep3_out(data+4, data[2]); + break; + } + spi_tx_dma(spi_tx_buf, 0x44); } -void SPI1_IRQHandler(void) { +/*void SPI1_IRQHandler(void) { // status is 0x43 if (SPI1->SR & SPI_SR_RXNE) { uint8_t dat = SPI1->DR; @@ -633,7 +647,7 @@ void SPI1_IRQHandler(void) { puth(stat); puts("\n"); } -} +}*/ // SPI RX void DMA2_Stream2_IRQHandler(void) { @@ -654,6 +668,7 @@ void DMA2_Stream2_IRQHandler(void) { void DMA2_Stream3_IRQHandler(void) { // ack DMA2->LIFCR = DMA_LIFCR_CTCIF3; + //puts("spi tx done\n"); // reenable interrupt //EXTI->IMR |= (1 << 4); @@ -666,7 +681,7 @@ void EXTI4_IRQHandler(void) { if (pr & (1 << 4)) { spi_total_count = 0; spi_rx_dma(spi_buf, 0x14); - puts("exti4\n"); + //puts("exti4\n"); } EXTI->PR = pr; } diff --git a/boardesp/proxy.c b/boardesp/proxy.c index 8bf60d7..b64e324 100644 --- a/boardesp/proxy.c +++ b/boardesp/proxy.c @@ -26,6 +26,9 @@ struct espconn tcp_conn; // TCP specific protocol structure. esp_tcp tcp_proto; +uint32_t sendData[0x14] = {0}; +uint32_t recvData[0x40] = {0}; + 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 @@ -38,9 +41,6 @@ static void ICACHE_FLASH_ATTR tcp_rx_cb(void *arg, char *data, uint16_t len) { // nothing too big if (len > 0x14) return; - uint32_t value = 0xD3D4D5D6; - uint32_t sendData[0x40] = {0}; - SpiData spiData; spiData.cmd = 2; @@ -50,17 +50,35 @@ static void ICACHE_FLASH_ATTR tcp_rx_cb(void *arg, char *data, uint16_t len) { // manual CS pin gpio_output_set(0, (1 << 5), 0, 0); + memset(sendData, 0xCC, 0x14); + + // send request memcpy(((void*)sendData), data, len); spiData.data = sendData; spiData.dataLen = 0x14; SPIMasterSendData(SpiNum_HSPI, &spiData); - spiData.data = sendData; - spiData.dataLen = 0x44; + // give the ST time to be ready, 1 ms + // TODO: how can we do this better? + os_delay_us(1000); + + // blank out recvData + memset(recvData, 0xBB, 0x44); + + // receive the length + spiData.data = recvData; + spiData.dataLen = 4; SPIMasterRecvData(SpiNum_HSPI, &spiData); + int length = recvData[0]; + + // got response, 0x40 works, 0x44 does not + spiData.data = recvData+1; + spiData.dataLen = 0x40; + SPIMasterRecvData(SpiNum_HSPI, &spiData); + gpio_output_set((1 << 5), 0, 0, 0); - espconn_send(&tcp_conn, sendData, 0x40); + espconn_send(&tcp_conn, recvData, 0x44); } void ICACHE_FLASH_ATTR tcp_connect_cb(void *arg) { diff --git a/lib/panda.py b/lib/panda.py index 593610a..ac8463f 100644 --- a/lib/panda.py +++ b/lib/panda.py @@ -5,6 +5,11 @@ import socket import usb1 from usb1 import USBErrorIO, USBErrorOverflow +try: + from hexdump import hexdump +except: + pass + # stupid tunneling of USB over wifi and SPI class WifiHandle(object): def __init__(self, ip="192.168.0.10", port=1337): @@ -12,31 +17,31 @@ class WifiHandle(object): def __recv(self): ret = self.sock.recv(0x44) - from hexdump import hexdump - hexdump(ret) - return ret + length = struct.unpack("I", ret[0:4])[0] + return ret[4:4+length] def controlWrite(self, request_type, request, value, index, data, timeout=0): - # ignore data, panda doesn't use it - return self.controlRead(self, request_type, request, value, index, 0, timeout) + # ignore data in reply, panda doesn't use it + return self.controlRead(request_type, request, value, index, 0, timeout) def controlRead(self, request_type, request, value, index, length, timeout=0): - self.sock.send(struct.pack("IBBHHH", 0, request_type, request, value, index, length)) + self.sock.send(struct.pack("HHBBHHH", 0, 0, request_type, request, value, index, length)) return self.__recv() def bulkWrite(self, endpoint, data, timeout=0): assert len(data) <= 0x10 - self.sock.send(struct.pack("I", endpoint)+data) + self.sock.send(struct.pack("HH", endpoint, len(data))+data) self.__recv() # to /dev/null def bulkRead(self, endpoint, length, timeout=0): - self.sock.send(struct.pack("I", endpoint)) + self.sock.send(struct.pack("HH", endpoint, 0)) return self.__recv() class Panda(object): def __init__(self, serial=None, claim=True): if serial == "WIFI": self.handle = WifiHandle() + print "opening WIFI device" else: context = usb1.USBContext() @@ -66,7 +71,7 @@ class Panda(object): # ******************* health ******************* def health(self): - dat = self.handle.controlRead(usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE, 0xd2, 0, 0, 0x20) + dat = self.handle.controlRead(usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE, 0xd2, 0, 0, 13) a = struct.unpack("IIBBBBB", dat) return {"voltage": a[0], "current": a[1], "started": a[2], "controls_allowed": a[3], @@ -156,8 +161,8 @@ class Panda(object): self.kline_drain(bus=bus) if checksum: x += get_checksum(x) - for i in range(0, len(x), 0x10): - ts = x[i:i+0x10] + for i in range(0, len(x), 0xf): + ts = x[i:i+0xf] self.handle.bulkWrite(2, chr(bus)+ts) echo = self.kline_ll_recv(len(ts), bus=bus) if echo != ts: diff --git a/tests/loopback_test.py b/tests/loopback_test.py index 46246ce..f970c1f 100755 --- a/tests/loopback_test.py +++ b/tests/loopback_test.py @@ -14,6 +14,14 @@ def get_test_string(): def run_test(): pandas = Panda.list() print pandas + + if len(pandas) == 0: + print "NO PANDAS" + assert False + + if len(pandas) == 1: + # if we only have one on USB, assume the other is on wifi + pandas.append("WIFI") h = map(lambda x: Panda(x), pandas) print h diff --git a/tests/standalone_test.py b/tests/standalone_test.py new file mode 100755 index 0000000..23ac346 --- /dev/null +++ b/tests/standalone_test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +import os +from panda.lib.panda import Panda + +if __name__ == "__main__": + if os.getenv("WIFI") is not None: + p = Panda("WIFI") + else: + p = Panda() + print p.health() +