Bugfixes and improvements for new hardware

This commit is contained in:
Jan Käberich 2020-09-14 23:13:32 +02:00
parent 7d9d5e27eb
commit 4cbd60e62d
33 changed files with 747 additions and 193 deletions

View file

@ -14,10 +14,17 @@ static uint16_t ISRMaskReg = 0x0000;
using namespace FPGAHAL;
static void SwitchBytes(uint16_t &value) {
value = (value & 0xFF00) >> 8 | (value & 0x00FF) << 8;
}
static void SwitchBytes(int16_t &value) {
value = (value & 0xFF00) >> 8 | (value & 0x00FF) << 8;
}
void WriteRegister(FPGA::Reg reg, uint16_t value) {
uint16_t cmd[2] = {(uint16_t) (0x8000 | (uint16_t) reg), value};
uint8_t cmd[4] = {0x80, (uint8_t) reg, (uint8_t) (value >> 8), (uint8_t) (value & 0xFF)};
Low(CS);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) cmd, 2, 100);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) cmd, 4, 100);
High(CS);
}
@ -34,8 +41,18 @@ bool FPGA::Configure(Flash *f, uint32_t start_address, uint32_t bitstream_size)
High(PROGRAM_B);
while(!isHigh(INIT_B));
if(isHigh(DONE)) {
LOG_ERR("DONE not asserted, aborting configuration");
return false;
}
uint32_t lastmessage = HAL_GetTick();
uint8_t buf[256];
while(bitstream_size > 0) {
if(HAL_GetTick() - lastmessage > 100) {
LOG_DEBUG("Remaining: %lu", bitstream_size);
lastmessage = HAL_GetTick();
}
uint16_t size = sizeof(buf);
if(size > bitstream_size) {
size = bitstream_size;
@ -73,18 +90,20 @@ bool FPGA::Init(HaltedCallback cb) {
Delay::ms(10);
// Check if FPGA response is as expected
uint16_t cmd[2] = {0x4000, 0x0000};
uint16_t recv[2];
uint8_t cmd[4] = {0x40, 0x00, 0x00, 0x00};
uint8_t recv[4];
Low(CS);
HAL_SPI_TransmitReceive(&FPGA_SPI, (uint8_t*) cmd, (uint8_t*) recv, 2, 100);
HAL_SPI_TransmitReceive(&FPGA_SPI, (uint8_t*) cmd, (uint8_t*) recv, 4, 100);
High(CS);
if(recv[1] != 0xF0A5) {
LOG_ERR("Initialization failed, got 0x%04x instead of 0xF0A5", recv[1]);
uint16_t resp = (uint16_t) recv[2] << 8 | recv[3];
uint16_t status = (uint16_t) recv[0] << 8 | recv[1];
if(resp != 0xF0A5) {
LOG_ERR("Initialization failed, got 0x%04x instead of 0xF0A5", resp);
return false;
}
LOG_DEBUG("Initialized, status register: 0x%04x", recv[0]);
LOG_DEBUG("Initialized, status register: 0x%04x", status);
return true;
}
@ -183,8 +202,15 @@ void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceReg
}
send[5] = (Source_M & 0x000F) << 12 | Source_FRAC;
send[6] = Source_DIV_A << 13 | Source_VCO << 7 | Source_N;
SwitchBytes(send[0]);
SwitchBytes(send[1]);
SwitchBytes(send[2]);
SwitchBytes(send[3]);
SwitchBytes(send[4]);
SwitchBytes(send[5]);
SwitchBytes(send[6]);
Low(CS);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) send, 7, 100);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) send, 14, 100);
High(CS);
}
@ -194,17 +220,18 @@ static inline int64_t sign_extend_64(int64_t x, uint16_t bits) {
}
static FPGA::ReadCallback callback;
static uint16_t raw[18];
static uint8_t raw[36];
static bool halted;
bool FPGA::InitiateSampleRead(ReadCallback cb) {
callback = cb;
uint16_t cmd = 0xC000;
uint8_t cmd[2] = {0xC0, 0x00};
uint16_t status;
Low(CS);
HAL_SPI_TransmitReceive(&FPGA_SPI, (uint8_t*) &cmd, (uint8_t*) &status, 1,
100);
HAL_SPI_TransmitReceive(&FPGA_SPI, cmd, (uint8_t*) &status, 2, 100);
SwitchBytes(status);
if (status & 0x0010) {
halted = true;
@ -227,27 +254,28 @@ bool FPGA::InitiateSampleRead(ReadCallback cb) {
}
// Start data read
HAL_SPI_Receive_DMA(&FPGA_SPI, (uint8_t*) raw, 18);
HAL_SPI_Receive_DMA(&FPGA_SPI, raw, 36);
return true;
}
static int64_t assembleSampleResultValue(uint8_t *raw) {
return sign_extend_64(
(uint16_t) raw[0] << 8 | raw[1] | (uint32_t) raw[2] << 24
| (uint32_t) raw[3] << 16 | (uint64_t) raw[4] << 40
| (uint64_t) raw[5] << 32, 48);
}
extern "C" {
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
FPGA::SamplingResult result;
High(CS);
// Assemble data from words
result.P1I = sign_extend_64(
(uint64_t) raw[17] << 32 | (uint32_t) raw[16] << 16 | raw[15], 48);
result.P1Q = sign_extend_64(
(uint64_t) raw[14] << 32 | (uint32_t) raw[13] << 16 | raw[12], 48);
result.P2I = sign_extend_64(
(uint64_t) raw[11] << 32 | (uint32_t) raw[10] << 16 | raw[9], 48);
result.P2Q = sign_extend_64(
(uint64_t) raw[8] << 32 | (uint32_t) raw[7] << 16 | raw[6], 48);
result.RefI = sign_extend_64(
(uint64_t) raw[5] << 32 | (uint32_t) raw[4] << 16 | raw[3], 48);
result.RefQ = sign_extend_64(
(uint64_t) raw[2] << 32 | (uint32_t) raw[1] << 16 | raw[0], 48);
result.P1I = assembleSampleResultValue(&raw[30]);
result.P1Q = assembleSampleResultValue(&raw[24]);
result.P2I = assembleSampleResultValue(&raw[18]);
result.P2Q = assembleSampleResultValue(&raw[12]);
result.RefI = assembleSampleResultValue(&raw[6]);
result.RefQ = assembleSampleResultValue(&raw[0]);
if (callback) {
callback(result);
}
@ -293,36 +321,45 @@ void FPGA::SetMode(Mode mode) {
}
uint16_t FPGA::GetStatus() {
uint16_t cmd = 0x4000;
uint16_t status;
uint8_t cmd[2] = {0x40, 0x00};
uint8_t status[2];
Low(CS);
HAL_SPI_TransmitReceive(&FPGA_SPI, (uint8_t*) &cmd, (uint8_t*) &status, 1,
HAL_SPI_TransmitReceive(&FPGA_SPI, (uint8_t*) &cmd, (uint8_t*) &status, 2,
100);
High(CS);
return status;
return (uint16_t) status[0] << 8 | status[1];
}
FPGA::ADCLimits FPGA::GetADCLimits() {
uint16_t cmd = 0xE000;
SwitchBytes(cmd);
Low(CS);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) &cmd, 1, 100);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) &cmd, 2, 100);
ADCLimits limits;
HAL_SPI_Receive(&FPGA_SPI, (uint8_t*) &limits, 6, 100);
HAL_SPI_Receive(&FPGA_SPI, (uint8_t*) &limits, 12, 100);
High(CS);
SwitchBytes(limits.P1max);
SwitchBytes(limits.P1min);
SwitchBytes(limits.P2max);
SwitchBytes(limits.P2min);
SwitchBytes(limits.Rmax);
SwitchBytes(limits.Rmin);
return limits;
}
void FPGA::ResetADCLimits() {
uint16_t cmd = 0x6000;
SwitchBytes(cmd);
Low(CS);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) &cmd, 1, 100);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) &cmd, 2, 100);
High(CS);
}
void FPGA::ResumeHaltedSweep() {
uint16_t cmd = 0x2000;
SwitchBytes(cmd);
Low(CS);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) &cmd, 1, 100);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) &cmd, 2, 100);
High(CS);
}

