#include "bus.h" #include "esp/gpio.h" #include #include "log.h" uint32_t spi_transfer_32_duplex(uint8_t bus, uint32_t val) { uint32_t out = val; uint32_t in; spi_transfer(bus, &out, &in, 1, SPI_32BIT); return in; } uint16_t spi_transfer_16_duplex(uint8_t bus, uint32_t val) { uint16_t out = val; uint16_t in; spi_transfer(bus, &out, &in, 1, SPI_16BIT); return in; } void reset_bus() { gpio_write(4, false); for (volatile int k = 0; k < 128; ++k); gpio_write(4, true); } void bus_init() { gpio_write(4, false); for (volatile int k = 0; k < 512 * 2; ++k); gpio_write(4, true); gpio_enable(4, GPIO_OUT_OPEN_DRAIN); gpio_write(4, true); for (volatile int k = 0; k < 512 * 4; ++k); spi_init(1, SPI_MODE0, SPI_FREQ_DIV_2M, true, SPI_BIG_ENDIAN, false); } uint16_t bus_transfer_msg(uint8_t addr, uint16_t dat) { union { struct { unsigned dat: 12; unsigned addr: 4; } __attribute__((packed)); uint16_t _; } frame = {._=0}; frame.addr = addr; frame.dat = dat; spi_transfer_16_duplex(1, frame._); for (volatile int k = 0; k < 512 * 2; ++k); uint16_t reply = spi_transfer_16_duplex(1, 0x0000); for (volatile int k = 0; k < 512 * 2; ++k); return reply; } bool bus_transfer_msg_arr(uint8_t addr, uint16_t* dat, uint8_t len) { union { struct { unsigned dat: 12; unsigned addr: 4; } __attribute__((packed)); uint16_t _; } frame = {._=0}; uint16_t last_frame = 0x0000; uint16_t reply = 0x0000; uint8_t error_count = 0; for (int i = 0; i < len; ++i) { frame.addr = addr + i; frame.dat = dat[i]; reply = spi_transfer_16_duplex(1, frame._); if(reply != last_frame && i != 0) error_count++; if(0){ syslog(" > "); syslog_i32(frame._); syslog(" < "); syslog_i32(reply); syslog(" =? "); syslog_i32(last_frame); syslog("\n"); } last_frame = frame._; for (volatile int k = 0; k < 512 * 2; ++k); } reply = spi_transfer_16_duplex(1, 0x0000); if(reply != last_frame) error_count++; if(0){ syslog(" > "); syslog_i32(frame._); syslog(" < "); syslog_i32(reply); syslog(" =? "); syslog_i32(last_frame); syslog("\n"); } return error_count == 0; } uint16_t bus_get_version() { return bus_transfer_msg(15, 0); } bool bus_ping() { return bus_get_version() == 0x002a; }