117 lines
2.6 KiB
C++
117 lines
2.6 KiB
C++
|
#include "bus.h"
|
||
|
#include "esp/gpio.h"
|
||
|
|
||
|
#include <esp/spi.h>
|
||
|
#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;
|
||
|
}
|