View file

@ -1,5 +1,13 @@
#include "Flash.hpp"
#include "FreeRTOS.h"
#include "task.h"
#include <cstring>
#define LOG_LEVEL LOG_LEVEL_INFO
#define LOG_MODULE "Flash"
#include "Log.h"
bool Flash::isPresent() {
CS(false);
// read JEDEC ID
@ -24,16 +32,18 @@ void Flash::read(uint32_t address, uint16_t length, void *dest) {
bool Flash::write(uint32_t address, uint16_t length, uint8_t *src) {
if((address & 0xFF) != 0 || length%256 != 0) {
// only writes to complete pages allowed
LOG_ERR("Invalid write address/size: %lu/%u", address, length);
return false;
}
address &= 0x00FFFFFF;
LOG_DEBUG("Writing %u bytes to address %lu", length, address);
while(length > 0) {
EnableWrite();
CS(false);
uint8_t cmd[4] = {
0x02,
((uint8_t) address >> 16) & 0xFF,
((uint8_t) address >> 8) & 0xFF,
(uint8_t) (address >> 16) & 0xFF,
(uint8_t) (address >> 8) & 0xFF,
(uint8_t) (address & 0xFF),
};
// issue read command
@ -41,9 +51,18 @@ bool Flash::write(uint32_t address, uint16_t length, uint8_t *src) {
// write data
HAL_SPI_Transmit(spi, src, 256, 1000);
CS(true);
if(!WaitBusy(5)) {
if(!WaitBusy(20)) {
LOG_ERR("Write timed out");
return false;
}
// Verify
uint8_t buf[256];
read(address, 256, buf);
if(memcmp(src, buf, 256)) {
LOG_ERR("Verification error");
return false;
}
address += 256;
length -= 256;
src += 256;
}
@ -59,6 +78,7 @@ void Flash::EnableWrite() {
}
bool Flash::eraseChip() {
LOG_INFO("Erasing...");
EnableWrite();
CS(false);
// enable write latch
@ -73,8 +93,8 @@ void Flash::initiateRead(uint32_t address) {
CS(false);
uint8_t cmd[4] = {
0x03,
((uint8_t) address >> 16) & 0xFF,
((uint8_t) address >> 8) & 0xFF,
(uint8_t) (address >> 16) & 0xFF,
(uint8_t) (address >> 8) & 0xFF,
(uint8_t) (address & 0xFF),
};
// issue read command
@ -86,15 +106,17 @@ bool Flash::WaitBusy(uint32_t timeout) {
CS(false);
uint8_t readStatus1 = 0x05;
HAL_SPI_Transmit(spi, &readStatus1, 1, 100);
while(HAL_GetTick() - starttime > timeout) {
do {
vTaskDelay(1);
uint8_t status1;
HAL_SPI_Receive(spi, &status1, 1, 100);
if(!(status1 & 0x01)) {
if (!(status1 & 0x01)) {
CS(true);
return true;
}
}
} while (HAL_GetTick() - starttime < timeout);
// timed out
CS(true);
LOG_ERR("Timeout occured");
return false;
}

View file

@ -6,7 +6,7 @@ extern "C" {
//#define LOG_BLOCKING
#define LOG_USART 2
#define LOG_USART 3
#define LOG_SENDBUF_LENGTH 1024
//#define LOG_USE_MUTEX

View file

@ -2,7 +2,7 @@
#include <cmath>
#define LOG_LEVEL LOG_LEVEL_DEBUG
#define LOG_LEVEL LOG_LEVEL_INFO
#define LOG_MODULE "SI5351"
#include "Log.h"

View file

@ -296,12 +296,14 @@ void MAX2871::UpdateFrequency() {
}
void MAX2871::Write(uint8_t reg, uint32_t val) {
uint16_t data[2];
uint8_t data[4];
// split value into two 16 bit words
data[0] = val >> 16;
data[1] = (val & 0xFFF8) | reg;
data[0] = (val >> 24) & 0xFF;
data[1] = (val >> 16) & 0xFF;
data[2] = (val >> 8) & 0xFF;
data[3] = (val & 0xF8) | reg;
Delay::us(1);
HAL_SPI_Transmit(hspi, (uint8_t*) data, 2, 20);
HAL_SPI_Transmit(hspi, (uint8_t*) data, 4, 20);
LE->BSRR = LEpin;
Delay::us(1);
LE->BSRR = LEpin << 16;
@ -309,15 +311,16 @@ void MAX2871::Write(uint8_t reg, uint32_t val) {
// Assumes that the MUX pin is already configured as "Read register 6" and connected to MISO
uint32_t MAX2871::Read() {
uint16_t transmit[2] = {0x0000, 0x0006};
HAL_SPI_Transmit(hspi, (uint8_t*) transmit, 2, 20);
uint8_t transmit[4] = {0x00, 0x00, 0x00, 0x06};
HAL_SPI_Transmit(hspi, (uint8_t*) transmit, 4, 20);
LE->BSRR = LEpin;
memset(transmit, 0, sizeof(transmit));
uint16_t recv[2];
HAL_SPI_TransmitReceive(hspi, (uint8_t*) transmit, (uint8_t*) recv, 2, 20);
uint8_t recv[4];
HAL_SPI_TransmitReceive(hspi, (uint8_t*) transmit, (uint8_t*) recv, 4, 20);
LE->BSRR = LEpin << 16;
// assemble readback result
uint32_t result = ((uint32_t) recv[0] << 16) | (recv[1] & 0xFFFF);
uint32_t result = ((uint32_t) recv[0] << 24) | ((uint32_t) recv[1] << 16
) | ((uint32_t) recv[2] << 8) | (recv[3] & 0xFF);
result <<= 2;
LOG_DEBUG("Readback: 0x%08x", result);
return result;