Add files via upload
This commit is contained in:
@@ -0,0 +1,757 @@
|
||||
// ADAR1000_Manager.cpp
|
||||
#include "main.h"
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "ADAR1000_Manager.h"
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
extern UART_HandleTypeDef huart3;
|
||||
|
||||
// Chip Select GPIO definitions
|
||||
static const struct {
|
||||
GPIO_TypeDef* port;
|
||||
uint16_t pin;
|
||||
} CHIP_SELECTS[4] = {
|
||||
{GPIOA, GPIO_PIN_0}, // ADAR1000 #1
|
||||
{GPIOA, GPIO_PIN_1}, // ADAR1000 #2
|
||||
{GPIOA, GPIO_PIN_2}, // ADAR1000 #3
|
||||
{GPIOA, GPIO_PIN_3} // ADAR1000 #4
|
||||
};
|
||||
|
||||
// Vector Modulator lookup tables
|
||||
const uint8_t ADAR1000Manager::VM_I[128] = {
|
||||
// ... (same as in your original file)
|
||||
};
|
||||
|
||||
const uint8_t ADAR1000Manager::VM_Q[128] = {
|
||||
// ... (same as in your original file)
|
||||
};
|
||||
|
||||
const uint8_t ADAR1000Manager::VM_GAIN[128] = {
|
||||
// ... (same as in your original file)
|
||||
};
|
||||
|
||||
ADAR1000Manager::ADAR1000Manager() {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
devices_.push_back(std::make_unique<ADAR1000Device>(i));
|
||||
}
|
||||
}
|
||||
|
||||
ADAR1000Manager::~ADAR1000Manager() {
|
||||
// Automatic cleanup by unique_ptr
|
||||
}
|
||||
|
||||
// System Management
|
||||
bool ADAR1000Manager::powerUpSystem() {
|
||||
const uint8_t msg[] = "Starting System Power-Up Sequence...\r\n";
|
||||
HAL_UART_Transmit(&huart3, msg, sizeof(msg) - 1, 1000);
|
||||
|
||||
// Power-up sequence steps...
|
||||
HAL_GPIO_WritePin(EN_P_3V3_VDD_SW_GPIO_Port, EN_P_3V3_VDD_SW_Pin, GPIO_PIN_SET);
|
||||
HAL_Delay(2);
|
||||
|
||||
HAL_GPIO_WritePin(EN_P_3V3_SW_GPIO_Port, EN_P_3V3_SW_Pin, GPIO_PIN_SET);
|
||||
HAL_Delay(2);
|
||||
|
||||
// Initialize devices
|
||||
if (!initializeAllDevices()) {
|
||||
const uint8_t err[] = "ERROR: ADAR1000 initialization failed!\r\n";
|
||||
HAL_UART_Transmit(&huart3, err, sizeof(err) - 1, 1000);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start in RX mode
|
||||
switchToRXMode();
|
||||
|
||||
const uint8_t success[] = "System Power-Up Sequence Completed Successfully.\r\n";
|
||||
HAL_UART_Transmit(&huart3, success, sizeof(success) - 1, 1000);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ADAR1000Manager::powerDownSystem() {
|
||||
switchToRXMode();
|
||||
HAL_Delay(10);
|
||||
|
||||
disablePASupplies();
|
||||
disableLNASupplies();
|
||||
HAL_GPIO_WritePin(EN_P_3V3_SW_GPIO_Port, EN_P_3V3_SW_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(EN_P_3V3_VDD_SW_GPIO_Port, EN_P_3V3_VDD_SW_Pin, GPIO_PIN_RESET);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mode Switching
|
||||
void ADAR1000Manager::switchToTXMode() {
|
||||
setLNABias(false);
|
||||
delayUs(10);
|
||||
enablePASupplies();
|
||||
delayUs(100);
|
||||
setPABias(true);
|
||||
delayUs(50);
|
||||
setADTR1107Control(true);
|
||||
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_RX_ENABLES, 0x00, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_TX_ENABLES, 0x0F, BROADCAST_OFF);
|
||||
adarSetTxBias(dev, BROADCAST_OFF);
|
||||
devices_[dev]->current_mode = BeamDirection::TX;
|
||||
}
|
||||
current_mode_ = BeamDirection::TX;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::switchToRXMode() {
|
||||
setPABias(false);
|
||||
delayUs(50);
|
||||
disablePASupplies();
|
||||
delayUs(10);
|
||||
setADTR1107Control(false);
|
||||
enableLNASupplies();
|
||||
delayUs(50);
|
||||
setLNABias(true);
|
||||
delayUs(50);
|
||||
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_TX_ENABLES, 0x00, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_RX_ENABLES, 0x0F, BROADCAST_OFF);
|
||||
devices_[dev]->current_mode = BeamDirection::RX;
|
||||
}
|
||||
current_mode_ = BeamDirection::RX;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::fastTXMode() {
|
||||
setADTR1107Control(true);
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_RX_ENABLES, 0x00, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_TX_ENABLES, 0x0F, BROADCAST_OFF);
|
||||
devices_[dev]->current_mode = BeamDirection::TX;
|
||||
}
|
||||
current_mode_ = BeamDirection::TX;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::fastRXMode() {
|
||||
setADTR1107Control(false);
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_TX_ENABLES, 0x00, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_RX_ENABLES, 0x0F, BROADCAST_OFF);
|
||||
devices_[dev]->current_mode = BeamDirection::RX;
|
||||
}
|
||||
current_mode_ = BeamDirection::RX;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::pulseTXMode() {
|
||||
setADTR1107Control(true);
|
||||
last_switch_time_us_ = HAL_GetTick() * 1000;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::pulseRXMode() {
|
||||
setADTR1107Control(false);
|
||||
last_switch_time_us_ = HAL_GetTick() * 1000;
|
||||
}
|
||||
|
||||
// Beam Steering
|
||||
bool ADAR1000Manager::setBeamAngle(float angle_degrees, BeamDirection direction) {
|
||||
uint8_t phase_settings[4];
|
||||
calculatePhaseSettings(angle_degrees, phase_settings);
|
||||
|
||||
if (direction == BeamDirection::TX) {
|
||||
setAllDevicesTXMode();
|
||||
} else {
|
||||
setAllDevicesRXMode();
|
||||
}
|
||||
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
for (uint8_t ch = 0; ch < 4; ++ch) {
|
||||
if (direction == BeamDirection::TX) {
|
||||
adarSetTxPhase(dev, ch + 1, phase_settings[ch], BROADCAST_OFF);
|
||||
adarSetTxVgaGain(dev, ch + 1, 0x7F, BROADCAST_OFF);
|
||||
} else {
|
||||
adarSetRxPhase(dev, ch + 1, phase_settings[ch], BROADCAST_OFF);
|
||||
adarSetRxVgaGain(dev, ch + 1, 30, BROADCAST_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ADAR1000Manager::setCustomBeamPattern(const uint8_t phase_settings[4], const uint8_t gain_settings[4], BeamDirection direction) {
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
for (uint8_t ch = 0; ch < 4; ++ch) {
|
||||
if (direction == BeamDirection::TX) {
|
||||
adarSetTxPhase(dev, ch + 1, phase_settings[ch], BROADCAST_OFF);
|
||||
adarSetTxVgaGain(dev, ch + 1, gain_settings[ch], BROADCAST_OFF);
|
||||
} else {
|
||||
adarSetRxPhase(dev, ch + 1, phase_settings[ch], BROADCAST_OFF);
|
||||
adarSetRxVgaGain(dev, ch + 1, gain_settings[ch], BROADCAST_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Beam Sweeping
|
||||
void ADAR1000Manager::startBeamSweeping() {
|
||||
beam_sweeping_active_ = true;
|
||||
current_beam_index_ = 0;
|
||||
last_beam_update_time_ = HAL_GetTick();
|
||||
}
|
||||
|
||||
void ADAR1000Manager::stopBeamSweeping() {
|
||||
beam_sweeping_active_ = false;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::updateBeamPosition() {
|
||||
if (!beam_sweeping_active_) return;
|
||||
|
||||
uint32_t current_time = HAL_GetTick();
|
||||
const std::vector<BeamConfig>& sequence =
|
||||
(current_mode_ == BeamDirection::TX) ? tx_beam_sequence_ : rx_beam_sequence_;
|
||||
|
||||
if (sequence.empty()) return;
|
||||
|
||||
if (current_time - last_beam_update_time_ >= beam_dwell_time_ms_) {
|
||||
const BeamConfig& beam = sequence[current_beam_index_];
|
||||
setCustomBeamPattern(beam.phase_settings, beam.gain_settings, current_mode_);
|
||||
|
||||
current_beam_index_ = (current_beam_index_ + 1) % sequence.size();
|
||||
last_beam_update_time_ = current_time;
|
||||
}
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setBeamSequence(const std::vector<BeamConfig>& sequence, BeamDirection direction) {
|
||||
if (direction == BeamDirection::TX) {
|
||||
tx_beam_sequence_ = sequence;
|
||||
} else {
|
||||
rx_beam_sequence_ = sequence;
|
||||
}
|
||||
}
|
||||
|
||||
void ADAR1000Manager::clearBeamSequence(BeamDirection direction) {
|
||||
if (direction == BeamDirection::TX) {
|
||||
tx_beam_sequence_.clear();
|
||||
} else {
|
||||
rx_beam_sequence_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Monitoring and Diagnostics
|
||||
float ADAR1000Manager::readTemperature(uint8_t deviceIndex) {
|
||||
if (deviceIndex >= devices_.size() || !devices_[deviceIndex]->initialized) {
|
||||
return -273.15f;
|
||||
}
|
||||
|
||||
uint8_t temp_raw = adarAdcRead(deviceIndex, BROADCAST_OFF);
|
||||
return (temp_raw * 0.5f) - 50.0f;
|
||||
}
|
||||
|
||||
bool ADAR1000Manager::verifyDeviceCommunication(uint8_t deviceIndex) {
|
||||
if (deviceIndex >= devices_.size()) return false;
|
||||
|
||||
uint8_t test_value = 0xA5;
|
||||
adarWrite(deviceIndex, REG_SCRATCHPAD, test_value, BROADCAST_OFF);
|
||||
HAL_Delay(1);
|
||||
uint8_t readback = adarRead(deviceIndex, REG_SCRATCHPAD);
|
||||
return (readback == test_value);
|
||||
}
|
||||
|
||||
uint8_t ADAR1000Manager::readRegister(uint8_t deviceIndex, uint32_t address) {
|
||||
return adarRead(deviceIndex, address);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::writeRegister(uint8_t deviceIndex, uint32_t address, uint8_t value) {
|
||||
adarWrite(deviceIndex, address, value, BROADCAST_OFF);
|
||||
}
|
||||
|
||||
// Configuration
|
||||
void ADAR1000Manager::setSwitchSettlingTime(uint32_t us) {
|
||||
switch_settling_time_us_ = us;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setFastSwitchMode(bool enable) {
|
||||
fast_switch_mode_ = enable;
|
||||
if (enable) {
|
||||
switch_settling_time_us_ = 10;
|
||||
enablePASupplies();
|
||||
enableLNASupplies();
|
||||
setPABias(true);
|
||||
setLNABias(true);
|
||||
} else {
|
||||
switch_settling_time_us_ = 50;
|
||||
}
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setBeamDwellTime(uint32_t ms) {
|
||||
beam_dwell_time_ms_ = ms;
|
||||
}
|
||||
|
||||
// Private helper methods (implementation continues...)
|
||||
// ... include all the private method implementations from your original file
|
||||
// ============================================================================
|
||||
// PRIVATE HELPER METHODS - Add these to the end of ADAR1000_Manager.cpp
|
||||
// ============================================================================
|
||||
|
||||
bool ADAR1000Manager::initializeAllDevices() {
|
||||
|
||||
|
||||
// Initialize each ADAR1000
|
||||
for (uint8_t i = 0; i < devices_.size(); ++i) {
|
||||
if (!initializeSingleDevice(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
setAllDevicesTXMode();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ADAR1000Manager::initializeSingleDevice(uint8_t deviceIndex) {
|
||||
if (deviceIndex >= devices_.size()) return false;
|
||||
|
||||
adarSoftReset(deviceIndex);
|
||||
HAL_Delay(10);
|
||||
|
||||
adarWriteConfigA(deviceIndex, INTERFACE_CONFIG_A_SDO_ACTIVE, BROADCAST_OFF);
|
||||
adarSetRamBypass(deviceIndex, BROADCAST_OFF);
|
||||
|
||||
// Initialize ADC
|
||||
adarWrite(deviceIndex, REG_ADC_CONTROL, ADAR1000_ADC_2MHZ_CLK | ADAR1000_ADC_EN, BROADCAST_OFF);
|
||||
|
||||
devices_[deviceIndex]->initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ADAR1000Manager::initializeADTR1107Sequence() {
|
||||
|
||||
//Powering up ADTR1107 TX mode
|
||||
const uint8_t msg[] = "Starting ADTR1107 Power Sequence...\r\n";
|
||||
HAL_UART_Transmit(&huart3, msg, sizeof(msg) - 1, 1000);
|
||||
|
||||
// Step 1: Connect all GND pins to ground (assumed in hardware)
|
||||
|
||||
// Step 2: Set VDD_SW to 3.3V
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_15, GPIO_PIN_SET); // EN_P_3V3_VDD_SW
|
||||
HAL_Delay(1);
|
||||
|
||||
// Step 3: Set VSS_SW to -3.3V
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_14, GPIO_PIN_SET); // EN_P_3V3_SW
|
||||
HAL_Delay(1);
|
||||
|
||||
// Step 4: Set CTRL_SW to RX mode initially via GPIO
|
||||
setADTR1107Control(false); // RX mode
|
||||
HAL_Delay(1);
|
||||
|
||||
// Step 5: Set VGG_LNA to 0
|
||||
uint8_t lna_bias_voltage = 0x00; // Example value, adjust based on your LNA requirements
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_LNA_BIAS_ON, lna_bias_voltage, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_LNA_BIAS_OFF, 0x00, BROADCAST_OFF);
|
||||
}
|
||||
|
||||
// Step 6: Set VDD_LNA to 0V for TX mode
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_RESET); // EN_P_3V3_LNA
|
||||
HAL_Delay(2);
|
||||
|
||||
// Step 7: Set VGG_PA to safe negative voltage (PA off for TX mode)
|
||||
/*A 0x00 value in the
|
||||
on or off bias registers, correspond to a 0 V output. A 0xFF in the
|
||||
on or off bias registers correspond to a −4.8 V output.*/
|
||||
uint8_t safe_pa_bias = 0x5D; // Safe negative voltage (-1.75V) to keep PA off
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_PA_CH1_BIAS_ON, safe_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH2_BIAS_ON, safe_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH3_BIAS_ON, safe_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH4_BIAS_ON, safe_pa_bias, BROADCAST_OFF);
|
||||
}
|
||||
HAL_Delay(10);
|
||||
|
||||
// Step 8: Set VDD_PA to 0V (PA powered up for TX mode)
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_SET); // EN_P_5V0_PA
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_1, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_SET);
|
||||
HAL_Delay(50);
|
||||
|
||||
// Step 9: Adjust VGG_PA voltage between −1.75 V and −0.25 V to achieve the desired IDQ_PA=220mA
|
||||
//Set VGG_PA to safe negative voltage (PA off for TX mode)
|
||||
/*A 0x00 value in the
|
||||
on or off bias registers, correspond to a 0 V output. A 0xFF in the
|
||||
on or off bias registers correspond to a −4.8 V output.*/
|
||||
uint8_t Idq_pa_bias = 0x0D; // Safe negative voltage (-0.2447V) to keep PA off
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_PA_CH1_BIAS_ON, Idq_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH2_BIAS_ON, Idq_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH3_BIAS_ON, Idq_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH4_BIAS_ON, Idq_pa_bias, BROADCAST_OFF);
|
||||
}
|
||||
HAL_Delay(10);
|
||||
|
||||
|
||||
const uint8_t success[] = "ADTR1107 power sequence completed.\r\n";
|
||||
HAL_UART_Transmit(&huart3, success, sizeof(success) - 1, 1000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ADAR1000Manager::setAllDevicesTXMode() {
|
||||
// Set ADTR1107 to TX mode first
|
||||
setADTR1107Mode(BeamDirection::TX);
|
||||
|
||||
// Then configure ADAR1000 for TX
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
// Disable RX first
|
||||
adarWrite(dev, REG_RX_ENABLES, 0x00, BROADCAST_OFF);
|
||||
|
||||
// Enable TX channels and set bias
|
||||
adarWrite(dev, REG_TX_ENABLES, 0x0F, BROADCAST_OFF); // Enable all 4 channels
|
||||
adarSetTxBias(dev, BROADCAST_OFF);
|
||||
|
||||
devices_[dev]->current_mode = BeamDirection::TX;
|
||||
}
|
||||
current_mode_ = BeamDirection::TX;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ADAR1000Manager::setAllDevicesRXMode() {
|
||||
// Set ADTR1107 to RX mode first
|
||||
setADTR1107Mode(BeamDirection::RX);
|
||||
|
||||
// Then configure ADAR1000 for RX
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
// Disable TX first
|
||||
adarWrite(dev, REG_TX_ENABLES, 0x00, BROADCAST_OFF);
|
||||
|
||||
// Enable RX channels
|
||||
adarWrite(dev, REG_RX_ENABLES, 0x0F, BROADCAST_OFF); // Enable all 4 channels
|
||||
|
||||
devices_[dev]->current_mode = BeamDirection::RX;
|
||||
}
|
||||
current_mode_ = BeamDirection::RX;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setADTR1107Mode(BeamDirection direction) {
|
||||
if (direction == BeamDirection::TX) {
|
||||
setADTR1107Control(true); // TX mode
|
||||
|
||||
// Step 1: Disable LNA power first
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_RESET); // Disable LNA power
|
||||
HAL_Delay(5);
|
||||
|
||||
// Step 2: Set LNA bias to safe off value
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_LNA_BIAS_ON, 0x00, BROADCAST_OFF); // Turn off LNA bias
|
||||
}
|
||||
HAL_Delay(5);
|
||||
|
||||
// Step 3: Enable PA power
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_SET); // EN_P_5V0_PA
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_1, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_SET);
|
||||
HAL_Delay(10);
|
||||
|
||||
// Step 4: Set PA bias to operational value
|
||||
uint8_t operational_pa_bias = 0x7F; // Maximum bias for full power
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_PA_CH1_BIAS_ON, operational_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH2_BIAS_ON, operational_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH3_BIAS_ON, operational_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH4_BIAS_ON, operational_pa_bias, BROADCAST_OFF);
|
||||
}
|
||||
HAL_Delay(5);
|
||||
|
||||
// Step 5: Set TR switch to TX mode
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarSetBit(dev, REG_SW_CONTROL, 2, BROADCAST_OFF); // TR_SOURCE = 1 (TX)
|
||||
adarSetBit(dev, REG_MISC_ENABLES, 5, BROADCAST_OFF); // BIAS_EN
|
||||
}
|
||||
|
||||
} else {
|
||||
// RECEIVE MODE: Enable LNA, Disable PA
|
||||
setADTR1107Control(false); // RX mode
|
||||
|
||||
// Step 1: Disable PA power first
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_RESET); // EN_P_5V0_PA
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_1, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_RESET);
|
||||
HAL_Delay(5);
|
||||
|
||||
// Step 2: Set PA bias to safe negative voltage
|
||||
uint8_t safe_pa_bias = 0x20;
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_PA_CH1_BIAS_ON, safe_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH2_BIAS_ON, safe_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH3_BIAS_ON, safe_pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH4_BIAS_ON, safe_pa_bias, BROADCAST_OFF);
|
||||
}
|
||||
HAL_Delay(5);
|
||||
|
||||
// Step 3: Enable LNA power
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_SET); // EN_P_3V3_LNA
|
||||
HAL_Delay(10);
|
||||
|
||||
// Step 4: Set LNA bias to operational value
|
||||
uint8_t operational_lna_bias = 0x30; // Adjust based on your LNA requirements
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_LNA_BIAS_ON, operational_lna_bias, BROADCAST_OFF);
|
||||
}
|
||||
HAL_Delay(5);
|
||||
|
||||
// Step 5: Set TR switch to RX mode
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarResetBit(dev, REG_SW_CONTROL, 2, BROADCAST_OFF); // TR_SOURCE = 0 (RX)
|
||||
adarSetBit(dev, REG_MISC_ENABLES, 4, BROADCAST_OFF); // LNA_BIAS_OUT_EN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setADTR1107Control(bool tx_mode) {
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
setTRSwitchPosition(dev, tx_mode);
|
||||
}
|
||||
delayUs(switch_settling_time_us_);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setTRSwitchPosition(uint8_t deviceIndex, bool tx_mode) {
|
||||
if (tx_mode) {
|
||||
// TX mode: Set TR_SOURCE = 1
|
||||
adarSetBit(deviceIndex, REG_SW_CONTROL, 2, BROADCAST_OFF);
|
||||
} else {
|
||||
// RX mode: Set TR_SOURCE = 0
|
||||
adarResetBit(deviceIndex, REG_SW_CONTROL, 2, BROADCAST_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the new public method
|
||||
bool ADAR1000Manager::setCustomBeamPattern16(const uint8_t phase_pattern[16], BeamDirection direction) {
|
||||
for (uint8_t dev = 0; dev < 4; ++dev) {
|
||||
for (uint8_t ch = 0; ch < 4; ++ch) {
|
||||
uint8_t phase = phase_pattern[dev * 4 + ch];
|
||||
if (direction == BeamDirection::TX) {
|
||||
adarSetTxPhase(dev, ch + 1, phase, BROADCAST_OFF);
|
||||
} else {
|
||||
adarSetRxPhase(dev, ch + 1, phase, BROADCAST_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::enablePASupplies() {
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_SET); // EN_P_5V0_PA
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_1, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::disablePASupplies() {
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_RESET); // EN_P_5V0_PA
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_1, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::enableLNASupplies() {
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_SET); // EN_P_3V3_LNA
|
||||
}
|
||||
|
||||
void ADAR1000Manager::disableLNASupplies() {
|
||||
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_13, GPIO_PIN_RESET); // EN_P_3V3_LNA
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setPABias(bool enable) {
|
||||
uint8_t pa_bias = enable ? 0x7F : 0x20; // Operational vs safe bias
|
||||
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_PA_CH1_BIAS_ON, pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH2_BIAS_ON, pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH3_BIAS_ON, pa_bias, BROADCAST_OFF);
|
||||
adarWrite(dev, REG_PA_CH4_BIAS_ON, pa_bias, BROADCAST_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setLNABias(bool enable) {
|
||||
uint8_t lna_bias = enable ? 0x30 : 0x00; // Operational vs off
|
||||
|
||||
for (uint8_t dev = 0; dev < devices_.size(); ++dev) {
|
||||
adarWrite(dev, REG_LNA_BIAS_ON, lna_bias, BROADCAST_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
void ADAR1000Manager::delayUs(uint32_t microseconds) {
|
||||
// Simple implementation - for F7 @ 216MHz, each loop ~7 cycles ≈ 0.032us
|
||||
volatile uint32_t cycles = microseconds * 10; // Adjust this multiplier for your clock
|
||||
while (cycles--) {
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
void ADAR1000Manager::calculatePhaseSettings(float angle_degrees, uint8_t phase_settings[4]) {
|
||||
const float freq = 10.5e9;
|
||||
const float c = 3e8;
|
||||
const float wavelength = c / freq;
|
||||
const float element_spacing = wavelength / 2;
|
||||
|
||||
float angle_rad = angle_degrees * M_PI / 180.0;
|
||||
float phase_shift = (2 * M_PI * element_spacing * sin(angle_rad)) / wavelength;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
float element_phase = i * phase_shift;
|
||||
while (element_phase < 0) element_phase += 2 * M_PI;
|
||||
while (element_phase >= 2 * M_PI) element_phase -= 2 * M_PI;
|
||||
phase_settings[i] = static_cast<uint8_t>((element_phase / (2 * M_PI)) * 128);
|
||||
}
|
||||
}
|
||||
|
||||
bool ADAR1000Manager::performSystemCalibration() {
|
||||
for (uint8_t i = 0; i < devices_.size(); ++i) {
|
||||
if (!verifyDeviceCommunication(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// LOW-LEVEL SPI COMMUNICATION METHODS
|
||||
// ============================================================================
|
||||
|
||||
uint32_t ADAR1000Manager::spiTransfer(uint8_t* txData, uint8_t* rxData, uint32_t size) {
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
if (rxData) {
|
||||
status = HAL_SPI_TransmitReceive(&hspi1, txData, rxData, size, 1000);
|
||||
} else {
|
||||
status = HAL_SPI_Transmit(&hspi1, txData, size, 1000);
|
||||
}
|
||||
|
||||
return (status == HAL_OK) ? size : 0;
|
||||
}
|
||||
|
||||
void ADAR1000Manager::setChipSelect(uint8_t deviceIndex, bool state) {
|
||||
if (deviceIndex >= devices_.size()) return;
|
||||
HAL_GPIO_WritePin(CHIP_SELECTS[deviceIndex].port,
|
||||
CHIP_SELECTS[deviceIndex].pin,
|
||||
state ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarWrite(uint8_t deviceIndex, uint32_t mem_addr, uint8_t data, uint8_t broadcast) {
|
||||
uint8_t instruction[3];
|
||||
|
||||
if (broadcast) {
|
||||
instruction[0] = 0x08;
|
||||
} else {
|
||||
instruction[0] = ((devices_[deviceIndex]->dev_addr & 0x03) << 5);
|
||||
}
|
||||
|
||||
instruction[0] |= (0x1F00 & mem_addr) >> 8;
|
||||
instruction[1] = (0xFF & mem_addr);
|
||||
instruction[2] = data;
|
||||
|
||||
setChipSelect(deviceIndex, true);
|
||||
spiTransfer(instruction, nullptr, sizeof(instruction));
|
||||
setChipSelect(deviceIndex, false);
|
||||
}
|
||||
|
||||
uint8_t ADAR1000Manager::adarRead(uint8_t deviceIndex, uint32_t mem_addr) {
|
||||
uint8_t instruction[3] = {0};
|
||||
uint8_t rx_buffer[3] = {0};
|
||||
|
||||
// Set SDO active
|
||||
adarWrite(deviceIndex, REG_INTERFACE_CONFIG_A, INTERFACE_CONFIG_A_SDO_ACTIVE, 0);
|
||||
|
||||
instruction[0] = 0x80 | ((devices_[deviceIndex]->dev_addr & 0x03) << 5);
|
||||
instruction[0] |= ((0xff00 & mem_addr) >> 8);
|
||||
instruction[1] = (0xff & mem_addr);
|
||||
instruction[2] = 0x00;
|
||||
|
||||
setChipSelect(deviceIndex, true);
|
||||
spiTransfer(instruction, rx_buffer, sizeof(instruction));
|
||||
setChipSelect(deviceIndex, false);
|
||||
|
||||
// Set SDO Inactive
|
||||
adarWrite(deviceIndex, REG_INTERFACE_CONFIG_A, 0, 0);
|
||||
|
||||
return rx_buffer[2];
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarSetBit(uint8_t deviceIndex, uint32_t mem_addr, uint8_t bit, uint8_t broadcast) {
|
||||
uint8_t temp = adarRead(deviceIndex, mem_addr);
|
||||
uint8_t data = temp | (1 << bit);
|
||||
adarWrite(deviceIndex, mem_addr, data, broadcast);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarResetBit(uint8_t deviceIndex, uint32_t mem_addr, uint8_t bit, uint8_t broadcast) {
|
||||
uint8_t temp = adarRead(deviceIndex, mem_addr);
|
||||
uint8_t data = temp & ~(1 << bit);
|
||||
adarWrite(deviceIndex, mem_addr, data, broadcast);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarSoftReset(uint8_t deviceIndex) {
|
||||
uint8_t instruction[3];
|
||||
instruction[0] = ((devices_[deviceIndex]->dev_addr & 0x03) << 5);
|
||||
instruction[1] = 0x00;
|
||||
instruction[2] = 0x81;
|
||||
|
||||
setChipSelect(deviceIndex, true);
|
||||
spiTransfer(instruction, nullptr, sizeof(instruction));
|
||||
setChipSelect(deviceIndex, false);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarWriteConfigA(uint8_t deviceIndex, uint8_t flags, uint8_t broadcast) {
|
||||
adarWrite(deviceIndex, REG_INTERFACE_CONFIG_A, flags, broadcast);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarSetRamBypass(uint8_t deviceIndex, uint8_t broadcast) {
|
||||
uint8_t data = (MEM_CTRL_BIAS_RAM_BYPASS | MEM_CTRL_BEAM_RAM_BYPASS);
|
||||
adarWrite(deviceIndex, REG_MEM_CTL, data, broadcast);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarSetRxPhase(uint8_t deviceIndex, uint8_t channel, uint8_t phase, uint8_t broadcast) {
|
||||
uint8_t i_val = VM_I[phase % 128];
|
||||
uint8_t q_val = VM_Q[phase % 128];
|
||||
|
||||
uint32_t mem_addr_i = REG_CH1_RX_PHS_I + (channel & 0x03) * 2;
|
||||
uint32_t mem_addr_q = REG_CH1_RX_PHS_Q + (channel & 0x03) * 2;
|
||||
|
||||
adarWrite(deviceIndex, mem_addr_i, i_val, broadcast);
|
||||
adarWrite(deviceIndex, mem_addr_q, q_val, broadcast);
|
||||
adarWrite(deviceIndex, REG_LOAD_WORKING, 0x1, broadcast);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarSetTxPhase(uint8_t deviceIndex, uint8_t channel, uint8_t phase, uint8_t broadcast) {
|
||||
uint8_t i_val = VM_I[phase % 128];
|
||||
uint8_t q_val = VM_Q[phase % 128];
|
||||
|
||||
uint32_t mem_addr_i = REG_CH1_TX_PHS_I + (channel & 0x03) * 2;
|
||||
uint32_t mem_addr_q = REG_CH1_TX_PHS_Q + (channel & 0x03) * 2;
|
||||
|
||||
adarWrite(deviceIndex, mem_addr_i, i_val, broadcast);
|
||||
adarWrite(deviceIndex, mem_addr_q, q_val, broadcast);
|
||||
adarWrite(deviceIndex, REG_LOAD_WORKING, 0x1, broadcast);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarSetRxVgaGain(uint8_t deviceIndex, uint8_t channel, uint8_t gain, uint8_t broadcast) {
|
||||
uint32_t mem_addr = REG_CH1_RX_GAIN + (channel & 0x03);
|
||||
adarWrite(deviceIndex, mem_addr, gain, broadcast);
|
||||
adarWrite(deviceIndex, REG_LOAD_WORKING, 0x1, broadcast);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarSetTxVgaGain(uint8_t deviceIndex, uint8_t channel, uint8_t gain, uint8_t broadcast) {
|
||||
uint32_t mem_addr = REG_CH1_TX_GAIN + (channel & 0x03);
|
||||
adarWrite(deviceIndex, mem_addr, gain, broadcast);
|
||||
adarWrite(deviceIndex, REG_LOAD_WORKING, LD_WRK_REGS_LDTX_OVERRIDE, broadcast);
|
||||
}
|
||||
|
||||
void ADAR1000Manager::adarSetTxBias(uint8_t deviceIndex, uint8_t broadcast) {
|
||||
adarWrite(deviceIndex, REG_BIAS_CURRENT_TX, 0x2D, broadcast);
|
||||
adarWrite(deviceIndex, REG_BIAS_CURRENT_TX_DRV, 0x06, broadcast);
|
||||
adarWrite(deviceIndex, REG_LOAD_WORKING, 0x2, broadcast);
|
||||
}
|
||||
|
||||
uint8_t ADAR1000Manager::adarAdcRead(uint8_t deviceIndex, uint8_t broadcast) {
|
||||
adarWrite(deviceIndex, REG_ADC_CONTROL, ADAR1000_ADC_ST_CONV, broadcast);
|
||||
|
||||
// Wait for conversion
|
||||
while (!(adarRead(deviceIndex, REG_ADC_CONTROL) & 0x01)) {
|
||||
// Busy wait
|
||||
}
|
||||
|
||||
return adarRead(deviceIndex, REG_ADC_OUT);
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
// ADAR1000_Manager.h
|
||||
#ifndef ADAR1000_MANAGER_H
|
||||
#define ADAR1000_MANAGER_H
|
||||
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "main.h"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
class ADAR1000Manager {
|
||||
public:
|
||||
enum class BeamDirection {
|
||||
TX = 0,
|
||||
RX = 1
|
||||
};
|
||||
|
||||
struct BeamConfig {
|
||||
float angle_degrees;
|
||||
uint8_t phase_settings[4];
|
||||
uint8_t gain_settings[4];
|
||||
uint32_t dwell_time_ms;
|
||||
|
||||
BeamConfig() : angle_degrees(0), dwell_time_ms(100) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
phase_settings[i] = 0;
|
||||
gain_settings[i] = 0x7F;
|
||||
}
|
||||
}
|
||||
|
||||
BeamConfig(float angle, uint32_t dwell = 100) : angle_degrees(angle), dwell_time_ms(dwell) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
phase_settings[i] = 0;
|
||||
gain_settings[i] = 0x7F;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ADAR1000Manager();
|
||||
~ADAR1000Manager();
|
||||
|
||||
// System Management
|
||||
bool powerUpSystem();
|
||||
bool powerDownSystem();
|
||||
bool initializeAllDevices();
|
||||
bool performSystemCalibration();
|
||||
|
||||
// Mode Switching
|
||||
void switchToTXMode();
|
||||
void switchToRXMode();
|
||||
void fastTXMode();
|
||||
void fastRXMode();
|
||||
void pulseTXMode();
|
||||
void pulseRXMode();
|
||||
|
||||
// Beam Steering
|
||||
bool setBeamAngle(float angle_degrees, BeamDirection direction);
|
||||
bool setCustomBeamPattern(const uint8_t phase_settings[16], const uint8_t gain_settings[4], BeamDirection direction);
|
||||
bool setCustomBeamPattern16(const uint8_t phase_pattern[16], BeamDirection direction);
|
||||
|
||||
// Beam Sweeping
|
||||
void startBeamSweeping();
|
||||
void stopBeamSweeping();
|
||||
void updateBeamPosition();
|
||||
void setBeamSequence(const std::vector<BeamConfig>& sequence, BeamDirection direction);
|
||||
void clearBeamSequence(BeamDirection direction);
|
||||
|
||||
// Device Control
|
||||
bool setAllDevicesTXMode();
|
||||
bool setAllDevicesRXMode();
|
||||
void setADTR1107Mode(BeamDirection direction);
|
||||
void setADTR1107Control(bool tx_mode);
|
||||
|
||||
// Monitoring and Diagnostics
|
||||
float readTemperature(uint8_t deviceIndex);
|
||||
bool verifyDeviceCommunication(uint8_t deviceIndex);
|
||||
uint8_t readRegister(uint8_t deviceIndex, uint32_t address);
|
||||
void writeRegister(uint8_t deviceIndex, uint32_t address, uint8_t value);
|
||||
|
||||
// Configuration
|
||||
void setSwitchSettlingTime(uint32_t us);
|
||||
void setFastSwitchMode(bool enable);
|
||||
void setBeamDwellTime(uint32_t ms);
|
||||
|
||||
// Getters
|
||||
bool isBeamSweepingActive() const { return beam_sweeping_active_; }
|
||||
uint8_t getCurrentBeamIndex() const { return current_beam_index_; }
|
||||
BeamDirection getCurrentMode() const { return current_mode_; }
|
||||
uint32_t getLastSwitchTime() const { return last_switch_time_us_; }
|
||||
|
||||
struct ADAR1000Device {
|
||||
uint8_t dev_addr;
|
||||
bool initialized;
|
||||
BeamDirection current_mode;
|
||||
float temperature;
|
||||
|
||||
ADAR1000Device(uint8_t addr)
|
||||
: dev_addr(addr), initialized(false), current_mode(BeamDirection::RX), temperature(25.0f) {
|
||||
}
|
||||
};
|
||||
|
||||
// Configuration
|
||||
bool fast_switch_mode_ = false;
|
||||
uint32_t switch_settling_time_us_ = 50;
|
||||
uint32_t beam_dwell_time_ms_ = 100;
|
||||
uint32_t last_switch_time_us_ = 0;
|
||||
|
||||
// Device Management
|
||||
std::vector<std::unique_ptr<ADAR1000Device>> devices_;
|
||||
BeamDirection current_mode_ = BeamDirection::RX;
|
||||
|
||||
// Beam Sweeping
|
||||
std::vector<BeamConfig> tx_beam_sequence_;
|
||||
std::vector<BeamConfig> rx_beam_sequence_;
|
||||
uint8_t current_beam_index_ = 0;
|
||||
bool beam_sweeping_active_ = false;
|
||||
uint32_t last_beam_update_time_ = 0;
|
||||
|
||||
// Lookup tables
|
||||
static const uint8_t VM_I[128];
|
||||
static const uint8_t VM_Q[128];
|
||||
static const uint8_t VM_GAIN[128];
|
||||
|
||||
// Private Methods
|
||||
bool initializeSingleDevice(uint8_t deviceIndex);
|
||||
bool initializeADTR1107Sequence();
|
||||
void calculatePhaseSettings(float angle_degrees, uint8_t phase_settings[4]);
|
||||
void delayUs(uint32_t microseconds);
|
||||
|
||||
// Power Management
|
||||
void enablePASupplies();
|
||||
void disablePASupplies();
|
||||
void enableLNASupplies();
|
||||
void disableLNASupplies();
|
||||
void setPABias(bool enable);
|
||||
void setLNABias(bool enable);
|
||||
|
||||
// SPI Communication
|
||||
void setChipSelect(uint8_t deviceIndex, bool state);
|
||||
uint32_t spiTransfer(uint8_t* txData, uint8_t* rxData, uint32_t size);
|
||||
void adarWrite(uint8_t deviceIndex, uint32_t mem_addr, uint8_t data, uint8_t broadcast);
|
||||
uint8_t adarRead(uint8_t deviceIndex, uint32_t mem_addr);
|
||||
void adarSetBit(uint8_t deviceIndex, uint32_t mem_addr, uint8_t bit, uint8_t broadcast);
|
||||
void adarResetBit(uint8_t deviceIndex, uint32_t mem_addr, uint8_t bit, uint8_t broadcast);
|
||||
void adarSoftReset(uint8_t deviceIndex);
|
||||
void adarWriteConfigA(uint8_t deviceIndex, uint8_t flags, uint8_t broadcast);
|
||||
void adarSetRamBypass(uint8_t deviceIndex, uint8_t broadcast);
|
||||
|
||||
// Channel Configuration
|
||||
void adarSetRxPhase(uint8_t deviceIndex, uint8_t channel, uint8_t phase, uint8_t broadcast);
|
||||
void adarSetTxPhase(uint8_t deviceIndex, uint8_t channel, uint8_t phase, uint8_t broadcast);
|
||||
void adarSetRxVgaGain(uint8_t deviceIndex, uint8_t channel, uint8_t gain, uint8_t broadcast);
|
||||
void adarSetTxVgaGain(uint8_t deviceIndex, uint8_t channel, uint8_t gain, uint8_t broadcast);
|
||||
void adarSetTxBias(uint8_t deviceIndex, uint8_t broadcast);
|
||||
uint8_t adarAdcRead(uint8_t deviceIndex, uint8_t broadcast);
|
||||
void setTRSwitchPosition(uint8_t deviceIndex, bool tx_mode);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
// Register Definitions
|
||||
#define BROADCAST_OFF 0
|
||||
#define BROADCAST_ON 1
|
||||
|
||||
#define REG_INTERFACE_CONFIG_A 0x000
|
||||
#define REG_SCRATCHPAD 0x00A
|
||||
#define REG_CH1_RX_GAIN 0x010
|
||||
#define REG_CH2_RX_GAIN 0x011
|
||||
#define REG_CH3_RX_GAIN 0x012
|
||||
#define REG_CH4_RX_GAIN 0x013
|
||||
#define REG_CH1_RX_PHS_I 0x014
|
||||
#define REG_CH1_RX_PHS_Q 0x015
|
||||
#define REG_CH2_RX_PHS_I 0x016
|
||||
#define REG_CH2_RX_PHS_Q 0x017
|
||||
#define REG_CH3_RX_PHS_I 0x018
|
||||
#define REG_CH3_RX_PHS_Q 0x019
|
||||
#define REG_CH4_RX_PHS_I 0x01A
|
||||
#define REG_CH4_RX_PHS_Q 0x01B
|
||||
#define REG_CH1_TX_GAIN 0x01C
|
||||
#define REG_CH2_TX_GAIN 0x01D
|
||||
#define REG_CH3_TX_GAIN 0x01E
|
||||
#define REG_CH4_TX_GAIN 0x01F
|
||||
#define REG_CH1_TX_PHS_I 0x020
|
||||
#define REG_CH1_TX_PHS_Q 0x021
|
||||
#define REG_CH2_TX_PHS_I 0x022
|
||||
#define REG_CH2_TX_PHS_Q 0x023
|
||||
#define REG_CH3_TX_PHS_I 0x024
|
||||
#define REG_CH3_TX_PHS_Q 0x025
|
||||
#define REG_CH4_TX_PHS_I 0x026
|
||||
#define REG_CH4_TX_PHS_Q 0x027
|
||||
#define REG_LOAD_WORKING 0x028
|
||||
#define REG_PA_CH1_BIAS_ON 0x029
|
||||
#define REG_PA_CH2_BIAS_ON 0x02A
|
||||
#define REG_PA_CH3_BIAS_ON 0x02B
|
||||
#define REG_PA_CH4_BIAS_ON 0x02C
|
||||
#define REG_LNA_BIAS_ON 0x02D
|
||||
#define REG_RX_ENABLES 0x02E
|
||||
#define REG_TX_ENABLES 0x02F
|
||||
#define REG_MISC_ENABLES 0x030
|
||||
#define REG_SW_CONTROL 0x031
|
||||
#define REG_ADC_CONTROL 0x032
|
||||
#define REG_ADC_OUT 0x033
|
||||
#define REG_BIAS_CURRENT_TX 0x036
|
||||
#define REG_BIAS_CURRENT_TX_DRV 0x037
|
||||
#define REG_MEM_CTL 0x038
|
||||
#define REG_PA_CH1_BIAS_OFF 0x046
|
||||
#define REG_PA_CH2_BIAS_OFF 0x047
|
||||
#define REG_PA_CH3_BIAS_OFF 0x048
|
||||
#define REG_PA_CH4_BIAS_OFF 0x049
|
||||
#define REG_LNA_BIAS_OFF 0x04A
|
||||
|
||||
// Register Constants
|
||||
#define INTERFACE_CONFIG_A_SDO_ACTIVE ((1 << 4) | (1 << 3))
|
||||
#define ADAR1000_ADC_2MHZ_CLK 0x00
|
||||
#define ADAR1000_ADC_EN 0x60
|
||||
#define ADAR1000_ADC_ST_CONV 0x70
|
||||
#define MEM_CTRL_BIAS_RAM_BYPASS (1 << 5)
|
||||
#define MEM_CTRL_BEAM_RAM_BYPASS (1 << 6)
|
||||
#define LD_WRK_REGS_LDTX_OVERRIDE (1 << 1)
|
||||
|
||||
#endif // ADAR1000_MANAGER_H
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef __ADS7830_H
|
||||
#define __ADS7830_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* I2C Address Definitions */
|
||||
#define ADS7830_DEFAULT_ADDRESS (0x48) // 1001 000 (ADDR = GND)
|
||||
#define ADS7830_VDD_ADDRESS (0x49) // 1001 001 (ADDR = VDD)
|
||||
#define ADS7830_SDA_ADDRESS (0x4A) // 1001 010 (ADDR = SDA)
|
||||
#define ADS7830_SCL_ADDRESS (0x4B) // 1001 011 (ADDR = SCL)
|
||||
|
||||
/* Conversion Delay (in ms) */
|
||||
#define ADS7830_CONVERSIONDELAY (1)
|
||||
|
||||
/* Command Byte Register Masks */
|
||||
#define ADS7830_REG_COMMAND_SD_MASK (0x80) // Single-Ended/Differential Inputs
|
||||
#define ADS7830_REG_COMMAND_SD_DIFF (0x00) // Bit = 0, Differential Inputs
|
||||
#define ADS7830_REG_COMMAND_SD_SINGLE (0x80) // Bit = 1, Single-Ended Inputs
|
||||
|
||||
#define ADS7830_REG_COMMAND_CH_MASK (0x70) // Input multiplexer Configuration
|
||||
#define ADS7830_REG_COMMAND_CH_DIFF_0_1 (0x00) // Differential P = CH0, N = CH1
|
||||
#define ADS7830_REG_COMMAND_CH_DIFF_2_3 (0x10) // Differential P = CH2, N = CH3
|
||||
#define ADS7830_REG_COMMAND_CH_DIFF_4_5 (0x20) // Differential P = CH4, N = CH5
|
||||
#define ADS7830_REG_COMMAND_CH_DIFF_6_7 (0x30) // Differential P = CH6, N = CH7
|
||||
#define ADS7830_REG_COMMAND_CH_DIFF_1_0 (0x40) // Differential P = CH1, N = CH0
|
||||
#define ADS7830_REG_COMMAND_CH_DIFF_3_2 (0x50) // Differential P = CH3, N = CH2
|
||||
#define ADS7830_REG_COMMAND_CH_DIFF_5_4 (0x60) // Differential P = CH5, N = CH4
|
||||
#define ADS7830_REG_COMMAND_CH_DIFF_7_6 (0x70) // Differential P = CH7, N = CH6
|
||||
#define ADS7830_REG_COMMAND_CH_SINGLE_0 (0x00) // Single-ended P = CH0, N = COM
|
||||
#define ADS7830_REG_COMMAND_CH_SINGLE_1 (0x10) // Single-ended P = CH1, N = COM
|
||||
#define ADS7830_REG_COMMAND_CH_SINGLE_2 (0x20) // Single-ended P = CH2, N = COM
|
||||
#define ADS7830_REG_COMMAND_CH_SINGLE_3 (0x30) // Single-ended P = CH3, N = COM
|
||||
#define ADS7830_REG_COMMAND_CH_SINGLE_4 (0x40) // Single-ended P = CH4, N = COM
|
||||
#define ADS7830_REG_COMMAND_CH_SINGLE_5 (0x50) // Single-ended P = CH5, N = COM
|
||||
#define ADS7830_REG_COMMAND_CH_SINGLE_6 (0x60) // Single-ended P = CH6, N = COM
|
||||
#define ADS7830_REG_COMMAND_CH_SINGLE_7 (0x70) // Single-ended P = CH7, N = COM
|
||||
|
||||
#define ADS7830_REG_COMMAND_PD_MASK (0x0C) // Power-Down Selection
|
||||
#define ADS7830_REG_COMMAND_PD_PDADCONV (0x00) // Power Down Between A/D Converter Conversions
|
||||
#define ADS7830_REG_COMMAND_PD_IROFF_ADON (0x04) // Internal Reference OFF and A/D Converter ON
|
||||
#define ADS7830_REG_COMMAND_PD_IRON_ADOFF (0x08) // Internal Reference ON and A/D Converter OFF
|
||||
#define ADS7830_REG_COMMAND_PD_IRON_ADON (0x0C) // Internal Reference ON and A/D Converter ON
|
||||
|
||||
/* Mode Enumerations */
|
||||
typedef enum {
|
||||
ADS7830_SDMODE_DIFF = ADS7830_REG_COMMAND_SD_DIFF,
|
||||
ADS7830_SDMODE_SINGLE = ADS7830_REG_COMMAND_SD_SINGLE
|
||||
} ADS7830_SDMode_t;
|
||||
|
||||
typedef enum {
|
||||
ADS7830_PDADCONV = ADS7830_REG_COMMAND_PD_PDADCONV,
|
||||
ADS7830_PDIROFF_ADON = ADS7830_REG_COMMAND_PD_IROFF_ADON,
|
||||
ADS7830_PDIRON_ADOFF = ADS7830_REG_COMMAND_PD_IRON_ADOFF,
|
||||
ADS7830_PDIRON_ADON = ADS7830_REG_COMMAND_PD_IRON_ADON
|
||||
} ADS7830_PDMode_t;
|
||||
|
||||
/* ADC Handle Structure */
|
||||
typedef struct {
|
||||
I2C_HandleTypeDef *hi2c;
|
||||
uint8_t i2c_addr;
|
||||
ADS7830_SDMode_t sdmode;
|
||||
ADS7830_PDMode_t pdmode;
|
||||
uint8_t conversion_delay;
|
||||
uint8_t last_conversion_result;
|
||||
} ADS7830_HandleTypeDef;
|
||||
|
||||
/* Function Prototypes */
|
||||
bool ADS7830_Init(ADS7830_HandleTypeDef *hadc, I2C_HandleTypeDef *hi2c, uint8_t i2c_addr,
|
||||
ADS7830_SDMode_t sdmode, ADS7830_PDMode_t pdmode);
|
||||
bool ADS7830_SetSDMode(ADS7830_HandleTypeDef *hadc, ADS7830_SDMode_t sdmode);
|
||||
bool ADS7830_SetPDMode(ADS7830_HandleTypeDef *hadc, ADS7830_PDMode_t pdmode);
|
||||
uint8_t ADS7830_Measure_SingleEnded(ADS7830_HandleTypeDef *hadc, uint8_t channel);
|
||||
int8_t ADS7830_Measure_Differential(ADS7830_HandleTypeDef *hadc, uint8_t channel);
|
||||
uint8_t ADS7830_GetLastConversionResult(ADS7830_HandleTypeDef *hadc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ADS7830_H */
|
||||
211
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.c
Normal file
211
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ADS7830.c
Normal file
@@ -0,0 +1,211 @@
|
||||
#include "ADS7830.h"
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @brief Initialize the ADS7830 ADC
|
||||
* @param hadc: pointer to an ADS7830_HandleTypeDef structure
|
||||
* @param hi2c: pointer to an I2C_HandleTypeDef structure
|
||||
* @param i2c_addr: I2C address of the ADC
|
||||
* @param sdmode: Single-ended or differential mode
|
||||
* @param pdmode: Power-down mode
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool ADS7830_Init(ADS7830_HandleTypeDef *hadc, I2C_HandleTypeDef *hi2c, uint8_t i2c_addr,
|
||||
ADS7830_SDMode_t sdmode, ADS7830_PDMode_t pdmode) {
|
||||
|
||||
if (hadc == NULL || hi2c == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hadc->hi2c = hi2c;
|
||||
hadc->i2c_addr = i2c_addr << 1; // HAL requires 7-bit address shifted left
|
||||
hadc->sdmode = sdmode;
|
||||
hadc->pdmode = pdmode;
|
||||
hadc->conversion_delay = ADS7830_CONVERSIONDELAY;
|
||||
hadc->last_conversion_result = 0;
|
||||
|
||||
/* Test communication by reading from a channel */
|
||||
return (ADS7830_Measure_SingleEnded(hadc, 0) != 0xFF); // 0xFF indicates communication error
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Single-Ended/Differential mode
|
||||
* @param hadc: pointer to an ADS7830_HandleTypeDef structure
|
||||
* @param sdmode: Single-ended or differential mode
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool ADS7830_SetSDMode(ADS7830_HandleTypeDef *hadc, ADS7830_SDMode_t sdmode) {
|
||||
if (hadc == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hadc->sdmode = sdmode;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Power-Down mode
|
||||
* @param hadc: pointer to an ADS7830_HandleTypeDef structure
|
||||
* @param pdmode: Power-down mode
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool ADS7830_SetPDMode(ADS7830_HandleTypeDef *hadc, ADS7830_PDMode_t pdmode) {
|
||||
if (hadc == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hadc->pdmode = pdmode;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Measure single-ended voltage on specified channel
|
||||
* @param hadc: pointer to an ADS7830_HandleTypeDef structure
|
||||
* @param channel: ADC channel (0-7)
|
||||
* @retval uint8_t: 8-bit conversion result (0-255), 0xFF on error
|
||||
*/
|
||||
uint8_t ADS7830_Measure_SingleEnded(ADS7830_HandleTypeDef *hadc, uint8_t channel) {
|
||||
if (hadc == NULL || channel > 7) {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
uint8_t config = 0;
|
||||
|
||||
// Set Single-Ended/Differential Inputs
|
||||
config |= hadc->sdmode;
|
||||
|
||||
// Set Power-Down Selection
|
||||
config |= hadc->pdmode;
|
||||
|
||||
// Set single-ended input channel
|
||||
switch (channel) {
|
||||
case (0):
|
||||
config |= ADS7830_REG_COMMAND_CH_SINGLE_0;
|
||||
break;
|
||||
case (1):
|
||||
config |= ADS7830_REG_COMMAND_CH_SINGLE_1;
|
||||
break;
|
||||
case (2):
|
||||
config |= ADS7830_REG_COMMAND_CH_SINGLE_2;
|
||||
break;
|
||||
case (3):
|
||||
config |= ADS7830_REG_COMMAND_CH_SINGLE_3;
|
||||
break;
|
||||
case (4):
|
||||
config |= ADS7830_REG_COMMAND_CH_SINGLE_4;
|
||||
break;
|
||||
case (5):
|
||||
config |= ADS7830_REG_COMMAND_CH_SINGLE_5;
|
||||
break;
|
||||
case (6):
|
||||
config |= ADS7830_REG_COMMAND_CH_SINGLE_6;
|
||||
break;
|
||||
case (7):
|
||||
config |= ADS7830_REG_COMMAND_CH_SINGLE_7;
|
||||
break;
|
||||
default:
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
// Write config register to the ADC
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hadc->hi2c, hadc->i2c_addr, &config, 1, HAL_MAX_DELAY);
|
||||
if (status != HAL_OK) {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
// Wait for the conversion to complete
|
||||
HAL_Delay(hadc->conversion_delay);
|
||||
|
||||
// Read the conversion results
|
||||
uint8_t result = 0;
|
||||
status = HAL_I2C_Master_Receive(hadc->hi2c, hadc->i2c_addr, &result, 1, HAL_MAX_DELAY);
|
||||
if (status != HAL_OK) {
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
hadc->last_conversion_result = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Measure differential voltage between specified channel pairs
|
||||
* @param hadc: pointer to an ADS7830_HandleTypeDef structure
|
||||
* @param channel: Channel pair (01, 10, 23, 32, 45, 54, 67, 76)
|
||||
* @retval int8_t: 8-bit signed conversion result (-128 to 127), 0x80 on error
|
||||
*/
|
||||
int8_t ADS7830_Measure_Differential(ADS7830_HandleTypeDef *hadc, uint8_t channel) {
|
||||
if (hadc == NULL) {
|
||||
return (int8_t)0x80;
|
||||
}
|
||||
|
||||
uint8_t config = 0;
|
||||
|
||||
// Set Single-Ended/Differential Inputs
|
||||
config |= hadc->sdmode;
|
||||
|
||||
// Set Power-Down Selection
|
||||
config |= hadc->pdmode;
|
||||
|
||||
// Set Differential input channel
|
||||
switch (channel) {
|
||||
case (01):
|
||||
config |= ADS7830_REG_COMMAND_CH_DIFF_0_1; // CH0 = P, CH1 = N
|
||||
break;
|
||||
case (10):
|
||||
config |= ADS7830_REG_COMMAND_CH_DIFF_1_0; // CH1 = P, CH0 = N
|
||||
break;
|
||||
case (23):
|
||||
config |= ADS7830_REG_COMMAND_CH_DIFF_2_3; // CH2 = P, CH3 = N
|
||||
break;
|
||||
case (32):
|
||||
config |= ADS7830_REG_COMMAND_CH_DIFF_3_2; // CH3 = P, CH2 = N
|
||||
break;
|
||||
case (45):
|
||||
config |= ADS7830_REG_COMMAND_CH_DIFF_4_5; // CH4 = P, CH5 = N
|
||||
break;
|
||||
case (54):
|
||||
config |= ADS7830_REG_COMMAND_CH_DIFF_5_4; // CH5 = P, CH4 = N
|
||||
break;
|
||||
case (67):
|
||||
config |= ADS7830_REG_COMMAND_CH_DIFF_6_7; // CH6 = P, CH7 = N
|
||||
break;
|
||||
case (76):
|
||||
config |= ADS7830_REG_COMMAND_CH_DIFF_7_6; // CH7 = P, CH6 = N
|
||||
break;
|
||||
default:
|
||||
return (int8_t)0x80;
|
||||
}
|
||||
|
||||
// Write config register to the ADC
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hadc->hi2c, hadc->i2c_addr, &config, 1, HAL_MAX_DELAY);
|
||||
if (status != HAL_OK) {
|
||||
return (int8_t)0x80;
|
||||
}
|
||||
|
||||
// Wait for the conversion to complete
|
||||
HAL_Delay(hadc->conversion_delay);
|
||||
|
||||
// Read the conversion results
|
||||
uint8_t raw_adc = 0;
|
||||
status = HAL_I2C_Master_Receive(hadc->hi2c, hadc->i2c_addr, &raw_adc, 1, HAL_MAX_DELAY);
|
||||
if (status != HAL_OK) {
|
||||
return (int8_t)0x80;
|
||||
}
|
||||
|
||||
// Convert to signed 8-bit value
|
||||
int8_t result = (int8_t)raw_adc;
|
||||
hadc->last_conversion_result = raw_adc;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the last conversion result
|
||||
* @param hadc: pointer to an ADS7830_HandleTypeDef structure
|
||||
* @retval uint8_t: Last conversion result
|
||||
*/
|
||||
uint8_t ADS7830_GetLastConversionResult(ADS7830_HandleTypeDef *hadc) {
|
||||
if (hadc == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return hadc->last_conversion_result;
|
||||
}
|
||||
462
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.cpp
Normal file
462
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.cpp
Normal file
@@ -0,0 +1,462 @@
|
||||
/***************************************************************************************************/
|
||||
/*
|
||||
This is an Arduino basic library for Bosch BMP180 & BMP085 barometric pressure &
|
||||
temperature sensor
|
||||
|
||||
Power supply voltage: 1.8v - 3.6v
|
||||
Range: 30,000Pa..110,000Pa at -40°C..+85°C
|
||||
Typ. resolution: 1Pa / 0.1°C
|
||||
Typ. accuracy: ±100Pa* / ±1.0°C* at 0°C..+65°C
|
||||
Typ. relative accuracy: ±12Pa / xx°C
|
||||
Duty cycle: 10% active & 90% inactive, to prevent self heating
|
||||
|
||||
*sensor is sensitive to direct light, which can affect
|
||||
the accuracy of the measurement
|
||||
|
||||
written by : enjoyneering79
|
||||
sourse code: https://github.com/enjoyneering/
|
||||
|
||||
|
||||
This chip uses I2C bus to communicate, specials pins are required to interface
|
||||
Board: SDA SCL Level
|
||||
Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 5v
|
||||
Mega2560................................. 20 21 5v
|
||||
Due, SAM3X8E............................. 20 21 3.3v
|
||||
Leonardo, Micro, ATmega32U4.............. 2 3 5v
|
||||
Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 5v
|
||||
Blue Pill, STM32F103xxxx boards.......... PB7 PB6 3.3v/5v
|
||||
ESP8266 ESP-01........................... GPIO0/D5 GPIO2/D3 3.3v/5v
|
||||
NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 3.3v/5v
|
||||
ESP32.................................... GPIO21/D21 GPIO22/D22 3.3v
|
||||
|
||||
NOTE:
|
||||
- EOC pin is not used, shows the end of conversion
|
||||
- XCLR pin is not used, reset pin
|
||||
|
||||
Frameworks & Libraries:
|
||||
ATtiny Core - https://github.com/SpenceKonde/ATTinyCore
|
||||
ESP32 Core - https://github.com/espressif/arduino-esp32
|
||||
ESP8266 Core - https://github.com/esp8266/Arduino
|
||||
STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32
|
||||
|
||||
GNU GPL license, all text above must be included in any redistribution,
|
||||
see link for details - https://www.gnu.org/licenses/licenses.html
|
||||
*/
|
||||
/***************************************************************************************************/
|
||||
|
||||
#include "BMP180.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Constructor
|
||||
|
||||
NOTE:
|
||||
- BMP180_ULTRALOWPOWER, pressure oversampled 1 time & consumption 3μA
|
||||
- BMP180_STANDARD, pressure oversampled 2 times & consumption 5μA
|
||||
- BMP180_HIGHRES, pressure oversampled 4 times & consumption 7μA
|
||||
- BMP180_ULTRAHIGHRES, pressure oversampled 8 times & consumption 12μA
|
||||
*/
|
||||
/**************************************************************************/
|
||||
BMP180::BMP180(BMP180_RESOLUTION res_mode)
|
||||
{
|
||||
_resolution = res_mode;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
getPressure()
|
||||
|
||||
Calculates compensated pressure, in Pa
|
||||
|
||||
NOTE:
|
||||
- resolutin 1Pa with accuracy ±150Pa at range 30,000Pa..110,000Pa
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int32_t BMP180::getPressure(void)
|
||||
{
|
||||
int32_t UT = 0;
|
||||
int32_t UP = 0;
|
||||
int32_t B3 = 0;
|
||||
int32_t B5 = 0;
|
||||
int32_t B6 = 0;
|
||||
int32_t X1 = 0;
|
||||
int32_t X2 = 0;
|
||||
int32_t X3 = 0;
|
||||
int32_t pressure = 0;
|
||||
uint32_t B4 = 0;
|
||||
uint32_t B7 = 0;
|
||||
|
||||
UT = readRawTemperature(); //read uncompensated temperature, 16-bit
|
||||
if (UT == BMP180_ERROR) return BMP180_ERROR; //error handler, collision on i2c bus
|
||||
|
||||
UP = readRawPressure(); //read uncompensated pressure, 19-bit
|
||||
if (UP == BMP180_ERROR) return BMP180_ERROR; //error handler, collision on i2c bus
|
||||
|
||||
B5 = computeB5(UT);
|
||||
|
||||
/* pressure calculation */
|
||||
B6 = B5 - 4000;
|
||||
X1 = ((int32_t)_calCoeff.bmpB2 * ((B6 * B6) >> 12)) >> 11;
|
||||
X2 = ((int32_t)_calCoeff.bmpAC2 * B6) >> 11;
|
||||
X3 = X1 + X2;
|
||||
B3 = ((((int32_t)_calCoeff.bmpAC1 * 4 + X3) << _resolution) + 2) / 4;
|
||||
|
||||
X1 = ((int32_t)_calCoeff.bmpAC3 * B6) >> 13;
|
||||
X2 = ((int32_t)_calCoeff.bmpB1 * ((B6 * B6) >> 12)) >> 16;
|
||||
X3 = ((X1 + X2) + 2) >> 2;
|
||||
B4 = ((uint32_t)_calCoeff.bmpAC4 * (X3 + 32768L)) >> 15;
|
||||
B7 = (UP - B3) * (50000UL >> _resolution);
|
||||
|
||||
if (B4 == 0) return BMP180_ERROR; //safety check, avoiding division by zero
|
||||
|
||||
if (B7 < 0x80000000) pressure = (B7 * 2) / B4;
|
||||
else pressure = (B7 / B4) * 2;
|
||||
|
||||
X1 = pow((pressure >> 8), 2);
|
||||
X1 = (X1 * 3038L) >> 16;
|
||||
X2 = (-7357L * pressure) >> 16;
|
||||
|
||||
return pressure = pressure + ((X1 + X2 + 3791L) >> 4);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
getTemperature()
|
||||
|
||||
Calculates compensated temperature, in °C
|
||||
|
||||
NOTE:
|
||||
- resolution 0.1°C with accuracy ±1.0°C at range 0°C..+65°C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
float BMP180::getTemperature(void)
|
||||
{
|
||||
int16_t rawTemperature = readRawTemperature();
|
||||
|
||||
if (rawTemperature == BMP180_ERROR) return BMP180_ERROR; //error handler, collision on i2c bus
|
||||
return (float)((computeB5(rawTemperature) + 8) >> 4) / 10;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
getSeaLevelPressure()
|
||||
|
||||
Converts current pressure to sea level pressure at specific true
|
||||
altitude, in Pa
|
||||
|
||||
NOTE:
|
||||
- true altitude is the actual elevation above sea level, to find out
|
||||
your current true altitude do search with google earth or gps
|
||||
- see level pressure is commonly used in weather reports & forecasts
|
||||
to compensate current true altitude
|
||||
- for example, we know that a sunny day happens if the current sea
|
||||
level pressure is 250Pa above the average sea level pressure of
|
||||
101325 Pa, so by converting the current pressure to sea level &
|
||||
comparing it with an average sea level pressure we can instantly
|
||||
predict the weather conditions
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int32_t BMP180::getSeaLevelPressure(int16_t trueAltitude)
|
||||
{
|
||||
int32_t pressure = getPressure();
|
||||
|
||||
if (pressure == BMP180_ERROR) return BMP180_ERROR;
|
||||
return (pressure / pow(1.0 - (float)trueAltitude / 44330, 5.255));
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
softReset()
|
||||
|
||||
Soft reset
|
||||
|
||||
NOTE:
|
||||
- performs the same sequence as power on reset
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void BMP180::softReset(void)
|
||||
{
|
||||
write8(BMP180_SOFT_RESET_REG, BMP180_SOFT_RESET_CTRL);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
readFirmwareVersion()
|
||||
|
||||
Reads ML & AL Version
|
||||
|
||||
NOTE:
|
||||
- ML version is LSB, 4-bit..0-bit
|
||||
- AL version is MSB, 7-bit..5-bit
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t BMP180::readFirmwareVersion(void)
|
||||
{
|
||||
return read8(BMP180_GET_VERSION_REG);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
readDeviceID()
|
||||
|
||||
Reads chip ID
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t BMP180::readDeviceID(void)
|
||||
{
|
||||
if (read8(BMP180_GET_ID_REG) == BMP180_CHIP_ID) return 180;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
readCalibrationCoefficients()
|
||||
|
||||
Reads factory calibration coefficients from E2PROM
|
||||
|
||||
NOTE:
|
||||
- every sensor module has individual calibration coefficients
|
||||
- before first temperature & pressure calculation master have to read
|
||||
calibration coefficients from 176-bit E2PROM
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool BMP180::readCalibrationCoefficients()
|
||||
{
|
||||
int32_t value = 0;
|
||||
|
||||
for (uint8_t reg = BMP180_CAL_AC1_REG; reg <= BMP180_CAL_MD_REG; reg++)
|
||||
{
|
||||
value = read16(reg);
|
||||
|
||||
if (value == BMP180_ERROR) return false; //error handler, collision on i2c bus
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case BMP180_CAL_AC1_REG: //used for pressure computation
|
||||
_calCoeff.bmpAC1 = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_AC2_REG: //used for pressure computation
|
||||
_calCoeff.bmpAC2 = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_AC3_REG: //used for pressure computation
|
||||
_calCoeff.bmpAC3 = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_AC4_REG: //used for pressure computation
|
||||
_calCoeff.bmpAC4 = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_AC5_REG: //used for temperature computation
|
||||
_calCoeff.bmpAC5 = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_AC6_REG: //used for temperature computation
|
||||
_calCoeff.bmpAC6 = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_B1_REG: //used for pressure computation
|
||||
_calCoeff.bmpB1 = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_B2_REG: //used for pressure computation
|
||||
_calCoeff.bmpB2 = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_MB_REG: //???
|
||||
_calCoeff.bmpMB = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_MC_REG: //used for temperature computation
|
||||
_calCoeff.bmpMC = value;
|
||||
break;
|
||||
|
||||
case BMP180_CAL_MD_REG: //used for temperature computation
|
||||
_calCoeff.bmpMD = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
readRawTemperature()
|
||||
|
||||
Reads raw/uncompensated temperature value, 16-bit
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint16_t BMP180::readRawTemperature(void)
|
||||
{
|
||||
/* send temperature measurement command */
|
||||
if (write8(BMP180_START_MEASURMENT_REG, BMP180_GET_TEMPERATURE_CTRL) != true) return BMP180_ERROR; //error handler, collision on i2c bus
|
||||
|
||||
/* set measurement delay */
|
||||
HAL_Delay(5);
|
||||
|
||||
/* read result */
|
||||
return read16(BMP180_READ_ADC_MSB_REG); //reads msb + lsb
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
readRawPressure()
|
||||
|
||||
Reads raw/uncompensated pressure value, 19-bits
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t BMP180::readRawPressure(void)
|
||||
{
|
||||
uint8_t regControl = 0;
|
||||
uint32_t rawPressure = 0;
|
||||
|
||||
/* convert resolution to register control */
|
||||
switch (_resolution)
|
||||
{
|
||||
case BMP180_ULTRALOWPOWER: //oss0
|
||||
regControl = BMP180_GET_PRESSURE_OSS0_CTRL;
|
||||
break;
|
||||
|
||||
case BMP180_STANDARD: //oss1
|
||||
regControl = BMP180_GET_PRESSURE_OSS1_CTRL;
|
||||
break;
|
||||
|
||||
case BMP180_HIGHRES: //oss2
|
||||
regControl = BMP180_GET_PRESSURE_OSS2_CTRL;
|
||||
break;
|
||||
|
||||
case BMP180_ULTRAHIGHRES: //oss3
|
||||
regControl = BMP180_GET_PRESSURE_OSS3_CTRL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send pressure measurement command */
|
||||
if (write8(BMP180_START_MEASURMENT_REG, regControl) != true) return BMP180_ERROR; //error handler, collision on i2c bus
|
||||
|
||||
/* set measurement delay */
|
||||
switch (_resolution)
|
||||
{
|
||||
case BMP180_ULTRALOWPOWER:
|
||||
HAL_Delay(5);
|
||||
break;
|
||||
|
||||
case BMP180_STANDARD:
|
||||
HAL_Delay(8);
|
||||
break;
|
||||
|
||||
case BMP180_HIGHRES:
|
||||
HAL_Delay(14);
|
||||
break;
|
||||
|
||||
case BMP180_ULTRAHIGHRES:
|
||||
HAL_Delay(26);
|
||||
break;
|
||||
}
|
||||
|
||||
/* read result msb + lsb */
|
||||
rawPressure = read16(BMP180_READ_ADC_MSB_REG); //16-bits
|
||||
if (rawPressure == BMP180_ERROR) return BMP180_ERROR; //error handler, collision on i2c bus
|
||||
|
||||
/* read result xlsb */
|
||||
rawPressure <<= 8;
|
||||
rawPressure |= read8(BMP180_READ_ADC_XLSB_REG); //19-bits
|
||||
|
||||
rawPressure >>= (8 - _resolution);
|
||||
|
||||
return rawPressure;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
computeB5()
|
||||
|
||||
Computes B5 value
|
||||
|
||||
NOTE:
|
||||
- to compensate raw/uncompensated temperature
|
||||
- also used for compensated pressure calculation
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int32_t BMP180::computeB5(int32_t UT)
|
||||
{
|
||||
int32_t X1 = ((UT - (int32_t)_calCoeff.bmpAC6) * (int32_t)_calCoeff.bmpAC5) >> 15;
|
||||
int32_t X2 = ((int32_t)_calCoeff.bmpMC << 11) / (X1 + (int32_t)_calCoeff.bmpMD);
|
||||
|
||||
return X1 + X2;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
read8()
|
||||
|
||||
Reads 8-bit value over I2C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t BMP180::read8(uint8_t reg)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
// Write register address
|
||||
status = HAL_I2C_Master_Transmit(&hi2c3, BMP180_ADDRESS, ®, 1, I2C_TIMEOUT);
|
||||
if (status != HAL_OK) return BMP180_ERROR;
|
||||
|
||||
// Read data from register
|
||||
status = HAL_I2C_Master_Receive(&hi2c3, BMP180_ADDRESS, &data, 1, I2C_TIMEOUT);
|
||||
if (status != HAL_OK) return BMP180_ERROR;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
read16()
|
||||
|
||||
Reads 16-bits value over I2C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
uint16_t BMP180::read16(uint8_t reg)
|
||||
{
|
||||
uint8_t data[2] = {0, 0};
|
||||
uint16_t value = 0;
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
// Write register address
|
||||
status = HAL_I2C_Master_Transmit(&hi2c3, BMP180_ADDRESS, ®, 1, I2C_TIMEOUT);
|
||||
if (status != HAL_OK) return BMP180_ERROR;
|
||||
|
||||
// Read 2 bytes from register
|
||||
status = HAL_I2C_Master_Receive(&hi2c3, BMP180_ADDRESS, data, 2, I2C_TIMEOUT);
|
||||
if (status != HAL_OK) return BMP180_ERROR;
|
||||
|
||||
// Combine bytes (MSB first)
|
||||
value = (data[0] << 8) | data[1];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
write8()
|
||||
|
||||
Writes 8-bits value over I2C
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
bool BMP180::write8(uint8_t reg, uint8_t control)
|
||||
{
|
||||
uint8_t data[2] = {reg, control};
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
// Write register address and data
|
||||
status = HAL_I2C_Master_Transmit(&hi2c3, BMP180_ADDRESS, data, 2, I2C_TIMEOUT);
|
||||
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
156
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.h
Normal file
156
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/BMP180.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/***************************************************************************************************/
|
||||
/*
|
||||
This is an Arduino basic library for Bosch BMP180 & BMP085 barometric pressure &
|
||||
temperature sensor
|
||||
|
||||
Power supply voltage: 1.8v - 3.6v
|
||||
Range: 30,000Pa..110,000Pa at -40°C..+85°C
|
||||
Typ. resolution: 1Pa / 0.1°C
|
||||
Typ. accuracy: ±100Pa* / ±1.0°C* at 0°C..+65°C
|
||||
Typ. relative accuracy: ±12Pa / xx°C
|
||||
Duty cycle: 10% active & 90% inactive, to prevent self heating
|
||||
|
||||
*sensor is sensitive to direct light, which can affect
|
||||
the accuracy of the measurement
|
||||
|
||||
written by : enjoyneering79
|
||||
sourse code: https://github.com/enjoyneering/
|
||||
|
||||
|
||||
This chip uses I2C bus to communicate, specials pins are required to interface
|
||||
Board: SDA SCL Level
|
||||
Uno, Mini, Pro, ATmega168, ATmega328..... A4 A5 5v
|
||||
Mega2560................................. 20 21 5v
|
||||
Due, SAM3X8E............................. 20 21 3.3v
|
||||
Leonardo, Micro, ATmega32U4.............. 2 3 5v
|
||||
Digistump, Trinket, ATtiny85............. 0/physical pin no.5 2/physical pin no.7 5v
|
||||
Blue Pill, STM32F103xxxx boards.......... PB7 PB6 3.3v/5v
|
||||
ESP8266 ESP-01........................... GPIO0/D5 GPIO2/D3 3.3v/5v
|
||||
NodeMCU 1.0, WeMos D1 Mini............... GPIO4/D2 GPIO5/D1 3.3v/5v
|
||||
ESP32.................................... GPIO21/D21 GPIO22/D22 3.3v
|
||||
|
||||
NOTE:
|
||||
- EOC pin is not used, shows the end of conversion
|
||||
- XCLR pin is not used, reset pin
|
||||
|
||||
Frameworks & Libraries:
|
||||
ATtiny Core - https://github.com/SpenceKonde/ATTinyCore
|
||||
ESP32 Core - https://github.com/espressif/arduino-esp32
|
||||
ESP8266 Core - https://github.com/esp8266/Arduino
|
||||
STM32 Core - https://github.com/rogerclarkmelbourne/Arduino_STM32
|
||||
|
||||
GNU GPL license, all text above must be included in any redistribution,
|
||||
see link for details - https://www.gnu.org/licenses/licenses.html
|
||||
*/
|
||||
/***************************************************************************************************/
|
||||
|
||||
#ifndef BMP180_h
|
||||
#define BMP180_h
|
||||
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include <cmath>
|
||||
|
||||
extern I2C_HandleTypeDef hi2c3;
|
||||
|
||||
/* resolutions */
|
||||
typedef enum : uint8_t
|
||||
{
|
||||
BMP180_ULTRALOWPOWER = 0x00, //low power mode, oss0
|
||||
BMP180_STANDARD = 0x01, //standard mode, oss1
|
||||
BMP180_HIGHRES = 0x02, //high resolution mode, oss2
|
||||
BMP180_ULTRAHIGHRES = 0x03 //ultra high resolution mode, oss3
|
||||
}
|
||||
BMP180_RESOLUTION;
|
||||
|
||||
|
||||
/* calibration registers */
|
||||
typedef enum : uint8_t
|
||||
{
|
||||
BMP180_CAL_AC1_REG = 0xAA, //ac1 pressure computation
|
||||
BMP180_CAL_AC2_REG = 0xAC, //ac2 pressure computation
|
||||
BMP180_CAL_AC3_REG = 0xAE, //ac3 pressure computation
|
||||
BMP180_CAL_AC4_REG = 0xB0, //ac4 pressure computation
|
||||
BMP180_CAL_AC5_REG = 0xB2, //ac5 temperature computation
|
||||
BMP180_CAL_AC6_REG = 0xB4, //ac6 temperature computation
|
||||
BMP180_CAL_B1_REG = 0xB6, //b1 pressure computation
|
||||
BMP180_CAL_B2_REG = 0xB8, //b2 pressure computation
|
||||
BMP180_CAL_MB_REG = 0xBA, //mb
|
||||
BMP180_CAL_MC_REG = 0xBC, //mc temperature computation
|
||||
BMP180_CAL_MD_REG = 0xBE //md temperature computation
|
||||
}
|
||||
BMP180_CAL_REG;
|
||||
|
||||
#define BMP180_GET_ID_REG 0xD0 //device id register
|
||||
#define BMP180_GET_VERSION_REG 0xD1 //device version register
|
||||
|
||||
#define BMP180_SOFT_RESET_REG 0xE0 //soft reset register
|
||||
#define BMP180_SOFT_RESET_CTRL 0xB6 //soft reset control
|
||||
|
||||
#define BMP180_START_MEASURMENT_REG 0xF4 //start measurment register
|
||||
#define BMP180_READ_ADC_MSB_REG 0xF6 //read adc msb register
|
||||
#define BMP180_READ_ADC_LSB_REG 0xF7 //read adc lsb register
|
||||
#define BMP180_READ_ADC_XLSB_REG 0xF8 //read adc xlsb register
|
||||
|
||||
/* BMP180_START_MEASURMENT_REG controls */
|
||||
#define BMP180_GET_TEMPERATURE_CTRL 0x2E //get temperature control
|
||||
#define BMP180_GET_PRESSURE_OSS0_CTRL 0x34 //get pressure oversampling 1 time/oss0 control
|
||||
#define BMP180_GET_PRESSURE_OSS1_CTRL 0x74 //get pressure oversampling 2 time/oss1 control
|
||||
#define BMP180_GET_PRESSURE_OSS2_CTRL 0xB4 //get pressure oversampling 4 time/oss2 control
|
||||
#define BMP180_GET_PRESSURE_OSS3_CTRL 0xF4 //get pressure oversampling 8 time/oss3 control
|
||||
|
||||
/* misc */
|
||||
#define BMP180_CHIP_ID 0x55 //id number
|
||||
|
||||
#define BMP180_ERROR 255 //returns 255, if communication error is occurred
|
||||
|
||||
#define BMP180_ADDRESS (0x77 << 1) // HAL requires 7-bit address shifted left by 1 bit
|
||||
|
||||
#define I2C_TIMEOUT 100
|
||||
|
||||
/* to store calibration coefficients */
|
||||
typedef struct
|
||||
{
|
||||
int16_t bmpAC1 = 0;
|
||||
int16_t bmpAC2 = 0;
|
||||
int16_t bmpAC3 = 0;
|
||||
uint16_t bmpAC4 = 0;
|
||||
uint16_t bmpAC5 = 0;
|
||||
uint16_t bmpAC6 = 0;
|
||||
|
||||
int16_t bmpB1 = 0;
|
||||
int16_t bmpB2 = 0;
|
||||
|
||||
int16_t bmpMB = 0;
|
||||
int16_t bmpMC = 0;
|
||||
int16_t bmpMD = 0;
|
||||
}
|
||||
BMP180_CAL_COEFF;
|
||||
|
||||
|
||||
class BMP180
|
||||
{
|
||||
public:
|
||||
BMP180(BMP180_RESOLUTION = BMP180_ULTRAHIGHRES); //BMP180_ULTRAHIGHRES, by default
|
||||
int32_t getPressure(void); //in Pa
|
||||
float getTemperature(void); //in °C
|
||||
int32_t getSeaLevelPressure(int16_t trueAltitude = 115); //in Pa, by default true altitude id 115 meters
|
||||
void softReset(void);
|
||||
uint8_t readFirmwareVersion(void);
|
||||
uint8_t readDeviceID(void);
|
||||
|
||||
|
||||
private:
|
||||
BMP180_CAL_COEFF _calCoeff;
|
||||
|
||||
uint8_t _resolution;
|
||||
|
||||
bool readCalibrationCoefficients(void);
|
||||
uint16_t readRawTemperature(void);
|
||||
uint32_t readRawPressure(void);
|
||||
int32_t computeB5(int32_t UT);
|
||||
uint8_t read8(uint8_t reg);
|
||||
uint16_t read16(uint8_t reg);
|
||||
bool write8(uint8_t reg, uint8_t control);
|
||||
};
|
||||
|
||||
#endif
|
||||
397
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DA5578.c
Normal file
397
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/DA5578.c
Normal file
@@ -0,0 +1,397 @@
|
||||
#include "DAC5578.h"
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @brief Initialize the DAC5578
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param hi2c: pointer to an I2C_HandleTypeDef structure
|
||||
* @param i2c_addr: I2C address of the DAC
|
||||
* @param resolution: DAC resolution (only 8 is valid for DAC5578)
|
||||
* @param ldac_port: GPIO port for LDAC pin
|
||||
* @param ldac_pin: GPIO pin for LDAC pin
|
||||
* @param clr_port: GPIO port for CLR pin
|
||||
* @param clr_pin: GPIO pin for CLR pin
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_Init(DAC5578_HandleTypeDef *hdac, I2C_HandleTypeDef *hi2c, uint8_t i2c_addr,
|
||||
uint8_t resolution, GPIO_TypeDef *ldac_port, uint16_t ldac_pin,
|
||||
GPIO_TypeDef *clr_port, uint16_t clr_pin) {
|
||||
|
||||
if (hdac == NULL || hi2c == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* DAC5578 is 8-bit only */
|
||||
hdac->resolution_bits = 8;
|
||||
hdac->clear_code = DAC5578_CLR_CODE_ZERO; // Default clear to zero
|
||||
|
||||
hdac->hi2c = hi2c;
|
||||
hdac->i2c_addr = i2c_addr << 1; // HAL requires 7-bit address shifted left
|
||||
hdac->ldac_port = ldac_port;
|
||||
hdac->ldac_pin = ldac_pin;
|
||||
hdac->clr_port = clr_port;
|
||||
hdac->clr_pin = clr_pin;
|
||||
|
||||
/* Set LDAC high (inactive) and CLR high (normal operation) */
|
||||
if (ldac_port != NULL) {
|
||||
HAL_GPIO_WritePin(ldac_port, ldac_pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
if (clr_port != NULL) {
|
||||
HAL_GPIO_WritePin(clr_port, clr_pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/* Reset the DAC and enable internal reference by default */
|
||||
bool success = DAC5578_Reset(hdac);
|
||||
if (success) {
|
||||
success = DAC5578_SetInternalReference(hdac, true);
|
||||
}
|
||||
|
||||
/* Set the clear code in the device */
|
||||
if (success) {
|
||||
success = DAC5578_SetClearCode(hdac, hdac->clear_code);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the DAC5578
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_Reset(DAC5578_HandleTypeDef *hdac) {
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = DAC5578_CMD_RESET;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x00;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a value to a specific channel's input register
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param channel: DAC channel (0-7)
|
||||
* @param value: 8-bit value to write
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_WriteChannelValue(DAC5578_HandleTypeDef *hdac, uint8_t channel, uint16_t value) {
|
||||
if (channel > 7) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* DAC5578 is 8-bit, so mask value */
|
||||
value &= 0xFF;
|
||||
|
||||
return DAC5578_CommandWrite(hdac, DAC5578_CMD_WRITE | (channel & 0x7), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update a specific channel's DAC register from input register
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param channel: DAC channel (0-7) or DAC5578_CHANNEL_BROADCAST
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_UpdateChannel(DAC5578_HandleTypeDef *hdac, uint8_t channel) {
|
||||
if (channel > 7 && channel != DAC5578_CHANNEL_BROADCAST) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Update command with channel selection */
|
||||
uint8_t command = DAC5578_CMD_UPDATE | (channel & 0x7);
|
||||
if (channel == DAC5578_CHANNEL_BROADCAST) {
|
||||
command = DAC5578_CMD_UPDATE | 0x8; // Broadcast flag
|
||||
}
|
||||
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = command;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x00;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write and update a specific channel in one operation
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param channel: DAC channel (0-7)
|
||||
* @param value: 8-bit value to write and update
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_WriteAndUpdateChannelValue(DAC5578_HandleTypeDef *hdac, uint8_t channel, uint16_t value) {
|
||||
if (channel > 7) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* DAC5578 is 8-bit, so mask value */
|
||||
value &= 0xFF;
|
||||
|
||||
return DAC5578_CommandWrite(hdac, DAC5578_CMD_WRITE_UPDATE | (channel & 0x7), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the same value to all channels' input registers
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param value: 8-bit value to write to all channels
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_WriteAllChannels(DAC5578_HandleTypeDef *hdac, uint16_t value) {
|
||||
/* DAC5578 is 8-bit, so mask value */
|
||||
value &= 0xFF;
|
||||
|
||||
return DAC5578_CommandWrite(hdac, DAC5578_CMD_WRITE_ALL, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the input register value of a specific channel
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param channel: DAC channel (0-7)
|
||||
* @param value: pointer to store the read value
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_ReadInputChannelValue(DAC5578_HandleTypeDef *hdac, uint8_t channel, uint16_t *value) {
|
||||
if (channel > 7) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Note: DAC5578 has limited read capability - this reads back the input register */
|
||||
return DAC5578_CommandRead(hdac, DAC5578_CMD_WRITE | (channel & 0x7), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the DAC register value (current output) of a specific channel
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param channel: DAC channel (0-7)
|
||||
* @param value: pointer to store the read value
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_ReadDACChannelValue(DAC5578_HandleTypeDef *hdac, uint8_t channel, uint16_t *value) {
|
||||
if (channel > 7) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Note: DAC5578 has limited read capability - this reads back the DAC register */
|
||||
return DAC5578_CommandRead(hdac, DAC5578_CMD_UPDATE | (channel & 0x7), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set power down mode for a specific channel
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param channel: DAC channel (0-7)
|
||||
* @param mode: power down mode
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_SetPowerDownMode(DAC5578_HandleTypeDef *hdac, uint8_t channel, DAC5578_PowerDownMode_t mode) {
|
||||
if (channel > 7 || mode > 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = DAC5578_CMD_POWERDOWN | (channel & 0x7);
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = mode & 0x03;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set power down mode for all channels
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param mode: power down mode
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_SetPowerDownAll(DAC5578_HandleTypeDef *hdac, DAC5578_PowerDownMode_t mode) {
|
||||
if (mode > 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = DAC5578_CMD_POWERDOWN_ALL;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = mode & 0x03;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the internal reference
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param enable: true to enable, false to disable
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_SetInternalReference(DAC5578_HandleTypeDef *hdac, bool enable) {
|
||||
uint8_t command = enable ? DAC5578_CMD_INT_REF_ENABLE : DAC5578_CMD_INT_REF_DISABLE;
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = command;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x00;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup LDAC mask for hardware LDAC control
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param ldac_mask: 8-bit mask where each bit corresponds to a channel
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_SetupLDAC(DAC5578_HandleTypeDef *hdac, uint8_t ldac_mask) {
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = DAC5578_CMD_LDAC_SETUP;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = ldac_mask & 0xFF; // Each bit corresponds to a channel (0-7)
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger software LDAC update
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_SoftwareLDAC(DAC5578_HandleTypeDef *hdac) {
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = DAC5578_CMD_SOFTWARE_LDAC;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x00;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
/* CLR Pin Functions */
|
||||
|
||||
/**
|
||||
* @brief Set the clear code that determines what happens when CLR pin is activated
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param clear_code: desired clear code behavior
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_SetClearCode(DAC5578_HandleTypeDef *hdac, DAC5578_ClearCode_t clear_code) {
|
||||
if (clear_code > DAC5578_CLR_CODE_NOP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The clear code is set using the RESET command with specific data bits */
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = DAC5578_CMD_RESET;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = (clear_code & 0x03); // Clear code in bits 1:0
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
|
||||
if (status == HAL_OK) {
|
||||
hdac->clear_code = clear_code;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current clear code setting
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @retval DAC5578_ClearCode_t: current clear code setting
|
||||
*/
|
||||
DAC5578_ClearCode_t DAC5578_GetClearCode(DAC5578_HandleTypeDef *hdac) {
|
||||
return hdac->clear_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Activate the CLR pin (set low) to clear DAC outputs
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @retval None
|
||||
*/
|
||||
void DAC5578_ActivateClearPin(DAC5578_HandleTypeDef *hdac) {
|
||||
if (hdac->clr_port != NULL) {
|
||||
HAL_GPIO_WritePin(hdac->clr_port, hdac->clr_pin, GPIO_PIN_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivate the CLR pin (set high) for normal operation
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @retval None
|
||||
*/
|
||||
void DAC5578_DeactivateClearPin(DAC5578_HandleTypeDef *hdac) {
|
||||
if (hdac->clr_port != NULL) {
|
||||
HAL_GPIO_WritePin(hdac->clr_port, hdac->clr_pin, GPIO_PIN_SET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pulse the CLR pin to clear all DAC outputs according to clear code
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @retval None
|
||||
*/
|
||||
void DAC5578_ClearOutputs(DAC5578_HandleTypeDef *hdac) {
|
||||
if (hdac->clr_port != NULL) {
|
||||
/* Generate a pulse on CLR pin (active low) */
|
||||
HAL_GPIO_WritePin(hdac->clr_port, hdac->clr_pin, GPIO_PIN_RESET);
|
||||
HAL_Delay(1); // Hold for at least 50ns (1ms is plenty)
|
||||
HAL_GPIO_WritePin(hdac->clr_port, hdac->clr_pin, GPIO_PIN_SET);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Software clear - uses I2C command to clear outputs without CLR pin
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_SoftwareClear(DAC5578_HandleTypeDef *hdac) {
|
||||
/* Use the reset command with the current clear code to perform software clear */
|
||||
return DAC5578_SetClearCode(hdac, hdac->clear_code);
|
||||
}
|
||||
|
||||
/* Private functions */
|
||||
|
||||
/**
|
||||
* @brief Write a command and value to the DAC
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param command: command byte
|
||||
* @param value: 8-bit value to write
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_CommandWrite(DAC5578_HandleTypeDef *hdac, uint8_t command, uint16_t value) {
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = command;
|
||||
buffer[1] = (value >> 8) & 0xFF; // MSB (should be 0 for 8-bit DAC)
|
||||
buffer[2] = value & 0xFF; // LSB (actual 8-bit data)
|
||||
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
return (status == HAL_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a value from the DAC after sending a command
|
||||
* @param hdac: pointer to a DAC5578_HandleTypeDef structure
|
||||
* @param command: command byte
|
||||
* @param value: pointer to store the read value
|
||||
* @retval bool: true if successful, false otherwise
|
||||
*/
|
||||
bool DAC5578_CommandRead(DAC5578_HandleTypeDef *hdac, uint8_t command, uint16_t *value) {
|
||||
uint8_t buffer[3];
|
||||
|
||||
/* First write the command to set up readback */
|
||||
HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(hdac->hi2c, hdac->i2c_addr, &command, 1, HAL_MAX_DELAY);
|
||||
if (status != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Then read 3 bytes back */
|
||||
status = HAL_I2C_Master_Receive(hdac->hi2c, hdac->i2c_addr, buffer, 3, HAL_MAX_DELAY);
|
||||
if (status != HAL_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Extract the 8-bit value from the response */
|
||||
*value = buffer[2] & 0xFF;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#ifndef __DAC5578_H
|
||||
#define __DAC5578_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
|
||||
extern I2C_HandleTypeDef hi2c1;
|
||||
|
||||
/* Command definitions - DAC5578 specific */
|
||||
#define DAC5578_CMD_WRITE (0x0 << 4) // Write to input register
|
||||
#define DAC5578_CMD_UPDATE (0x1 << 4) // Update DAC register
|
||||
#define DAC5578_CMD_WRITE_UPDATE (0x2 << 4) // Write and update
|
||||
#define DAC5578_CMD_WRITE_ALL (0x3 << 4) // Write to all channels
|
||||
#define DAC5578_CMD_POWERDOWN (0x4 << 4) // Power down
|
||||
#define DAC5578_CMD_POWERDOWN_ALL (0x5 << 4) // Power down all channels
|
||||
#define DAC5578_CMD_INT_REF_ENABLE (0x6 << 4) // Enable internal reference
|
||||
#define DAC5578_CMD_INT_REF_DISABLE (0x7 << 4) // Disable internal reference
|
||||
#define DAC5578_CMD_RESET (0x8 << 4) // Software reset
|
||||
#define DAC5578_CMD_LDAC_SETUP (0x9 << 4) // LDAC setup register
|
||||
#define DAC5578_CMD_SOFTWARE_LDAC (0xA << 4) // Software LDAC trigger
|
||||
|
||||
/* Broadcast channel for simultaneous updates */
|
||||
#define DAC5578_CHANNEL_BROADCAST 0x8
|
||||
|
||||
/* Power down modes */
|
||||
typedef enum {
|
||||
DAC5578_PWD_NORMAL = 0, // Normal operation
|
||||
DAC5578_PWD_1K = 1, // 1kΩ to GND
|
||||
DAC5578_PWD_100K = 2, // 100kΩ to GND
|
||||
DAC5578_PWD_HIZ = 3 // High impedance
|
||||
} DAC5578_PowerDownMode_t;
|
||||
|
||||
/* Clear code options - determines what happens when CLR pin is activated */
|
||||
typedef enum {
|
||||
DAC5578_CLR_CODE_ZERO = 0, // Clear to zero scale (0x00)
|
||||
DAC5578_CLR_CODE_MID = 1, // Clear to midscale (0x80)
|
||||
DAC5578_CLR_CODE_FULL = 2, // Clear to full scale (0xFF)
|
||||
DAC5578_CLR_CODE_NOP = 3 // No operation (retain current value)
|
||||
} DAC5578_ClearCode_t;
|
||||
|
||||
/* DAC handle structure */
|
||||
typedef struct {
|
||||
I2C_HandleTypeDef *hi2c;
|
||||
uint8_t i2c_addr;
|
||||
uint8_t resolution_bits;
|
||||
GPIO_TypeDef *ldac_port;
|
||||
uint16_t ldac_pin;
|
||||
GPIO_TypeDef *clr_port;
|
||||
uint16_t clr_pin;
|
||||
DAC5578_ClearCode_t clear_code; // Current clear code setting
|
||||
} DAC5578_HandleTypeDef;
|
||||
|
||||
/* Function prototypes */
|
||||
bool DAC5578_Init(DAC5578_HandleTypeDef *hdac, I2C_HandleTypeDef *hi2c, uint8_t i2c_addr,
|
||||
uint8_t resolution, GPIO_TypeDef *ldac_port, uint16_t ldac_pin,
|
||||
GPIO_TypeDef *clr_port, uint16_t clr_pin);
|
||||
bool DAC5578_Reset(DAC5578_HandleTypeDef *hdac);
|
||||
bool DAC5578_WriteChannelValue(DAC5578_HandleTypeDef *hdac, uint8_t channel, uint16_t value);
|
||||
bool DAC5578_UpdateChannel(DAC5578_HandleTypeDef *hdac, uint8_t channel);
|
||||
bool DAC5578_WriteAndUpdateChannelValue(DAC5578_HandleTypeDef *hdac, uint8_t channel, uint16_t value);
|
||||
bool DAC5578_WriteAllChannels(DAC5578_HandleTypeDef *hdac, uint16_t value);
|
||||
bool DAC5578_ReadInputChannelValue(DAC5578_HandleTypeDef *hdac, uint8_t channel, uint16_t *value);
|
||||
bool DAC5578_ReadDACChannelValue(DAC5578_HandleTypeDef *hdac, uint8_t channel, uint16_t *value);
|
||||
bool DAC5578_SetPowerDownMode(DAC5578_HandleTypeDef *hdac, uint8_t channel, DAC5578_PowerDownMode_t mode);
|
||||
bool DAC5578_SetPowerDownAll(DAC5578_HandleTypeDef *hdac, DAC5578_PowerDownMode_t mode);
|
||||
bool DAC5578_SetInternalReference(DAC5578_HandleTypeDef *hdac, bool enable);
|
||||
bool DAC5578_SetupLDAC(DAC5578_HandleTypeDef *hdac, uint8_t ldac_mask);
|
||||
bool DAC5578_SoftwareLDAC(DAC5578_HandleTypeDef *hdac);
|
||||
|
||||
/* CLR Pin Functions */
|
||||
bool DAC5578_SetClearCode(DAC5578_HandleTypeDef *hdac, DAC5578_ClearCode_t clear_code);
|
||||
DAC5578_ClearCode_t DAC5578_GetClearCode(DAC5578_HandleTypeDef *hdac);
|
||||
void DAC5578_ActivateClearPin(DAC5578_HandleTypeDef *hdac);
|
||||
void DAC5578_DeactivateClearPin(DAC5578_HandleTypeDef *hdac);
|
||||
void DAC5578_ClearOutputs(DAC5578_HandleTypeDef *hdac); // Pulse CLR pin to clear outputs
|
||||
|
||||
/* Private functions */
|
||||
bool DAC5578_CommandWrite(DAC5578_HandleTypeDef *hdac, uint8_t command, uint16_t value);
|
||||
bool DAC5578_CommandRead(DAC5578_HandleTypeDef *hdac, uint8_t command, uint16_t *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DAC5578_H */
|
||||
121
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.c
Normal file
121
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/GY_85_HAL.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "GY_85_HAL.h"
|
||||
|
||||
static int16_t g_offx = 0, g_offy = 0, g_offz = 0;
|
||||
|
||||
// ---------------- Internal Functions ---------------- //
|
||||
static void GY85_SetAccelerometer(void);
|
||||
static void GY85_ReadAccelerometer(GY85_t *imu);
|
||||
static void GY85_SetCompass(void);
|
||||
static void GY85_ReadCompass(GY85_t *imu);
|
||||
static void GY85_SetGyro(void);
|
||||
static void GY85_GyroCalibrate(void);
|
||||
static void GY85_ReadGyro(GY85_t *imu);
|
||||
|
||||
// ---------------- Initialization ---------------- //
|
||||
void GY85_Init(void)
|
||||
{
|
||||
GY85_SetAccelerometer();
|
||||
GY85_SetCompass();
|
||||
GY85_SetGyro();
|
||||
}
|
||||
|
||||
// ---------------- Update All Sensors ---------------- //
|
||||
void GY85_Update(GY85_t *imu)
|
||||
{
|
||||
GY85_ReadAccelerometer(imu);
|
||||
GY85_ReadCompass(imu);
|
||||
GY85_ReadGyro(imu);
|
||||
}
|
||||
|
||||
// ---------------- Accelerometer ---------------- //
|
||||
static void GY85_SetAccelerometer(void)
|
||||
{
|
||||
uint8_t data[2];
|
||||
data[0] = 0x31; data[1] = 0x01;
|
||||
HAL_I2C_Master_Transmit(&hi2c3, ADXL345_ADDR, data, 2, HAL_MAX_DELAY);
|
||||
|
||||
data[0] = 0x2D; data[1] = 0x08;
|
||||
HAL_I2C_Master_Transmit(&hi2c3, ADXL345_ADDR, data, 2, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
static void GY85_ReadAccelerometer(GY85_t *imu)
|
||||
{
|
||||
uint8_t reg = 0x32;
|
||||
uint8_t buf[6];
|
||||
HAL_I2C_Master_Transmit(&hi2c3, ADXL345_ADDR, ®, 1, HAL_MAX_DELAY);
|
||||
HAL_I2C_Master_Receive(&hi2c3, ADXL345_ADDR, buf, 6, HAL_MAX_DELAY);
|
||||
|
||||
imu->ax = (int16_t)((buf[1] << 8) | buf[0]);
|
||||
imu->ay = (int16_t)((buf[3] << 8) | buf[2]);
|
||||
imu->az = (int16_t)((buf[5] << 8) | buf[4]);
|
||||
}
|
||||
|
||||
// ---------------- Compass ---------------- //
|
||||
static void GY85_SetCompass(void)
|
||||
{
|
||||
uint8_t data[2] = {0x02, 0x00};
|
||||
HAL_I2C_Master_Transmit(&hi2c3, HMC5883_ADDR, data, 2, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
static void GY85_ReadCompass(GY85_t *imu)
|
||||
{
|
||||
uint8_t reg = 0x03;
|
||||
uint8_t buf[6];
|
||||
HAL_I2C_Master_Transmit(&hi2c3, HMC5883_ADDR, ®, 1, HAL_MAX_DELAY);
|
||||
HAL_I2C_Master_Receive(&hi2c3, HMC5883_ADDR, buf, 6, HAL_MAX_DELAY);
|
||||
|
||||
imu->mx = (int16_t)((buf[0] << 8) | buf[1]);
|
||||
imu->mz = (int16_t)((buf[2] << 8) | buf[3]);
|
||||
imu->my = (int16_t)((buf[4] << 8) | buf[5]);
|
||||
}
|
||||
|
||||
// ---------------- Gyroscope ---------------- //
|
||||
static void GY85_SetGyro(void)
|
||||
{
|
||||
uint8_t data[2];
|
||||
data[0] = 0x3E; data[1] = 0x00;
|
||||
HAL_I2C_Master_Transmit(&hi2c3, ITG3200_ADDR, data, 2, HAL_MAX_DELAY);
|
||||
|
||||
data[0] = 0x15; data[1] = 0x07;
|
||||
HAL_I2C_Master_Transmit(&hi2c3, ITG3200_ADDR, data, 2, HAL_MAX_DELAY);
|
||||
|
||||
data[0] = 0x16; data[1] = 0x1E;
|
||||
HAL_I2C_Master_Transmit(&hi2c3, ITG3200_ADDR, data, 2, HAL_MAX_DELAY);
|
||||
|
||||
data[0] = 0x17; data[1] = 0x00;
|
||||
HAL_I2C_Master_Transmit(&hi2c3, ITG3200_ADDR, data, 2, HAL_MAX_DELAY);
|
||||
|
||||
HAL_Delay(10);
|
||||
GY85_GyroCalibrate();
|
||||
}
|
||||
|
||||
static void GY85_GyroCalibrate(void)
|
||||
{
|
||||
int32_t tmpx = 0, tmpy = 0, tmpz = 0;
|
||||
GY85_t imu;
|
||||
|
||||
for(uint8_t i = 0; i < 10; i++)
|
||||
{
|
||||
HAL_Delay(10);
|
||||
GY85_ReadGyro(&imu);
|
||||
tmpx += imu.gx;
|
||||
tmpy += imu.gy;
|
||||
tmpz += imu.gz;
|
||||
}
|
||||
|
||||
g_offx = tmpx / 10;
|
||||
g_offy = tmpy / 10;
|
||||
g_offz = tmpz / 10;
|
||||
}
|
||||
|
||||
static void GY85_ReadGyro(GY85_t *imu)
|
||||
{
|
||||
uint8_t reg = 0x1B;
|
||||
uint8_t buf[8];
|
||||
HAL_I2C_Master_Transmit(&hi2c3, ITG3200_ADDR, ®, 1, HAL_MAX_DELAY);
|
||||
HAL_I2C_Master_Receive(&hi2c3, ITG3200_ADDR, buf, 8, HAL_MAX_DELAY);
|
||||
|
||||
imu->gx = ((int16_t)((buf[2] << 8) | buf[3])) - g_offx;
|
||||
imu->gy = ((int16_t)((buf[4] << 8) | buf[5])) - g_offy;
|
||||
imu->gz = ((int16_t)((buf[6] << 8) | buf[7])) - g_offz;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef __GY_85_HAL_H__
|
||||
#define __GY_85_HAL_H__
|
||||
|
||||
#include "stm32f7xx_hal.h" // change depending on MCU family
|
||||
#include <stdint.h>
|
||||
|
||||
#define ADXL345_ADDR (0x53 << 1)
|
||||
#define HMC5883_ADDR (0x1E << 1)
|
||||
#define ITG3200_ADDR (0x68 << 1)
|
||||
|
||||
extern I2C_HandleTypeDef hi2c3;
|
||||
|
||||
// Struct to hold all sensor data
|
||||
typedef struct {
|
||||
int16_t ax, ay, az; // accelerometer
|
||||
float gx, gy, gz; // gyroscope
|
||||
int16_t mx, my, mz; // magnetometer
|
||||
} GY85_t;
|
||||
|
||||
// Public API
|
||||
void GY85_Init(void);
|
||||
void GY85_Update(GY85_t *imu); // reads all sensors and stores in struct
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#include "RadarSettings.h"
|
||||
#include <cstring>
|
||||
|
||||
RadarSettings::RadarSettings() {
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void RadarSettings::resetToDefaults() {
|
||||
system_frequency = 10.0e9; // 10 GHz
|
||||
chirp_duration_1 = 30.0e-6; // 30 µs
|
||||
chirp_duration_2 = 0.5e-6; // 0.5 µs
|
||||
chirps_per_position = 32;
|
||||
freq_min = 10.0e6; // 10 MHz
|
||||
freq_max = 30.0e6; // 30 MHz
|
||||
prf1 = 1000.0; // 1 kHz
|
||||
prf2 = 2000.0; // 2 kHz
|
||||
max_distance = 50000.0; // 50 km
|
||||
map_size = 50000.0; // 50 km
|
||||
|
||||
settings_valid = true;
|
||||
}
|
||||
|
||||
bool RadarSettings::parseFromUSB(const uint8_t* data, uint32_t length) {
|
||||
// Minimum packet size: "SET" + 8 doubles + 1 uint32_t + "END" = 3 + 8*8 + 4 + 3 = 74 bytes
|
||||
if (data == nullptr || length < 74) {
|
||||
settings_valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for start marker "SET"
|
||||
if (memcmp(data, "SET", 3) != 0) {
|
||||
settings_valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for end marker "END"
|
||||
if (memcmp(data + length - 3, "END", 3) != 0) {
|
||||
settings_valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t offset = 3; // Skip "SET"
|
||||
|
||||
// Extract all parameters in order
|
||||
system_frequency = extractDouble(data + offset);
|
||||
offset += 8;
|
||||
|
||||
chirp_duration_1 = extractDouble(data + offset);
|
||||
offset += 8;
|
||||
|
||||
chirp_duration_2 = extractDouble(data + offset);
|
||||
offset += 8;
|
||||
|
||||
chirps_per_position = extractUint32(data + offset);
|
||||
offset += 4;
|
||||
|
||||
freq_min = extractDouble(data + offset);
|
||||
offset += 8;
|
||||
|
||||
freq_max = extractDouble(data + offset);
|
||||
offset += 8;
|
||||
|
||||
prf1 = extractDouble(data + offset);
|
||||
offset += 8;
|
||||
|
||||
prf2 = extractDouble(data + offset);
|
||||
offset += 8;
|
||||
|
||||
max_distance = extractDouble(data + offset);
|
||||
offset += 8;
|
||||
|
||||
map_size = extractDouble(data + offset);
|
||||
|
||||
// Validate the received settings
|
||||
settings_valid = validateSettings();
|
||||
|
||||
return settings_valid;
|
||||
}
|
||||
|
||||
bool RadarSettings::validateSettings() {
|
||||
// Check for reasonable value ranges
|
||||
if (system_frequency < 1e9 || system_frequency > 100e9) return false;
|
||||
if (chirp_duration_1 < 1e-6 || chirp_duration_1 > 1000e-6) return false;
|
||||
if (chirp_duration_2 < 0.1e-6 || chirp_duration_2 > 10e-6) return false;
|
||||
if (chirps_per_position < 1 || chirps_per_position > 256) return false;
|
||||
if (freq_min < 1e6 || freq_min > 100e6) return false;
|
||||
if (freq_max <= freq_min || freq_max > 100e6) return false;
|
||||
if (prf1 < 100 || prf1 > 10000) return false;
|
||||
if (prf2 < 100 || prf2 > 10000) return false;
|
||||
if (max_distance < 100 || max_distance > 100000) return false;
|
||||
if (map_size < 1000 || map_size > 200000) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double RadarSettings::extractDouble(const uint8_t* data) {
|
||||
uint64_t bits = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
bits = (bits << 8) | data[i];
|
||||
}
|
||||
|
||||
double value;
|
||||
memcpy(&value, &bits, sizeof(double));
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t RadarSettings::extractUint32(const uint8_t* data) {
|
||||
uint32_t value = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
value = (value << 8) | data[i];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef RADARSETTINGS_H
|
||||
#define RADARSETTINGS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class RadarSettings {
|
||||
public:
|
||||
// Default constructor with initial values
|
||||
RadarSettings();
|
||||
|
||||
// Parse settings from USB CDC data
|
||||
bool parseFromUSB(const uint8_t* data, uint32_t length);
|
||||
|
||||
// Getters for all settings
|
||||
double getSystemFrequency() const { return system_frequency; }
|
||||
double getChirpDuration1() const { return chirp_duration_1; }
|
||||
double getChirpDuration2() const { return chirp_duration_2; }
|
||||
uint32_t getChirpsPerPosition() const { return chirps_per_position; }
|
||||
double getFreqMin() const { return freq_min; }
|
||||
double getFreqMax() const { return freq_max; }
|
||||
double getPRF1() const { return prf1; }
|
||||
double getPRF2() const { return prf2; }
|
||||
double getMaxDistance() const { return max_distance; }
|
||||
double getMapSize() const { return map_size; }
|
||||
|
||||
// Check if settings are valid
|
||||
bool isValid() const { return settings_valid; }
|
||||
|
||||
// Reset to default values
|
||||
void resetToDefaults();
|
||||
|
||||
private:
|
||||
// Radar system parameters
|
||||
double system_frequency; // Hz
|
||||
double chirp_duration_1; // seconds (long chirp)
|
||||
double chirp_duration_2; // seconds (short chirp)
|
||||
uint32_t chirps_per_position;
|
||||
double freq_min; // Hz
|
||||
double freq_max; // Hz
|
||||
double prf1; // Hz
|
||||
double prf2; // Hz
|
||||
double max_distance; // meters
|
||||
double map_size; // meters
|
||||
|
||||
bool settings_valid;
|
||||
|
||||
// Helper methods
|
||||
bool validateSettings();
|
||||
double extractDouble(const uint8_t* data);
|
||||
uint32_t extractUint32(const uint8_t* data);
|
||||
};
|
||||
|
||||
#endif // RADARSETTINGS_H
|
||||
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
TinyGPS++ - a small GPS library for Arduino providing universal NMEA parsing
|
||||
Based on work by and "distanceBetween" and "courseTo" courtesy of Maarten Lamers.
|
||||
Suggestion to add satellites, courseTo(), and cardinal() by Matt Monson.
|
||||
Location precision improvements suggested by Wayne Holder.
|
||||
Copyright (C) 2008-2024 Mikal Hart
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "TinyGPS++.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#define _RMCterm "RMC"
|
||||
#define _GGAterm "GGA"
|
||||
|
||||
|
||||
TinyGPSPlus::TinyGPSPlus()
|
||||
: parity(0)
|
||||
, isChecksumTerm(false)
|
||||
, curSentenceType(GPS_SENTENCE_OTHER)
|
||||
, curTermNumber(0)
|
||||
, curTermOffset(0)
|
||||
, sentenceHasFix(false)
|
||||
, customElts(0)
|
||||
, customCandidates(0)
|
||||
, encodedCharCount(0)
|
||||
, sentencesWithFixCount(0)
|
||||
, failedChecksumCount(0)
|
||||
, passedChecksumCount(0)
|
||||
{
|
||||
term[0] = '\0';
|
||||
}
|
||||
|
||||
//
|
||||
// public methods
|
||||
//
|
||||
|
||||
bool TinyGPSPlus::encode(char c)
|
||||
{
|
||||
++encodedCharCount;
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case ',': // term terminators
|
||||
parity ^= (uint8_t)c;
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '*':
|
||||
{
|
||||
bool isValidSentence = false;
|
||||
if (curTermOffset < sizeof(term))
|
||||
{
|
||||
term[curTermOffset] = 0;
|
||||
isValidSentence = endOfTermHandler();
|
||||
}
|
||||
++curTermNumber;
|
||||
curTermOffset = 0;
|
||||
isChecksumTerm = c == '*';
|
||||
return isValidSentence;
|
||||
}
|
||||
break;
|
||||
|
||||
case '$': // sentence begin
|
||||
curTermNumber = curTermOffset = 0;
|
||||
parity = 0;
|
||||
curSentenceType = GPS_SENTENCE_OTHER;
|
||||
isChecksumTerm = false;
|
||||
sentenceHasFix = false;
|
||||
return false;
|
||||
|
||||
default: // ordinary characters
|
||||
if (curTermOffset < sizeof(term) - 1)
|
||||
term[curTermOffset++] = c;
|
||||
if (!isChecksumTerm)
|
||||
parity ^= c;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// internal utilities
|
||||
//
|
||||
int TinyGPSPlus::fromHex(char a)
|
||||
{
|
||||
if (a >= 'A' && a <= 'F')
|
||||
return a - 'A' + 10;
|
||||
else if (a >= 'a' && a <= 'f')
|
||||
return a - 'a' + 10;
|
||||
else
|
||||
return a - '0';
|
||||
}
|
||||
|
||||
// static
|
||||
// Parse a (potentially negative) number with up to 2 decimal digits -xxxx.yy
|
||||
int32_t TinyGPSPlus::parseDecimal(const char *term)
|
||||
{
|
||||
bool negative = *term == '-';
|
||||
if (negative) ++term;
|
||||
int32_t ret = 100 * (int32_t)atol(term);
|
||||
while (isdigit(*term)) ++term;
|
||||
if (*term == '.' && isdigit(term[1]))
|
||||
{
|
||||
ret += 10 * (term[1] - '0');
|
||||
if (isdigit(term[2]))
|
||||
ret += term[2] - '0';
|
||||
}
|
||||
return negative ? -ret : ret;
|
||||
}
|
||||
|
||||
// static
|
||||
// Parse degrees in that funny NMEA format DDMM.MMMM
|
||||
void TinyGPSPlus::parseDegrees(const char *term, RawDegrees °)
|
||||
{
|
||||
uint32_t leftOfDecimal = (uint32_t)atol(term);
|
||||
uint16_t minutes = (uint16_t)(leftOfDecimal % 100);
|
||||
uint32_t multiplier = 10000000UL;
|
||||
uint32_t tenMillionthsOfMinutes = minutes * multiplier;
|
||||
|
||||
deg.deg = (int16_t)(leftOfDecimal / 100);
|
||||
|
||||
while (isdigit(*term))
|
||||
++term;
|
||||
|
||||
if (*term == '.')
|
||||
while (isdigit(*++term))
|
||||
{
|
||||
multiplier /= 10;
|
||||
tenMillionthsOfMinutes += (*term - '0') * multiplier;
|
||||
}
|
||||
|
||||
deg.billionths = (5 * tenMillionthsOfMinutes + 1) / 3;
|
||||
deg.negative = false;
|
||||
}
|
||||
|
||||
#define COMBINE(sentence_type, term_number) (((unsigned)(sentence_type) << 5) | term_number)
|
||||
|
||||
// Processes a just-completed term
|
||||
// Returns true if new sentence has just passed checksum test and is validated
|
||||
bool TinyGPSPlus::endOfTermHandler()
|
||||
{
|
||||
// If it's the checksum term, and the checksum checks out, commit
|
||||
if (isChecksumTerm)
|
||||
{
|
||||
uint8_t checksum = 16 * fromHex(term[0]) + fromHex(term[1]);
|
||||
if (checksum == parity)
|
||||
{
|
||||
passedChecksumCount++;
|
||||
if (sentenceHasFix)
|
||||
++sentencesWithFixCount;
|
||||
|
||||
switch(curSentenceType)
|
||||
{
|
||||
case GPS_SENTENCE_RMC:
|
||||
date.commit();
|
||||
time.commit();
|
||||
if (sentenceHasFix)
|
||||
{
|
||||
location.commit();
|
||||
speed.commit();
|
||||
course.commit();
|
||||
}
|
||||
break;
|
||||
case GPS_SENTENCE_GGA:
|
||||
time.commit();
|
||||
if (sentenceHasFix)
|
||||
{
|
||||
location.commit();
|
||||
altitude.commit();
|
||||
}
|
||||
satellites.commit();
|
||||
hdop.commit();
|
||||
break;
|
||||
}
|
||||
|
||||
// Commit all custom listeners of this sentence type
|
||||
for (TinyGPSCustom *p = customCandidates; p != NULL && strcmp(p->sentenceName, customCandidates->sentenceName) == 0; p = p->next)
|
||||
p->commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
++failedChecksumCount;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// the first term determines the sentence type
|
||||
if (curTermNumber == 0)
|
||||
{
|
||||
if (term[0] == 'G' && strchr("PNABL", term[1]) != NULL && !strcmp(term + 2, _RMCterm))
|
||||
curSentenceType = GPS_SENTENCE_RMC;
|
||||
else if (term[0] == 'G' && strchr("PNABL", term[1]) != NULL && !strcmp(term + 2, _GGAterm))
|
||||
curSentenceType = GPS_SENTENCE_GGA;
|
||||
else
|
||||
curSentenceType = GPS_SENTENCE_OTHER;
|
||||
|
||||
// Any custom candidates of this sentence type?
|
||||
for (customCandidates = customElts; customCandidates != NULL && strcmp(customCandidates->sentenceName, term) < 0; customCandidates = customCandidates->next);
|
||||
if (customCandidates != NULL && strcmp(customCandidates->sentenceName, term) > 0)
|
||||
customCandidates = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curSentenceType != GPS_SENTENCE_OTHER && term[0])
|
||||
switch(COMBINE(curSentenceType, curTermNumber))
|
||||
{
|
||||
case COMBINE(GPS_SENTENCE_RMC, 1): // Time in both sentences
|
||||
case COMBINE(GPS_SENTENCE_GGA, 1):
|
||||
time.setTime(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 2): // RMC validity
|
||||
sentenceHasFix = term[0] == 'A';
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 3): // Latitude
|
||||
case COMBINE(GPS_SENTENCE_GGA, 2):
|
||||
location.setLatitude(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 4): // N/S
|
||||
case COMBINE(GPS_SENTENCE_GGA, 3):
|
||||
location.rawNewLatData.negative = term[0] == 'S';
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 5): // Longitude
|
||||
case COMBINE(GPS_SENTENCE_GGA, 4):
|
||||
location.setLongitude(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 6): // E/W
|
||||
case COMBINE(GPS_SENTENCE_GGA, 5):
|
||||
location.rawNewLngData.negative = term[0] == 'W';
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 7): // Speed (RMC)
|
||||
speed.set(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 8): // Course (RMC)
|
||||
course.set(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 9): // Date (RMC)
|
||||
date.setDate(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_GGA, 6): // Fix data (GGA)
|
||||
sentenceHasFix = term[0] > '0';
|
||||
location.newFixQuality = (TinyGPSLocation::Quality)term[0];
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_GGA, 7): // Satellites used (GGA)
|
||||
satellites.set(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_GGA, 8): // HDOP
|
||||
hdop.set(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_GGA, 9): // Altitude (GGA)
|
||||
altitude.set(term);
|
||||
break;
|
||||
case COMBINE(GPS_SENTENCE_RMC, 12):
|
||||
location.newFixMode = (TinyGPSLocation::Mode)term[0];
|
||||
break;
|
||||
}
|
||||
|
||||
// Set custom values as needed
|
||||
for (TinyGPSCustom *p = customCandidates; p != NULL && strcmp(p->sentenceName, customCandidates->sentenceName) == 0 && p->termNumber <= curTermNumber; p = p->next)
|
||||
if (p->termNumber == curTermNumber)
|
||||
p->set(term);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */
|
||||
double TinyGPSPlus::distanceBetween(double lat1, double long1, double lat2, double long2)
|
||||
{
|
||||
// returns distance in meters between two positions, both specified
|
||||
// as signed decimal-degrees latitude and longitude. Uses great-circle
|
||||
// distance computation for hypothetical sphere of radius 6371009 meters.
|
||||
// Because Earth is no exact sphere, rounding errors may be up to 0.5%.
|
||||
// Courtesy of Maarten Lamers
|
||||
double delta = (long1-long2)* (PI / 180);
|
||||
double sdlong = sin(delta);
|
||||
double cdlong = cos(delta);
|
||||
lat1 = (lat1)* (PI / 180);
|
||||
lat2 = (lat2)* (PI / 180);
|
||||
double slat1 = sin(lat1);
|
||||
double clat1 = cos(lat1);
|
||||
double slat2 = sin(lat2);
|
||||
double clat2 = cos(lat2);
|
||||
delta = (clat1 * slat2) - (slat1 * clat2 * cdlong);
|
||||
delta = delta*delta;
|
||||
delta += (clat2 * sdlong)*(clat2 * sdlong);
|
||||
delta = sqrt(delta);
|
||||
double denom = (slat1 * slat2) + (clat1 * clat2 * cdlong);
|
||||
delta = atan2(delta, denom);
|
||||
return delta * _GPS_EARTH_MEAN_RADIUS;
|
||||
}
|
||||
|
||||
double TinyGPSPlus::courseTo(double lat1, double long1, double lat2, double long2)
|
||||
{
|
||||
// returns course in degrees (North=0, West=270) from position 1 to position 2,
|
||||
// both specified as signed decimal-degrees latitude and longitude.
|
||||
// Because Earth is no exact sphere, calculated course may be off by a tiny fraction.
|
||||
// Courtesy of Maarten Lamers
|
||||
double dlon = (PI/180)*(long2-long1);
|
||||
lat1 = (PI/180)*(lat1);
|
||||
lat2 = (PI/180)*(lat2);
|
||||
double a1 = sin(dlon) * cos(lat2);
|
||||
double a2 = sin(lat1) * cos(lat2) * cos(dlon);
|
||||
a2 = cos(lat1) * sin(lat2) - a2;
|
||||
a2 = atan2(a1, a2);
|
||||
if (a2 < 0.0)
|
||||
{
|
||||
a2 += TWO_PI;
|
||||
}
|
||||
return 180/PI*(a2);
|
||||
}
|
||||
|
||||
const char *TinyGPSPlus::cardinal(double course)
|
||||
{
|
||||
static const char* directions[] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"};
|
||||
int direction = (int)((course + 11.25f) / 22.5f);
|
||||
return directions[direction % 16];
|
||||
}
|
||||
|
||||
void TinyGPSLocation::commit()
|
||||
{
|
||||
rawLatData = rawNewLatData;
|
||||
rawLngData = rawNewLngData;
|
||||
fixQuality = newFixQuality;
|
||||
fixMode = newFixMode;
|
||||
lastCommitTime = HAL_GetTick();
|
||||
valid = updated = true;
|
||||
}
|
||||
|
||||
void TinyGPSLocation::setLatitude(const char *term)
|
||||
{
|
||||
TinyGPSPlus::parseDegrees(term, rawNewLatData);
|
||||
}
|
||||
|
||||
void TinyGPSLocation::setLongitude(const char *term)
|
||||
{
|
||||
TinyGPSPlus::parseDegrees(term, rawNewLngData);
|
||||
}
|
||||
|
||||
double TinyGPSLocation::lat()
|
||||
{
|
||||
updated = false;
|
||||
double ret = rawLatData.deg + rawLatData.billionths / 1000000000.0;
|
||||
return rawLatData.negative ? -ret : ret;
|
||||
}
|
||||
|
||||
double TinyGPSLocation::lng()
|
||||
{
|
||||
updated = false;
|
||||
double ret = rawLngData.deg + rawLngData.billionths / 1000000000.0;
|
||||
return rawLngData.negative ? -ret : ret;
|
||||
}
|
||||
|
||||
void TinyGPSDate::commit()
|
||||
{
|
||||
date = newDate;
|
||||
lastCommitTime = HAL_GetTick();
|
||||
valid = updated = true;
|
||||
}
|
||||
|
||||
void TinyGPSTime::commit()
|
||||
{
|
||||
time = newTime;
|
||||
lastCommitTime = HAL_GetTick();
|
||||
valid = updated = true;
|
||||
}
|
||||
|
||||
void TinyGPSTime::setTime(const char *term)
|
||||
{
|
||||
newTime = (uint32_t)TinyGPSPlus::parseDecimal(term);
|
||||
}
|
||||
|
||||
void TinyGPSDate::setDate(const char *term)
|
||||
{
|
||||
newDate = atol(term);
|
||||
}
|
||||
|
||||
uint16_t TinyGPSDate::year()
|
||||
{
|
||||
updated = false;
|
||||
uint16_t year = date % 100;
|
||||
return year + 2000;
|
||||
}
|
||||
|
||||
uint8_t TinyGPSDate::month()
|
||||
{
|
||||
updated = false;
|
||||
return (date / 100) % 100;
|
||||
}
|
||||
|
||||
uint8_t TinyGPSDate::day()
|
||||
{
|
||||
updated = false;
|
||||
return date / 10000;
|
||||
}
|
||||
|
||||
uint8_t TinyGPSTime::hour()
|
||||
{
|
||||
updated = false;
|
||||
return time / 1000000;
|
||||
}
|
||||
|
||||
uint8_t TinyGPSTime::minute()
|
||||
{
|
||||
updated = false;
|
||||
return (time / 10000) % 100;
|
||||
}
|
||||
|
||||
uint8_t TinyGPSTime::second()
|
||||
{
|
||||
updated = false;
|
||||
return (time / 100) % 100;
|
||||
}
|
||||
|
||||
uint8_t TinyGPSTime::centisecond()
|
||||
{
|
||||
updated = false;
|
||||
return time % 100;
|
||||
}
|
||||
|
||||
void TinyGPSDecimal::commit()
|
||||
{
|
||||
val = newval;
|
||||
lastCommitTime = HAL_GetTick();
|
||||
valid = updated = true;
|
||||
}
|
||||
|
||||
void TinyGPSDecimal::set(const char *term)
|
||||
{
|
||||
newval = TinyGPSPlus::parseDecimal(term);
|
||||
}
|
||||
|
||||
void TinyGPSInteger::commit()
|
||||
{
|
||||
val = newval;
|
||||
lastCommitTime = HAL_GetTick();
|
||||
valid = updated = true;
|
||||
}
|
||||
|
||||
void TinyGPSInteger::set(const char *term)
|
||||
{
|
||||
newval = atol(term);
|
||||
}
|
||||
|
||||
TinyGPSCustom::TinyGPSCustom(TinyGPSPlus &gps, const char *_sentenceName, int _termNumber)
|
||||
{
|
||||
begin(gps, _sentenceName, _termNumber);
|
||||
}
|
||||
|
||||
void TinyGPSCustom::begin(TinyGPSPlus &gps, const char *_sentenceName, int _termNumber)
|
||||
{
|
||||
lastCommitTime = 0;
|
||||
updated = valid = false;
|
||||
sentenceName = _sentenceName;
|
||||
termNumber = _termNumber;
|
||||
memset(stagingBuffer, '\0', sizeof(stagingBuffer));
|
||||
memset(buffer, '\0', sizeof(buffer));
|
||||
|
||||
// Insert this item into the GPS tree
|
||||
gps.insertCustom(this, _sentenceName, _termNumber);
|
||||
}
|
||||
|
||||
void TinyGPSCustom::commit()
|
||||
{
|
||||
strcpy(this->buffer, this->stagingBuffer);
|
||||
lastCommitTime = HAL_GetTick();
|
||||
valid = updated = true;
|
||||
}
|
||||
|
||||
void TinyGPSCustom::set(const char *term)
|
||||
{
|
||||
strncpy(this->stagingBuffer, term, sizeof(this->stagingBuffer) - 1);
|
||||
}
|
||||
|
||||
void TinyGPSPlus::insertCustom(TinyGPSCustom *pElt, const char *sentenceName, int termNumber)
|
||||
{
|
||||
TinyGPSCustom **ppelt;
|
||||
|
||||
for (ppelt = &this->customElts; *ppelt != NULL; ppelt = &(*ppelt)->next)
|
||||
{
|
||||
int cmp = strcmp(sentenceName, (*ppelt)->sentenceName);
|
||||
if (cmp < 0 || (cmp == 0 && termNumber < (*ppelt)->termNumber))
|
||||
break;
|
||||
}
|
||||
|
||||
pElt->next = *ppelt;
|
||||
*ppelt = pElt;
|
||||
}
|
||||
289
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.h
Normal file
289
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/TinyGPS++.h
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
TinyGPS++ - a small GPS library for Arduino providing universal NMEA parsing
|
||||
Based on work by and "distanceBetween" and "courseTo" courtesy of Maarten Lamers.
|
||||
Suggestion to add satellites, courseTo(), and cardinal() by Matt Monson.
|
||||
Location precision improvements suggested by Wayne Holder.
|
||||
Copyright (C) 2008-2024 Mikal Hart
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __TinyGPSPlus_h
|
||||
#define __TinyGPSPlus_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include "stm32f7xx_hal.h"
|
||||
|
||||
|
||||
#define _GPS_VERSION "1.1.0" // software version of this library
|
||||
#define _GPS_MPH_PER_KNOT 1.15077945
|
||||
#define _GPS_MPS_PER_KNOT 0.51444444
|
||||
#define _GPS_KMPH_PER_KNOT 1.852
|
||||
#define _GPS_MILES_PER_METER 0.00062137112
|
||||
#define _GPS_KM_PER_METER 0.001
|
||||
#define _GPS_FEET_PER_METER 3.2808399
|
||||
#define _GPS_MAX_FIELD_SIZE 15
|
||||
#define _GPS_EARTH_MEAN_RADIUS 6371009 // old: 6372795
|
||||
|
||||
#define PI 3.14159265359
|
||||
#define TWO_PI 6.28318530718
|
||||
|
||||
struct RawDegrees
|
||||
{
|
||||
uint16_t deg;
|
||||
uint32_t billionths;
|
||||
bool negative;
|
||||
public:
|
||||
RawDegrees() : deg(0), billionths(0), negative(false)
|
||||
{}
|
||||
};
|
||||
|
||||
struct TinyGPSLocation
|
||||
{
|
||||
friend class TinyGPSPlus;
|
||||
public:
|
||||
enum Quality { Invalid = '0', GPS = '1', DGPS = '2', PPS = '3', RTK = '4', FloatRTK = '5', Estimated = '6', Manual = '7', Simulated = '8' };
|
||||
enum Mode { N = 'N', A = 'A', D = 'D', E = 'E'};
|
||||
|
||||
bool isValid() const { return valid; }
|
||||
bool isUpdated() const { return updated; }
|
||||
uint32_t age() const { return valid ? HAL_GetTick() - lastCommitTime : (uint32_t)ULONG_MAX; }
|
||||
const RawDegrees &rawLat() { updated = false; return rawLatData; }
|
||||
const RawDegrees &rawLng() { updated = false; return rawLngData; }
|
||||
double lat();
|
||||
double lng();
|
||||
Quality FixQuality() { updated = false; return fixQuality; }
|
||||
Mode FixMode() { updated = false; return fixMode; }
|
||||
|
||||
TinyGPSLocation() : valid(false), updated(false), fixQuality(Invalid), fixMode(N)
|
||||
{}
|
||||
|
||||
private:
|
||||
bool valid, updated;
|
||||
RawDegrees rawLatData, rawLngData, rawNewLatData, rawNewLngData;
|
||||
Quality fixQuality, newFixQuality;
|
||||
Mode fixMode, newFixMode;
|
||||
uint32_t lastCommitTime;
|
||||
void commit();
|
||||
void setLatitude(const char *term);
|
||||
void setLongitude(const char *term);
|
||||
};
|
||||
|
||||
struct TinyGPSDate
|
||||
{
|
||||
friend class TinyGPSPlus;
|
||||
public:
|
||||
bool isValid() const { return valid; }
|
||||
bool isUpdated() const { return updated; }
|
||||
uint32_t age() const { return valid ? HAL_GetTick() - lastCommitTime : (uint32_t)ULONG_MAX; }
|
||||
|
||||
uint32_t value() { updated = false; return date; }
|
||||
uint16_t year();
|
||||
uint8_t month();
|
||||
uint8_t day();
|
||||
|
||||
TinyGPSDate() : valid(false), updated(false), date(0)
|
||||
{}
|
||||
|
||||
private:
|
||||
bool valid, updated;
|
||||
uint32_t date, newDate;
|
||||
uint32_t lastCommitTime;
|
||||
void commit();
|
||||
void setDate(const char *term);
|
||||
};
|
||||
|
||||
struct TinyGPSTime
|
||||
{
|
||||
friend class TinyGPSPlus;
|
||||
public:
|
||||
bool isValid() const { return valid; }
|
||||
bool isUpdated() const { return updated; }
|
||||
uint32_t age() const { return valid ? HAL_GetTick() - lastCommitTime : (uint32_t)ULONG_MAX; }
|
||||
|
||||
uint32_t value() { updated = false; return time; }
|
||||
uint8_t hour();
|
||||
uint8_t minute();
|
||||
uint8_t second();
|
||||
uint8_t centisecond();
|
||||
|
||||
TinyGPSTime() : valid(false), updated(false), time(0)
|
||||
{}
|
||||
|
||||
private:
|
||||
bool valid, updated;
|
||||
uint32_t time, newTime;
|
||||
uint32_t lastCommitTime;
|
||||
void commit();
|
||||
void setTime(const char *term);
|
||||
};
|
||||
|
||||
struct TinyGPSDecimal
|
||||
{
|
||||
friend class TinyGPSPlus;
|
||||
public:
|
||||
bool isValid() const { return valid; }
|
||||
bool isUpdated() const { return updated; }
|
||||
uint32_t age() const { return valid ? HAL_GetTick() - lastCommitTime : (uint32_t)ULONG_MAX; }
|
||||
int32_t value() { updated = false; return val; }
|
||||
|
||||
TinyGPSDecimal() : valid(false), updated(false), val(0)
|
||||
{}
|
||||
|
||||
private:
|
||||
bool valid, updated;
|
||||
uint32_t lastCommitTime;
|
||||
int32_t val, newval;
|
||||
void commit();
|
||||
void set(const char *term);
|
||||
};
|
||||
|
||||
struct TinyGPSInteger
|
||||
{
|
||||
friend class TinyGPSPlus;
|
||||
public:
|
||||
bool isValid() const { return valid; }
|
||||
bool isUpdated() const { return updated; }
|
||||
uint32_t age() const { return valid ? HAL_GetTick() - lastCommitTime : (uint32_t)ULONG_MAX; }
|
||||
uint32_t value() { updated = false; return val; }
|
||||
|
||||
TinyGPSInteger() : valid(false), updated(false), val(0)
|
||||
{}
|
||||
|
||||
private:
|
||||
bool valid, updated;
|
||||
uint32_t lastCommitTime;
|
||||
uint32_t val, newval;
|
||||
void commit();
|
||||
void set(const char *term);
|
||||
};
|
||||
|
||||
struct TinyGPSSpeed : TinyGPSDecimal
|
||||
{
|
||||
double knots() { return value() / 100.0; }
|
||||
double mph() { return _GPS_MPH_PER_KNOT * value() / 100.0; }
|
||||
double mps() { return _GPS_MPS_PER_KNOT * value() / 100.0; }
|
||||
double kmph() { return _GPS_KMPH_PER_KNOT * value() / 100.0; }
|
||||
};
|
||||
|
||||
struct TinyGPSCourse : public TinyGPSDecimal
|
||||
{
|
||||
double deg() { return value() / 100.0; }
|
||||
};
|
||||
|
||||
struct TinyGPSAltitude : TinyGPSDecimal
|
||||
{
|
||||
double meters() { return value() / 100.0; }
|
||||
double miles() { return _GPS_MILES_PER_METER * value() / 100.0; }
|
||||
double kilometers() { return _GPS_KM_PER_METER * value() / 100.0; }
|
||||
double feet() { return _GPS_FEET_PER_METER * value() / 100.0; }
|
||||
};
|
||||
|
||||
struct TinyGPSHDOP : TinyGPSDecimal
|
||||
{
|
||||
double hdop() { return value() / 100.0; }
|
||||
};
|
||||
|
||||
class TinyGPSPlus;
|
||||
class TinyGPSCustom
|
||||
{
|
||||
public:
|
||||
TinyGPSCustom() {};
|
||||
TinyGPSCustom(TinyGPSPlus &gps, const char *sentenceName, int termNumber);
|
||||
void begin(TinyGPSPlus &gps, const char *_sentenceName, int _termNumber);
|
||||
|
||||
bool isUpdated() const { return updated; }
|
||||
bool isValid() const { return valid; }
|
||||
uint32_t age() const { return valid ? HAL_GetTick() - lastCommitTime : (uint32_t)ULONG_MAX; }
|
||||
const char *value() { updated = false; return buffer; }
|
||||
|
||||
private:
|
||||
void commit();
|
||||
void set(const char *term);
|
||||
|
||||
char stagingBuffer[_GPS_MAX_FIELD_SIZE + 1];
|
||||
char buffer[_GPS_MAX_FIELD_SIZE + 1];
|
||||
unsigned long lastCommitTime;
|
||||
bool valid, updated;
|
||||
const char *sentenceName;
|
||||
int termNumber;
|
||||
friend class TinyGPSPlus;
|
||||
TinyGPSCustom *next;
|
||||
};
|
||||
|
||||
class TinyGPSPlus
|
||||
{
|
||||
public:
|
||||
TinyGPSPlus();
|
||||
bool encode(char c); // process one character received from GPS
|
||||
TinyGPSPlus &operator << (char c) {encode(c); return *this;}
|
||||
|
||||
TinyGPSLocation location;
|
||||
TinyGPSDate date;
|
||||
TinyGPSTime time;
|
||||
TinyGPSSpeed speed;
|
||||
TinyGPSCourse course;
|
||||
TinyGPSAltitude altitude;
|
||||
TinyGPSInteger satellites;
|
||||
TinyGPSHDOP hdop;
|
||||
|
||||
static const char *libraryVersion() { return _GPS_VERSION; }
|
||||
|
||||
static double distanceBetween(double lat1, double long1, double lat2, double long2);
|
||||
static double courseTo(double lat1, double long1, double lat2, double long2);
|
||||
static const char *cardinal(double course);
|
||||
|
||||
static int32_t parseDecimal(const char *term);
|
||||
static void parseDegrees(const char *term, RawDegrees °);
|
||||
|
||||
uint32_t charsProcessed() const { return encodedCharCount; }
|
||||
uint32_t sentencesWithFix() const { return sentencesWithFixCount; }
|
||||
uint32_t failedChecksum() const { return failedChecksumCount; }
|
||||
uint32_t passedChecksum() const { return passedChecksumCount; }
|
||||
|
||||
private:
|
||||
enum {GPS_SENTENCE_GGA, GPS_SENTENCE_RMC, GPS_SENTENCE_OTHER};
|
||||
|
||||
// parsing state variables
|
||||
uint8_t parity;
|
||||
bool isChecksumTerm;
|
||||
char term[_GPS_MAX_FIELD_SIZE];
|
||||
uint8_t curSentenceType;
|
||||
uint8_t curTermNumber;
|
||||
uint8_t curTermOffset;
|
||||
bool sentenceHasFix;
|
||||
|
||||
// custom element support
|
||||
friend class TinyGPSCustom;
|
||||
TinyGPSCustom *customElts;
|
||||
TinyGPSCustom *customCandidates;
|
||||
void insertCustom(TinyGPSCustom *pElt, const char *sentenceName, int index);
|
||||
|
||||
// statistics
|
||||
uint32_t encodedCharCount;
|
||||
uint32_t sentencesWithFixCount;
|
||||
uint32_t failedChecksumCount;
|
||||
uint32_t passedChecksumCount;
|
||||
|
||||
// internal utilities
|
||||
int fromHex(char a);
|
||||
bool endOfTermHandler();
|
||||
};
|
||||
|
||||
#endif // def(__TinyGPSPlus_h)
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
TinyGPSPlus - a small GPS library for Arduino providing universal NMEA parsing
|
||||
Based on work by and "distanceBetween" and "courseTo" courtesy of Maarten Lamers.
|
||||
Suggestion to add satellites, courseTo(), and cardinal() by Matt Monson.
|
||||
Location precision improvements suggested by Wayne Holder.
|
||||
Copyright (C) 2008-2024 Mikal Hart
|
||||
All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __TinyGPSPlus_h
|
||||
#include "TinyGPS++.h"
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
#include "USBHandler.h"
|
||||
#include <cstring>
|
||||
|
||||
USBHandler::USBHandler() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void USBHandler::reset() {
|
||||
current_state = USBState::WAITING_FOR_START;
|
||||
start_flag_received = false;
|
||||
buffer_index = 0;
|
||||
current_settings.resetToDefaults();
|
||||
}
|
||||
|
||||
void USBHandler::processUSBData(const uint8_t* data, uint32_t length) {
|
||||
if (data == nullptr || length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (current_state) {
|
||||
case USBState::WAITING_FOR_START:
|
||||
processStartFlag(data, length);
|
||||
break;
|
||||
|
||||
case USBState::RECEIVING_SETTINGS:
|
||||
processSettingsData(data, length);
|
||||
break;
|
||||
|
||||
case USBState::READY_FOR_DATA:
|
||||
// Ready to receive radar data commands
|
||||
// Add additional command processing here if needed
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void USBHandler::processStartFlag(const uint8_t* data, uint32_t length) {
|
||||
// Start flag: bytes [23, 46, 158, 237]
|
||||
const uint8_t START_FLAG[] = {23, 46, 158, 237};
|
||||
|
||||
// Check if start flag is in the received data
|
||||
for (uint32_t i = 0; i <= length - 4; i++) {
|
||||
if (memcmp(data + i, START_FLAG, 4) == 0) {
|
||||
start_flag_received = true;
|
||||
current_state = USBState::RECEIVING_SETTINGS;
|
||||
buffer_index = 0; // Reset buffer for settings data
|
||||
|
||||
// You can send an acknowledgment back here if needed
|
||||
// sendUSBAcknowledgment();
|
||||
|
||||
// If there's more data after the start flag, process it
|
||||
if (length > i + 4) {
|
||||
processSettingsData(data + i + 4, length - i - 4);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USBHandler::processSettingsData(const uint8_t* data, uint32_t length) {
|
||||
// Add data to buffer
|
||||
uint32_t bytes_to_copy = (length < (MAX_BUFFER_SIZE - buffer_index)) ?
|
||||
length : (MAX_BUFFER_SIZE - buffer_index);
|
||||
|
||||
memcpy(usb_buffer + buffer_index, data, bytes_to_copy);
|
||||
buffer_index += bytes_to_copy;
|
||||
|
||||
// Check if we have a complete settings packet (contains "SET" and "END")
|
||||
if (buffer_index >= 74) { // Minimum size for valid settings packet
|
||||
// Look for "SET" at beginning and "END" somewhere in the packet
|
||||
bool has_set = (memcmp(usb_buffer, "SET", 3) == 0);
|
||||
bool has_end = false;
|
||||
|
||||
for (uint32_t i = 3; i <= buffer_index - 3; i++) {
|
||||
if (memcmp(usb_buffer + i, "END", 3) == 0) {
|
||||
has_end = true;
|
||||
|
||||
// Parse the complete packet up to "END"
|
||||
if (has_set && current_settings.parseFromUSB(usb_buffer, i + 3)) {
|
||||
current_state = USBState::READY_FOR_DATA;
|
||||
|
||||
// You can send settings acknowledgment back here
|
||||
// sendSettingsAcknowledgment();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find a valid packet but buffer is full, reset
|
||||
if (buffer_index >= MAX_BUFFER_SIZE && !has_end) {
|
||||
buffer_index = 0; // Reset buffer to avoid overflow
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef USBHANDLER_H
|
||||
#define USBHANDLER_H
|
||||
|
||||
#include "RadarSettings.h"
|
||||
#include <cstdint>
|
||||
|
||||
class USBHandler {
|
||||
public:
|
||||
enum class USBState {
|
||||
WAITING_FOR_START,
|
||||
RECEIVING_SETTINGS,
|
||||
READY_FOR_DATA
|
||||
};
|
||||
|
||||
USBHandler();
|
||||
|
||||
// Process incoming USB data
|
||||
void processUSBData(const uint8_t* data, uint32_t length);
|
||||
|
||||
// Check if start flag was received
|
||||
bool isStartFlagReceived() const { return start_flag_received; }
|
||||
|
||||
// Get current settings
|
||||
const RadarSettings& getSettings() const { return current_settings; }
|
||||
|
||||
// Get current state
|
||||
USBState getState() const { return current_state; }
|
||||
|
||||
// Reset USB handler
|
||||
void reset();
|
||||
|
||||
private:
|
||||
RadarSettings current_settings;
|
||||
USBState current_state;
|
||||
bool start_flag_received;
|
||||
|
||||
// Buffer for accumulating USB data
|
||||
static constexpr uint32_t MAX_BUFFER_SIZE = 256;
|
||||
uint8_t usb_buffer[MAX_BUFFER_SIZE];
|
||||
uint32_t buffer_index;
|
||||
|
||||
void processStartFlag(const uint8_t* data, uint32_t length);
|
||||
void processSettingsData(const uint8_t* data, uint32_t length);
|
||||
};
|
||||
|
||||
#endif // USBHANDLER_H
|
||||
731
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.c
Normal file
731
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.c
Normal file
@@ -0,0 +1,731 @@
|
||||
/***************************************************************************//**
|
||||
* @file AD9523.c
|
||||
* @brief Implementation of AD9523 Driver.
|
||||
* @author ACozma(andrei.cozma@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2012-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "ad9523.h"
|
||||
#include "no_os_alloc.h"
|
||||
|
||||
/* Helpers to avoid excess line breaks */
|
||||
#define AD_IFE(_pde, _a, _b) ((dev->pdata->_pde) ? _a : _b)
|
||||
#define AD_IF(_pde, _a) AD_IFE(_pde, _a, 0)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Reads the value of the selected register.
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
* @param reg_addr - The address of the register to read.
|
||||
* @param reg_data - Pointer to the read value.
|
||||
|
||||
* @return Returns 0 in case of success or negative error code.
|
||||
*******************************************************************************/
|
||||
int32_t ad9523_spi_read(struct ad9523_dev *dev,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret = 0;
|
||||
uint8_t index;
|
||||
|
||||
*reg_data = 0;
|
||||
for (index = 0; index < AD9523_TRANSF_LEN(reg_addr); index++) {
|
||||
buf[0] = 0x80 | (reg_addr >> 8);
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = 0x00;
|
||||
ret |= no_os_spi_write_and_read(dev->spi_desc,
|
||||
buf,
|
||||
3);
|
||||
reg_addr--;
|
||||
*reg_data <<= 8;
|
||||
*reg_data |= buf[2];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Writes a value to the selected register.
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
* @param reg_addr - The address of the register to write to.
|
||||
* @param reg_data - The value to write to the register.
|
||||
*
|
||||
* @return Returns 0 in case of success or negative error code.
|
||||
*******************************************************************************/
|
||||
int32_t ad9523_spi_write(struct ad9523_dev *dev,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data)
|
||||
{
|
||||
uint8_t buf[3];
|
||||
|
||||
int32_t ret = 0;
|
||||
uint8_t index;
|
||||
|
||||
for (index = 0; index < AD9523_TRANSF_LEN(reg_addr); index++) {
|
||||
buf[0] = reg_addr >> 8;
|
||||
buf[1] = reg_addr & 0xFF;
|
||||
buf[2] = (reg_data >> ((AD9523_TRANSF_LEN(reg_addr) - index - 1) * 8)) & 0xFF;
|
||||
ret |= no_os_spi_write_and_read(dev->spi_desc,
|
||||
buf,
|
||||
3);
|
||||
reg_addr--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Updates the AD9523 configuration
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return Returns 0 in case of success or negative error code.
|
||||
*******************************************************************************/
|
||||
int32_t ad9523_io_update(struct ad9523_dev *dev)
|
||||
{
|
||||
return ad9523_spi_write(dev,
|
||||
AD9523_IO_UPDATE,
|
||||
AD9523_IO_UPDATE_EN);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Sets the clock provider for selected channel.
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
* @param ch - Selected channel.
|
||||
* @param out - Selected clock provider.
|
||||
*
|
||||
* @return Returns 0 in case of success or negative error code.
|
||||
*******************************************************************************/
|
||||
int32_t ad9523_vco_out_map(struct ad9523_dev *dev,
|
||||
uint32_t ch,
|
||||
uint32_t out)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t mask;
|
||||
uint32_t reg_data;
|
||||
|
||||
switch (ch) {
|
||||
case 0 ... 3:
|
||||
ret = ad9523_spi_read(dev,
|
||||
AD9523_PLL1_OUTPUT_CHANNEL_CTRL,
|
||||
®_data);
|
||||
if (ret < 0)
|
||||
break;
|
||||
mask = AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH0 << ch;
|
||||
if (out) {
|
||||
reg_data |= mask;
|
||||
out = AD9523_VCXO;
|
||||
} else {
|
||||
reg_data &= ~mask;
|
||||
}
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_OUTPUT_CHANNEL_CTRL,
|
||||
reg_data);
|
||||
break;
|
||||
case 4 ... 6:
|
||||
ret = ad9523_spi_read(dev,
|
||||
AD9523_PLL1_OUTPUT_CTRL,
|
||||
®_data);
|
||||
if (ret < 0)
|
||||
break;
|
||||
mask = AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH4_M2 << (ch - 4);
|
||||
if (out)
|
||||
reg_data |= mask;
|
||||
else
|
||||
reg_data &= ~mask;
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_OUTPUT_CTRL,
|
||||
reg_data);
|
||||
break;
|
||||
case 7 ... 9:
|
||||
ret = ad9523_spi_read(dev,
|
||||
AD9523_PLL1_OUTPUT_CHANNEL_CTRL,
|
||||
®_data);
|
||||
if (ret < 0)
|
||||
break;
|
||||
mask = AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH7_M2 << (ch - 7);
|
||||
if (out)
|
||||
reg_data |= mask;
|
||||
else
|
||||
reg_data &= ~mask;
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_OUTPUT_CHANNEL_CTRL,
|
||||
reg_data);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->ad9523_st.vco_out_map[ch] = out;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Updates the AD9523 configuration.
|
||||
*
|
||||
* @return Returns 0 in case of success or negative error code.
|
||||
*******************************************************************************/
|
||||
|
||||
// vco calibration on default setup may not work (as it is a buffered write)
|
||||
// calibration requires all registers to be written (not in hold registers) first.
|
||||
|
||||
int32_t ad9523_calibrate(struct ad9523_dev *dev)
|
||||
{
|
||||
uint32_t reg_data;
|
||||
uint32_t timeout;
|
||||
|
||||
ad9523_spi_write(dev,
|
||||
AD9523_PLL2_VCO_CTRL,
|
||||
AD9523_PLL2_VCO_CALIBRATE);
|
||||
ad9523_io_update(dev);
|
||||
|
||||
timeout = 0;
|
||||
while (timeout < 100) {
|
||||
no_os_mdelay(1);
|
||||
timeout = timeout + 1;
|
||||
ad9523_spi_read(dev,
|
||||
AD9523_READBACK_1,
|
||||
®_data);
|
||||
if ((reg_data & 0x1) == 0x0)
|
||||
break;
|
||||
}
|
||||
ad9523_spi_read(dev,
|
||||
AD9523_READBACK_1,
|
||||
®_data);
|
||||
if ((reg_data & 0x1) != 0x0) {
|
||||
printf("AD9523: VCO calibration failed (%#06lx)!\n", reg_data);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Updates the AD9523 configuration.
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return Returns 0 in case of success or negative error code.
|
||||
*******************************************************************************/
|
||||
|
||||
// status
|
||||
// calibration requires all registers to be written (not in hold registers) first.
|
||||
|
||||
int32_t ad9523_status(struct ad9523_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t reg_data;
|
||||
uint32_t status;
|
||||
uint32_t timeout;
|
||||
|
||||
status = 0;
|
||||
|
||||
// vcxo + pll2 must always be okay- (is it not?)
|
||||
|
||||
status = status | AD9523_READBACK_0_STAT_VCXO;
|
||||
status = status | AD9523_READBACK_0_STAT_PLL2_LD;
|
||||
|
||||
if (dev->pdata->pll1_bypass_en == 0) {
|
||||
status = status | AD9523_READBACK_0_STAT_PLL2_REF_CLK;
|
||||
status = status | AD9523_READBACK_0_STAT_PLL2_FB_CLK;
|
||||
status = status | AD9523_READBACK_0_STAT_REF_TEST;
|
||||
status = status | AD9523_READBACK_0_STAT_REFB;
|
||||
status = status | AD9523_READBACK_0_STAT_REFA;
|
||||
status = status | AD9523_READBACK_0_STAT_PLL1_LD;
|
||||
}
|
||||
|
||||
timeout = 0;
|
||||
while (timeout < 100) {
|
||||
no_os_mdelay(1);
|
||||
timeout = timeout + 1;
|
||||
ad9523_spi_read(dev,
|
||||
AD9523_READBACK_0,
|
||||
®_data);
|
||||
if ((reg_data & status) == status)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
if ((reg_data & AD9523_READBACK_0_STAT_VCXO) != AD9523_READBACK_0_STAT_VCXO) {
|
||||
printf("AD9523: VCXO status errors (%#06lx)!\n", reg_data);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if ((reg_data & AD9523_READBACK_0_STAT_PLL2_LD) !=
|
||||
AD9523_READBACK_0_STAT_PLL2_LD) {
|
||||
printf("AD9523: PLL2 NOT locked (%#06lx)!\n", reg_data);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Updates the AD9523 configuration.
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return Returns 0 in case of success or negative error code.
|
||||
*******************************************************************************/
|
||||
int32_t ad9523_sync(struct ad9523_dev *dev)
|
||||
{
|
||||
int32_t ret, tmp;
|
||||
uint32_t reg_data;
|
||||
|
||||
ret = ad9523_spi_read(dev,
|
||||
AD9523_STATUS_SIGNALS,
|
||||
®_data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
tmp = reg_data;
|
||||
tmp |= AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_STATUS_SIGNALS,
|
||||
tmp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ad9523_io_update(dev);
|
||||
tmp &= ~AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_STATUS_SIGNALS,
|
||||
tmp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ad9523_io_update(dev);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Initialize the AD9523 data structure with the default register values.
|
||||
*
|
||||
* @param init_param - The device initial parameters.
|
||||
*
|
||||
* @return Always return 0.
|
||||
*******************************************************************************/
|
||||
int32_t ad9523_init(struct ad9523_init_param *init_param)
|
||||
{
|
||||
|
||||
int32_t i = 0;
|
||||
|
||||
init_param->pdata->vcxo_freq = 0;
|
||||
init_param->pdata->spi3wire = 0;
|
||||
|
||||
/* Differential/ Single-Ended Input Configuration */
|
||||
init_param->pdata->refa_diff_rcv_en = 0;
|
||||
init_param->pdata->refb_diff_rcv_en = 0;
|
||||
init_param->pdata->zd_in_diff_en = 0;
|
||||
init_param->pdata->osc_in_diff_en = 0;
|
||||
|
||||
/*
|
||||
* Valid if differential input disabled
|
||||
* if not true defaults to pos input
|
||||
*/
|
||||
init_param->pdata->refa_cmos_neg_inp_en = 0;
|
||||
init_param->pdata->refb_cmos_neg_inp_en = 0;
|
||||
init_param->pdata->zd_in_cmos_neg_inp_en = 0;
|
||||
init_param->pdata->osc_in_cmos_neg_inp_en = 0;
|
||||
|
||||
/* PLL1 Setting */
|
||||
init_param->pdata->refa_r_div = 1;
|
||||
init_param->pdata->refb_r_div = 1;
|
||||
init_param->pdata->pll1_feedback_div = 1;
|
||||
init_param->pdata->pll1_charge_pump_current_nA = 0;
|
||||
init_param->pdata->zero_delay_mode_internal_en = 0;
|
||||
init_param->pdata->osc_in_feedback_en = 0;
|
||||
init_param->pdata->pll1_bypass_en = 1;
|
||||
init_param->pdata->pll1_loop_filter_rzero = 1;
|
||||
|
||||
/* Reference */
|
||||
init_param->pdata->ref_mode = 0;
|
||||
|
||||
/* PLL2 Setting */
|
||||
init_param->pdata->pll2_charge_pump_current_nA = 0;
|
||||
init_param->pdata->pll2_ndiv_a_cnt = 0;
|
||||
init_param->pdata->pll2_ndiv_b_cnt = 4;
|
||||
init_param->pdata->pll2_freq_doubler_en = 0;
|
||||
init_param->pdata->pll2_r2_div = 0;
|
||||
init_param->pdata->pll2_vco_diff_m1 = 0; /* 3..5 */
|
||||
init_param->pdata->pll2_vco_diff_m2 = 0; /* 3..5 */
|
||||
|
||||
/* Loop Filter PLL2 */
|
||||
init_param->pdata->rpole2 = 0;
|
||||
init_param->pdata->rzero = 0;
|
||||
init_param->pdata->cpole1 = 0;
|
||||
init_param->pdata->rzero_bypass_en = 0;
|
||||
|
||||
/* Output Channel Configuration */
|
||||
for (i = 0; i < init_param->pdata->num_channels; i++) {
|
||||
(&init_param->pdata->channels[i])->channel_num = 0;
|
||||
(&init_param->pdata->channels[i])->divider_output_invert_en = 0;
|
||||
(&init_param->pdata->channels[i])->sync_ignore_en = 0;
|
||||
(&init_param->pdata->channels[i])->low_power_mode_en = 0;
|
||||
(&init_param->pdata->channels[i])->use_alt_clock_src = 0;
|
||||
(&init_param->pdata->channels[i])->output_dis = 0;
|
||||
(&init_param->pdata->channels[i])->driver_mode = LVPECL_8mA;
|
||||
(&init_param->pdata->channels[i])->divider_phase = 0;
|
||||
(&init_param->pdata->channels[i])->channel_divider = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Setup the AD9523 device.
|
||||
*
|
||||
* @param device - The device structure.
|
||||
* @param init_param - The structure holding the device initial parameters.
|
||||
*
|
||||
* @return Returns 0 in case of success or negative error code.
|
||||
*******************************************************************************/
|
||||
int32_t ad9523_setup(struct ad9523_dev **device,
|
||||
const struct ad9523_init_param *init_param)
|
||||
|
||||
{
|
||||
struct ad9523_channel_spec *chan;
|
||||
uint32_t active_mask = 0;
|
||||
int32_t ret, i;
|
||||
uint32_t reg_data;
|
||||
uint32_t version_id;
|
||||
struct ad9523_dev *dev;
|
||||
|
||||
dev = (struct ad9523_dev *)no_os_malloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
return -1;
|
||||
|
||||
/* SPI */
|
||||
ret = no_os_spi_init(&dev->spi_desc, &init_param->spi_init);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev->pdata = init_param->pdata;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_SERIAL_PORT_CONFIG,
|
||||
AD9523_SER_CONF_SOFT_RESET |
|
||||
(dev->pdata->spi3wire ? 0 :
|
||||
AD9523_SER_CONF_SDO_ACTIVE));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
no_os_mdelay(1);
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_READBACK_CTRL,
|
||||
AD9523_READBACK_CTRL_READ_BUFFERED);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_io_update(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_read(dev,
|
||||
AD9523_EEPROM_CUSTOMER_VERSION_ID,
|
||||
&version_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_EEPROM_CUSTOMER_VERSION_ID,
|
||||
0xAD95);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_read(dev,
|
||||
AD9523_EEPROM_CUSTOMER_VERSION_ID,
|
||||
®_data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (reg_data != 0xAD95) {
|
||||
printf("AD9523: SPI write-verify failed (%#06lX)!\n\r",
|
||||
reg_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_EEPROM_CUSTOMER_VERSION_ID,
|
||||
version_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* PLL1 Setup
|
||||
*/
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_REF_A_DIVIDER,
|
||||
dev->pdata->refa_r_div);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_REF_B_DIVIDER,
|
||||
dev->pdata->refb_r_div);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_FEEDBACK_DIVIDER,
|
||||
dev->pdata->pll1_feedback_div);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_CHARGE_PUMP_CTRL,
|
||||
AD_IFE(pll1_bypass_en, AD9523_PLL1_CHARGE_PUMP_TRISTATE,
|
||||
AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(dev->pdata->
|
||||
pll1_charge_pump_current_nA) |
|
||||
AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL |
|
||||
AD9523_PLL1_BACKLASH_PW_MIN));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_INPUT_RECEIVERS_CTRL,
|
||||
AD_IFE(pll1_bypass_en, AD9523_PLL1_REFA_REFB_PWR_CTRL_EN |
|
||||
AD_IF(osc_in_diff_en, AD9523_PLL1_OSC_IN_DIFF_EN) |
|
||||
AD_IF(osc_in_cmos_neg_inp_en, AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN),
|
||||
AD_IF(refa_diff_rcv_en, AD9523_PLL1_REFA_RCV_EN) |
|
||||
AD_IF(refb_diff_rcv_en, AD9523_PLL1_REFB_RCV_EN) |
|
||||
AD_IF(osc_in_diff_en, AD9523_PLL1_OSC_IN_DIFF_EN) |
|
||||
AD_IF(osc_in_cmos_neg_inp_en,
|
||||
AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN) |
|
||||
AD_IF(refa_diff_rcv_en, AD9523_PLL1_REFA_DIFF_RCV_EN) |
|
||||
AD_IF(refb_diff_rcv_en, AD9523_PLL1_REFB_DIFF_RCV_EN)));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_REF_CTRL,
|
||||
AD_IFE(pll1_bypass_en, AD9523_PLL1_BYPASS_FEEDBACK_DIV_EN |
|
||||
AD9523_PLL1_ZERO_DELAY_MODE_INT,
|
||||
AD_IF(zd_in_diff_en, AD9523_PLL1_ZD_IN_DIFF_EN) |
|
||||
AD_IF(zd_in_cmos_neg_inp_en,
|
||||
AD9523_PLL1_ZD_IN_CMOS_NEG_INP_EN) |
|
||||
AD_IF(zero_delay_mode_internal_en,
|
||||
AD9523_PLL1_ZERO_DELAY_MODE_INT) |
|
||||
AD_IF(osc_in_feedback_en, AD9523_PLL1_OSC_IN_PLL_FEEDBACK_EN) |
|
||||
AD_IF(refa_cmos_neg_inp_en, AD9523_PLL1_REFA_CMOS_NEG_INP_EN) |
|
||||
AD_IF(refb_cmos_neg_inp_en, AD9523_PLL1_REFB_CMOS_NEG_INP_EN)));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_MISC_CTRL,
|
||||
AD9523_PLL1_REFB_INDEP_DIV_CTRL_EN |
|
||||
AD9523_PLL1_REF_MODE(dev->pdata->ref_mode));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL1_LOOP_FILTER_CTRL,
|
||||
AD9523_PLL1_LOOP_FILTER_RZERO(dev->pdata->
|
||||
pll1_loop_filter_rzero));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* PLL2 Setup
|
||||
*/
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL2_CHARGE_PUMP,
|
||||
AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(dev->pdata->
|
||||
pll2_charge_pump_current_nA));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL2_FEEDBACK_DIVIDER_AB,
|
||||
AD9523_PLL2_FB_NDIV_A_CNT(dev->pdata->pll2_ndiv_a_cnt) |
|
||||
AD9523_PLL2_FB_NDIV_B_CNT(dev->pdata->pll2_ndiv_b_cnt));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL2_CTRL,
|
||||
AD9523_PLL2_CHARGE_PUMP_MODE_NORMAL |
|
||||
AD9523_PLL2_BACKLASH_CTRL_EN |
|
||||
AD_IF(pll2_freq_doubler_en,
|
||||
AD9523_PLL2_FREQ_DOUBLER_EN));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev->ad9523_st.vco_freq = (dev->pdata->vcxo_freq *
|
||||
(dev->pdata->pll2_freq_doubler_en ? 2 : 1)
|
||||
/ dev->pdata->pll2_r2_div) * AD9523_PLL2_FB_NDIV(dev->pdata->
|
||||
pll2_ndiv_a_cnt,
|
||||
dev->pdata->
|
||||
pll2_ndiv_b_cnt);
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL2_VCO_CTRL,
|
||||
AD9523_PLL2_VCO_CALIBRATE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL2_VCO_DIVIDER,
|
||||
AD9523_PLL2_VCO_DIV_M1(dev->pdata->
|
||||
pll2_vco_diff_m1) |
|
||||
AD9523_PLL2_VCO_DIV_M2(dev->pdata->
|
||||
pll2_vco_diff_m2) |
|
||||
AD_IFE(pll2_vco_diff_m1,
|
||||
0,
|
||||
AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN) |
|
||||
AD_IFE(pll2_vco_diff_m2,
|
||||
0,
|
||||
AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (dev->pdata->pll2_vco_diff_m1)
|
||||
dev->ad9523_st.vco_out_freq[AD9523_VCO1] =
|
||||
dev->ad9523_st.vco_freq / dev->pdata->pll2_vco_diff_m1;
|
||||
|
||||
if (dev->pdata->pll2_vco_diff_m2)
|
||||
dev->ad9523_st.vco_out_freq[AD9523_VCO2] =
|
||||
dev->ad9523_st.vco_freq / dev->pdata->pll2_vco_diff_m2;
|
||||
|
||||
dev->ad9523_st.vco_out_freq[AD9523_VCXO] = dev->pdata->vcxo_freq;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL2_R2_DIVIDER,
|
||||
AD9523_PLL2_R2_DIVIDER_VAL(dev->pdata->pll2_r2_div));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_PLL2_LOOP_FILTER_CTRL,
|
||||
AD9523_PLL2_LOOP_FILTER_CPOLE1(dev->pdata->cpole1) |
|
||||
AD9523_PLL2_LOOP_FILTER_RZERO(dev->pdata->rzero) |
|
||||
AD9523_PLL2_LOOP_FILTER_RPOLE2(dev->pdata->rpole2) |
|
||||
AD_IF(rzero_bypass_en,
|
||||
AD9523_PLL2_LOOP_FILTER_RZERO_BYPASS_EN));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < dev->pdata->num_channels; i++) {
|
||||
chan = &dev->pdata->channels[i];
|
||||
if (chan->channel_num < AD9523_NUM_CHAN) {
|
||||
active_mask |= (1 << chan->channel_num);
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_CHANNEL_CLOCK_DIST(chan->channel_num),
|
||||
AD9523_CLK_DIST_DRIVER_MODE(chan->driver_mode) |
|
||||
AD9523_CLK_DIST_DIV(chan->channel_divider) |
|
||||
AD9523_CLK_DIST_DIV_PHASE(chan->divider_phase) |
|
||||
(chan->sync_ignore_en ?
|
||||
AD9523_CLK_DIST_IGNORE_SYNC_EN : 0) |
|
||||
(chan->divider_output_invert_en ?
|
||||
AD9523_CLK_DIST_INV_DIV_OUTPUT_EN : 0) |
|
||||
(chan->low_power_mode_en ?
|
||||
AD9523_CLK_DIST_LOW_PWR_MODE_EN : 0) |
|
||||
(chan->output_dis ?
|
||||
AD9523_CLK_DIST_PWR_DOWN_EN : 0));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_vco_out_map(dev,
|
||||
chan->channel_num,
|
||||
chan->use_alt_clock_src);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < AD9523_NUM_CHAN; i++) {
|
||||
if (!(active_mask & (1 << i))) {
|
||||
ad9523_spi_write(dev,
|
||||
AD9523_CHANNEL_CLOCK_DIST(i),
|
||||
AD9523_CLK_DIST_DRIVER_MODE(TRISTATE) |
|
||||
AD9523_CLK_DIST_PWR_DOWN_EN);
|
||||
}
|
||||
}
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_POWER_DOWN_CTRL,
|
||||
0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_spi_write(dev,
|
||||
AD9523_STATUS_SIGNALS,
|
||||
AD9523_STATUS_MONITOR_01_PLL12_LOCKED);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_io_update(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad9523_sync(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ad9523_spi_write(dev,
|
||||
AD9523_READBACK_CTRL,
|
||||
0x0);
|
||||
ad9523_io_update(dev);
|
||||
ad9523_calibrate(dev);
|
||||
ad9523_sync(dev);
|
||||
|
||||
*device = dev;
|
||||
|
||||
return (ad9523_status(dev));
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Free the resources allocated by ad9523_setup().
|
||||
*
|
||||
* @param dev - The device structure.
|
||||
*
|
||||
* @return 0 in case of success, negative error code otherwise.
|
||||
*******************************************************************************/
|
||||
int32_t ad9523_remove(struct ad9523_dev *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
ret = no_os_spi_remove(dev->spi_desc);
|
||||
|
||||
no_os_free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
509
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.h
Normal file
509
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/ad9523.h
Normal file
@@ -0,0 +1,509 @@
|
||||
/***************************************************************************//**
|
||||
* @file AD9523.h
|
||||
* @brief Header file of AD9523 Driver.
|
||||
* @author DBogdan (dragos.bogdan@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2012-2016(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifndef _AD9523_H_
|
||||
#define _AD9523_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "no_os_delay.h"
|
||||
#include "no_os_spi.h"
|
||||
|
||||
/* Registers */
|
||||
|
||||
#define AD9523_READ (1 << 15)
|
||||
#define AD9523_WRITE (0 << 15)
|
||||
#define AD9523_CNT(x) (((x) - 1) << 13)
|
||||
#define AD9523_ADDR(x) ((x) & 0xFFF)
|
||||
|
||||
#define AD9523_R1B (1 << 16)
|
||||
#define AD9523_R2B (2 << 16)
|
||||
#define AD9523_R3B (3 << 16)
|
||||
#define AD9523_TRANSF_LEN(x) ((x) >> 16)
|
||||
|
||||
#define AD9523_SERIAL_PORT_CONFIG (AD9523_R1B | 0x0)
|
||||
#define AD9523_VERSION_REGISTER (AD9523_R1B | 0x2)
|
||||
#define AD9523_PART_REGISTER (AD9523_R1B | 0x3)
|
||||
#define AD9523_READBACK_CTRL (AD9523_R1B | 0x4)
|
||||
|
||||
#define AD9523_EEPROM_CUSTOMER_VERSION_ID (AD9523_R2B | 0x6)
|
||||
|
||||
#define AD9523_PLL1_REF_A_DIVIDER (AD9523_R2B | 0x11)
|
||||
#define AD9523_PLL1_REF_B_DIVIDER (AD9523_R2B | 0x13)
|
||||
#define AD9523_PLL1_REF_TEST_DIVIDER (AD9523_R1B | 0x14)
|
||||
#define AD9523_PLL1_FEEDBACK_DIVIDER (AD9523_R2B | 0x17)
|
||||
#define AD9523_PLL1_CHARGE_PUMP_CTRL (AD9523_R2B | 0x19)
|
||||
#define AD9523_PLL1_INPUT_RECEIVERS_CTRL (AD9523_R1B | 0x1A)
|
||||
#define AD9523_PLL1_REF_CTRL (AD9523_R1B | 0x1B)
|
||||
#define AD9523_PLL1_MISC_CTRL (AD9523_R1B | 0x1C)
|
||||
#define AD9523_PLL1_LOOP_FILTER_CTRL (AD9523_R1B | 0x1D)
|
||||
|
||||
#define AD9523_PLL2_CHARGE_PUMP (AD9523_R1B | 0xF0)
|
||||
#define AD9523_PLL2_FEEDBACK_DIVIDER_AB (AD9523_R1B | 0xF1)
|
||||
#define AD9523_PLL2_CTRL (AD9523_R1B | 0xF2)
|
||||
#define AD9523_PLL2_VCO_CTRL (AD9523_R1B | 0xF3)
|
||||
#define AD9523_PLL2_VCO_DIVIDER (AD9523_R1B | 0xF4)
|
||||
#define AD9523_PLL2_LOOP_FILTER_CTRL (AD9523_R2B | 0xF6)
|
||||
#define AD9523_PLL2_R2_DIVIDER (AD9523_R1B | 0xF7)
|
||||
|
||||
#define AD9523_CHANNEL_CLOCK_DIST(ch) (AD9523_R3B | (0x192 + 3 * ch))
|
||||
|
||||
#define AD9523_PLL1_OUTPUT_CTRL (AD9523_R1B | 0x1BA)
|
||||
#define AD9523_PLL1_OUTPUT_CHANNEL_CTRL (AD9523_R1B | 0x1BB)
|
||||
|
||||
#define AD9523_READBACK_0 (AD9523_R1B | 0x22C)
|
||||
#define AD9523_READBACK_1 (AD9523_R1B | 0x22D)
|
||||
|
||||
#define AD9523_STATUS_SIGNALS (AD9523_R3B | 0x232)
|
||||
#define AD9523_POWER_DOWN_CTRL (AD9523_R1B | 0x233)
|
||||
#define AD9523_IO_UPDATE (AD9523_R1B | 0x234)
|
||||
|
||||
#define AD9523_EEPROM_DATA_XFER_STATUS (AD9523_R1B | 0xB00)
|
||||
#define AD9523_EEPROM_ERROR_READBACK (AD9523_R1B | 0xB01)
|
||||
#define AD9523_EEPROM_CTRL1 (AD9523_R1B | 0xB02)
|
||||
#define AD9523_EEPROM_CTRL2 (AD9523_R1B | 0xB03)
|
||||
|
||||
/* AD9523_SERIAL_PORT_CONFIG */
|
||||
|
||||
#define AD9523_SER_CONF_SDO_ACTIVE ((1 << 7) | (1 << 0))
|
||||
#define AD9523_SER_CONF_SOFT_RESET ((1 << 5) | (1 << 2))
|
||||
|
||||
/* AD9523_READBACK_CTRL */
|
||||
#define AD9523_READBACK_CTRL_READ_BUFFERED (1 << 0)
|
||||
|
||||
/* AD9523_PLL1_CHARGE_PUMP_CTRL */
|
||||
#define AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(x) (((x) / 500) & 0x7F)
|
||||
#define AD9523_PLL1_CHARGE_PUMP_TRISTATE (1 << 7)
|
||||
#define AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL (3 << 8)
|
||||
#define AD9523_PLL1_CHARGE_PUMP_MODE_PUMP_DOWN (2 << 8)
|
||||
#define AD9523_PLL1_CHARGE_PUMP_MODE_PUMP_UP (1 << 8)
|
||||
#define AD9523_PLL1_CHARGE_PUMP_MODE_TRISTATE (0 << 8)
|
||||
#define AD9523_PLL1_BACKLASH_PW_MIN (0 << 10)
|
||||
#define AD9523_PLL1_BACKLASH_PW_LOW (1 << 10)
|
||||
#define AD9523_PLL1_BACKLASH_PW_HIGH (2 << 10)
|
||||
#define AD9523_PLL1_BACKLASH_PW_MAX (3 << 10)
|
||||
|
||||
/* AD9523_PLL1_INPUT_RECEIVERS_CTRL */
|
||||
#define AD9523_PLL1_REF_TEST_RCV_EN (1 << 7)
|
||||
#define AD9523_PLL1_REFB_DIFF_RCV_EN (1 << 6)
|
||||
#define AD9523_PLL1_REFA_DIFF_RCV_EN (1 << 5)
|
||||
#define AD9523_PLL1_REFB_RCV_EN (1 << 4)
|
||||
#define AD9523_PLL1_REFA_RCV_EN (1 << 3)
|
||||
#define AD9523_PLL1_REFA_REFB_PWR_CTRL_EN (1 << 2)
|
||||
#define AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN (1 << 1)
|
||||
#define AD9523_PLL1_OSC_IN_DIFF_EN (1 << 0)
|
||||
|
||||
/* AD9523_PLL1_REF_CTRL */
|
||||
#define AD9523_PLL1_BYPASS_REF_TEST_DIV_EN (1 << 7)
|
||||
#define AD9523_PLL1_BYPASS_FEEDBACK_DIV_EN (1 << 6)
|
||||
#define AD9523_PLL1_ZERO_DELAY_MODE_INT (1 << 5)
|
||||
#define AD9523_PLL1_ZERO_DELAY_MODE_EXT (0 << 5)
|
||||
#define AD9523_PLL1_OSC_IN_PLL_FEEDBACK_EN (1 << 4)
|
||||
#define AD9523_PLL1_ZD_IN_CMOS_NEG_INP_EN (1 << 3)
|
||||
#define AD9523_PLL1_ZD_IN_DIFF_EN (1 << 2)
|
||||
#define AD9523_PLL1_REFB_CMOS_NEG_INP_EN (1 << 1)
|
||||
#define AD9523_PLL1_REFA_CMOS_NEG_INP_EN (1 << 0)
|
||||
|
||||
/* AD9523_PLL1_MISC_CTRL */
|
||||
#define AD9523_PLL1_REFB_INDEP_DIV_CTRL_EN (1 << 7)
|
||||
#define AD9523_PLL1_OSC_CTRL_FAIL_VCC_BY2_EN (1 << 6)
|
||||
#define AD9523_PLL1_REF_MODE(x) ((x) << 2)
|
||||
#define AD9523_PLL1_BYPASS_REFB_DIV (1 << 1)
|
||||
#define AD9523_PLL1_BYPASS_REFA_DIV (1 << 0)
|
||||
|
||||
/* AD9523_PLL1_LOOP_FILTER_CTRL */
|
||||
#define AD9523_PLL1_LOOP_FILTER_RZERO(x) ((x) & 0xF)
|
||||
|
||||
/* AD9523_PLL2_CHARGE_PUMP */
|
||||
#define AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(x) ((x) / 3500)
|
||||
|
||||
/* AD9523_PLL2_FEEDBACK_DIVIDER_AB */
|
||||
#define AD9523_PLL2_FB_NDIV_A_CNT(x) (((x) & 0x3) << 6)
|
||||
#define AD9523_PLL2_FB_NDIV_B_CNT(x) (((x) & 0x3F) << 0)
|
||||
#define AD9523_PLL2_FB_NDIV(a, b) (4 * (b) + (a))
|
||||
|
||||
/* AD9523_PLL2_CTRL */
|
||||
#define AD9523_PLL2_CHARGE_PUMP_MODE_NORMAL (3 << 0)
|
||||
#define AD9523_PLL2_CHARGE_PUMP_MODE_PUMP_DOWN (2 << 0)
|
||||
#define AD9523_PLL2_CHARGE_PUMP_MODE_PUMP_UP (1 << 0)
|
||||
#define AD9523_PLL2_CHARGE_PUMP_MODE_TRISTATE (0 << 0)
|
||||
#define AD9523_PLL2_BACKLASH_PW_MIN (0 << 2)
|
||||
#define AD9523_PLL2_BACKLASH_PW_LOW (1 << 2)
|
||||
#define AD9523_PLL2_BACKLASH_PW_HIGH (2 << 2)
|
||||
#define AD9523_PLL2_BACKLASH_PW_MAX (3 << 1)
|
||||
#define AD9523_PLL2_BACKLASH_CTRL_EN (1 << 4)
|
||||
#define AD9523_PLL2_FREQ_DOUBLER_EN (1 << 5)
|
||||
#define AD9523_PLL2_LOCK_DETECT_PWR_DOWN_EN (1 << 7)
|
||||
|
||||
/* AD9523_PLL2_VCO_CTRL */
|
||||
#define AD9523_PLL2_VCO_CALIBRATE (1 << 1)
|
||||
#define AD9523_PLL2_FORCE_VCO_MIDSCALE (1 << 2)
|
||||
#define AD9523_PLL2_FORCE_REFERENCE_VALID (1 << 3)
|
||||
#define AD9523_PLL2_FORCE_RELEASE_SYNC (1 << 4)
|
||||
|
||||
/* AD9523_PLL2_VCO_DIVIDER */
|
||||
#define AD9523_PLL2_VCO_DIV_M1(x) ((((x) - 3) & 0x3) << 0)
|
||||
#define AD9523_PLL2_VCO_DIV_M2(x) ((((x) - 3) & 0x3) << 4)
|
||||
#define AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN (1 << 2)
|
||||
#define AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN (1 << 6)
|
||||
|
||||
/* AD9523_PLL2_LOOP_FILTER_CTRL */
|
||||
#define AD9523_PLL2_LOOP_FILTER_CPOLE1(x) (((x) & 0x7) << 0)
|
||||
#define AD9523_PLL2_LOOP_FILTER_RZERO(x) (((x) & 0x7) << 3)
|
||||
#define AD9523_PLL2_LOOP_FILTER_RPOLE2(x) (((x) & 0x7) << 6)
|
||||
#define AD9523_PLL2_LOOP_FILTER_RZERO_BYPASS_EN (1 << 8)
|
||||
|
||||
/* AD9523_PLL2_R2_DIVIDER */
|
||||
#define AD9523_PLL2_R2_DIVIDER_VAL(x) (((x) & 0x1F) << 0)
|
||||
|
||||
/* AD9523_CHANNEL_CLOCK_DIST */
|
||||
#define AD9523_CLK_DIST_DIV_PHASE(x) (((x) & 0x3F) << 18)
|
||||
#define AD9523_CLK_DIST_DIV_PHASE_REV(x) ((ret >> 18) & 0x3F)
|
||||
#define AD9523_CLK_DIST_DIV(x) ((((x) - 1) & 0x3FF) << 8)
|
||||
#define AD9523_CLK_DIST_DIV_REV(x) (((ret >> 8) & 0x3FF) + 1)
|
||||
#define AD9523_CLK_DIST_INV_DIV_OUTPUT_EN (1 << 7)
|
||||
#define AD9523_CLK_DIST_IGNORE_SYNC_EN (1 << 6)
|
||||
#define AD9523_CLK_DIST_PWR_DOWN_EN (1 << 5)
|
||||
#define AD9523_CLK_DIST_LOW_PWR_MODE_EN (1 << 4)
|
||||
#define AD9523_CLK_DIST_DRIVER_MODE(x) (((x) & 0xF) << 0)
|
||||
|
||||
/* AD9523_PLL1_OUTPUT_CTRL */
|
||||
#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH6_M2 (1 << 7)
|
||||
#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH5_M2 (1 << 6)
|
||||
#define AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH4_M2 (1 << 5)
|
||||
#define AD9523_PLL1_OUTP_CTRL_CMOS_DRV_WEAK (1 << 4)
|
||||
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_1 (0 << 0)
|
||||
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_2 (1 << 0)
|
||||
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_4 (2 << 0)
|
||||
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_8 (4 << 0)
|
||||
#define AD9523_PLL1_OUTP_CTRL_OUTPUT_DIV_16 (8 << 0)
|
||||
|
||||
/* AD9523_PLL1_OUTPUT_CHANNEL_CTRL */
|
||||
#define AD9523_PLL1_OUTP_CH_CTRL_OUTPUT_PWR_DOWN_EN (1 << 7)
|
||||
#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH9_M2 (1 << 6)
|
||||
#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH8_M2 (1 << 5)
|
||||
#define AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH7_M2 (1 << 4)
|
||||
#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH3 (1 << 3)
|
||||
#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH2 (1 << 2)
|
||||
#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH1 (1 << 1)
|
||||
#define AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH0 (1 << 0)
|
||||
|
||||
/* AD9523_READBACK_0 */
|
||||
#define AD9523_READBACK_0_STAT_PLL2_REF_CLK (1 << 7)
|
||||
#define AD9523_READBACK_0_STAT_PLL2_FB_CLK (1 << 6)
|
||||
#define AD9523_READBACK_0_STAT_VCXO (1 << 5)
|
||||
#define AD9523_READBACK_0_STAT_REF_TEST (1 << 4)
|
||||
#define AD9523_READBACK_0_STAT_REFB (1 << 3)
|
||||
#define AD9523_READBACK_0_STAT_REFA (1 << 2)
|
||||
#define AD9523_READBACK_0_STAT_PLL2_LD (1 << 1)
|
||||
#define AD9523_READBACK_0_STAT_PLL1_LD (1 << 0)
|
||||
|
||||
/* AD9523_READBACK_1 */
|
||||
#define AD9523_READBACK_1_HOLDOVER_ACTIVE (1 << 3)
|
||||
#define AD9523_READBACK_1_AUTOMODE_SEL_REFB (1 << 2)
|
||||
#define AD9523_READBACK_1_VCO_CALIB_IN_PROGRESS (1 << 0)
|
||||
|
||||
/* AD9523_STATUS_SIGNALS */
|
||||
#define AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL (1 << 16)
|
||||
#define AD9523_STATUS_MONITOR_01_PLL12_LOCKED (0x302)
|
||||
/* AD9523_POWER_DOWN_CTRL */
|
||||
#define AD9523_POWER_DOWN_CTRL_PLL1_PWR_DOWN (1 << 2)
|
||||
#define AD9523_POWER_DOWN_CTRL_PLL2_PWR_DOWN (1 << 1)
|
||||
#define AD9523_POWER_DOWN_CTRL_DIST_PWR_DOWN (1 << 0)
|
||||
|
||||
/* AD9523_IO_UPDATE */
|
||||
#define AD9523_IO_UPDATE_EN (1 << 0)
|
||||
|
||||
/* AD9523_EEPROM_DATA_XFER_STATUS */
|
||||
#define AD9523_EEPROM_DATA_XFER_IN_PROGRESS (1 << 0)
|
||||
|
||||
/* AD9523_EEPROM_ERROR_READBACK */
|
||||
#define AD9523_EEPROM_ERROR_READBACK_FAIL (1 << 0)
|
||||
|
||||
/* AD9523_EEPROM_CTRL1 */
|
||||
#define AD9523_EEPROM_CTRL1_SOFT_EEPROM (1 << 1)
|
||||
#define AD9523_EEPROM_CTRL1_EEPROM_WRITE_PROT_DIS (1 << 0)
|
||||
|
||||
/* AD9523_EEPROM_CTRL2 */
|
||||
#define AD9523_EEPROM_CTRL2_REG2EEPROM (1 << 0)
|
||||
|
||||
#define AD9523_NUM_CHAN 14
|
||||
#define AD9523_NUM_CHAN_ALT_CLK_SRC 10
|
||||
|
||||
enum outp_drv_mode {
|
||||
TRISTATE,
|
||||
LVPECL_8mA,
|
||||
LVDS_4mA,
|
||||
LVDS_7mA,
|
||||
HSTL0_16mA,
|
||||
HSTL1_8mA,
|
||||
CMOS_CONF1,
|
||||
CMOS_CONF2,
|
||||
CMOS_CONF3,
|
||||
CMOS_CONF4,
|
||||
CMOS_CONF5,
|
||||
CMOS_CONF6,
|
||||
CMOS_CONF7,
|
||||
CMOS_CONF8,
|
||||
CMOS_CONF9
|
||||
};
|
||||
|
||||
enum ref_sel_mode {
|
||||
NONEREVERTIVE_STAY_ON_REFB,
|
||||
REVERT_TO_REFA,
|
||||
SELECT_REFA,
|
||||
SELECT_REFB,
|
||||
EXT_REF_SEL
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct ad9523_channel_spec
|
||||
* @brief Output channel configuration
|
||||
*/
|
||||
struct ad9523_channel_spec {
|
||||
/** Output channel number. */
|
||||
uint8_t channel_num;
|
||||
/** Invert the polarity of the output clock. */
|
||||
uint8_t divider_output_invert_en;
|
||||
/** Ignore chip-level SYNC signal. */
|
||||
uint8_t sync_ignore_en;
|
||||
/** Reduce power used in the differential output modes. */
|
||||
uint8_t low_power_mode_en;
|
||||
/** Channel divider uses alternative clk source: CH0..CH3 VCXO, CH4..CH9 VCO2 */
|
||||
uint8_t use_alt_clock_src;
|
||||
/** Disables, powers down the entire channel. */
|
||||
uint8_t output_dis;
|
||||
/** Output driver mode (logic level family). */
|
||||
uint8_t driver_mode;
|
||||
/** Divider initial phase after a SYNC. Range 0..63
|
||||
* LSB = 1/2 of a period of the divider input clock.
|
||||
*/
|
||||
uint8_t divider_phase;
|
||||
/** 10-bit channel divider. */
|
||||
uint16_t channel_divider;
|
||||
/** Optional descriptive channel name. */
|
||||
int8_t extended_name[16];
|
||||
};
|
||||
|
||||
enum pll1_rzero_resistor {
|
||||
RZERO_883_OHM,
|
||||
RZERO_677_OHM,
|
||||
RZERO_341_OHM,
|
||||
RZERO_135_OHM,
|
||||
RZERO_10_OHM,
|
||||
RZERO_USE_EXT_RES = 8,
|
||||
};
|
||||
|
||||
enum rpole2_resistor {
|
||||
RPOLE2_900_OHM,
|
||||
RPOLE2_450_OHM,
|
||||
RPOLE2_300_OHM,
|
||||
RPOLE2_225_OHM,
|
||||
};
|
||||
|
||||
enum rzero_resistor {
|
||||
RZERO_3250_OHM,
|
||||
RZERO_2750_OHM,
|
||||
RZERO_2250_OHM,
|
||||
RZERO_2100_OHM,
|
||||
RZERO_3000_OHM,
|
||||
RZERO_2500_OHM,
|
||||
RZERO_2000_OHM,
|
||||
RZERO_1850_OHM,
|
||||
};
|
||||
|
||||
enum cpole1_capacitor {
|
||||
CPOLE1_0_PF,
|
||||
CPOLE1_8_PF,
|
||||
CPOLE1_16_PF,
|
||||
CPOLE1_24_PF,
|
||||
_CPOLE1_24_PF, /* place holder */
|
||||
CPOLE1_32_PF,
|
||||
CPOLE1_40_PF,
|
||||
CPOLE1_48_PF,
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct ad9523_platform_data
|
||||
* @brief platform specific information
|
||||
*/
|
||||
struct ad9523_platform_data {
|
||||
/** External VCXO frequency in Hz */
|
||||
uint32_t vcxo_freq;
|
||||
/** Enable SPI-3wire mode */
|
||||
uint8_t spi3wire;
|
||||
|
||||
/** REFA differential/single-ended input selection. */
|
||||
uint8_t refa_diff_rcv_en;
|
||||
/** REFB differential/single-ended input selection. */
|
||||
uint8_t refb_diff_rcv_en;
|
||||
/** Zero Delay differential/single-ended input selection. */
|
||||
uint8_t zd_in_diff_en;
|
||||
/** OSC differential/ single-ended input selection. */
|
||||
uint8_t osc_in_diff_en;
|
||||
|
||||
/*
|
||||
* Valid if differential input disabled
|
||||
* if not true defaults to pos input
|
||||
*/
|
||||
/** REFA single-ended neg./pos. input enable. */
|
||||
uint8_t refa_cmos_neg_inp_en;
|
||||
/* REFB single-ended neg./pos. input enable. */
|
||||
uint8_t refb_cmos_neg_inp_en;
|
||||
/** Zero Delay single-ended neg./pos. input enable. */
|
||||
uint8_t zd_in_cmos_neg_inp_en;
|
||||
/** OSC single-ended neg./pos. input enable. */
|
||||
uint8_t osc_in_cmos_neg_inp_en;
|
||||
|
||||
/* PLL1 Setting */
|
||||
/** PLL1 10-bit: REFA R divider. */
|
||||
uint16_t refa_r_div;
|
||||
/** PLL1 10-bit: REFB R divider. */
|
||||
uint16_t refb_r_div;
|
||||
/** PLL1 10-bit Feedback N divider. */
|
||||
uint16_t pll1_feedback_div;
|
||||
/** Magnitude of PLL1 charge pump current (nA). */
|
||||
uint16_t pll1_charge_pump_current_nA;
|
||||
/** Internal, external Zero Delay mode selection. */
|
||||
uint8_t zero_delay_mode_internal_en;
|
||||
/** PLL1 feedback path, local feedback from the
|
||||
* OSC_IN receiver or zero delay mode
|
||||
*/
|
||||
uint8_t osc_in_feedback_en;
|
||||
|
||||
/** Bypass PLL1 - Single loop mode */
|
||||
uint8_t pll1_bypass_en;
|
||||
/** PLL1 Loop Filter Zero Resistor selection. */
|
||||
uint8_t pll1_loop_filter_rzero;
|
||||
|
||||
/** Reference mode selection. */
|
||||
uint8_t ref_mode;
|
||||
|
||||
/* PLL2 Setting */
|
||||
/** Magnitude of PLL2 charge pump current (nA). */
|
||||
uint32_t pll2_charge_pump_current_nA;
|
||||
/** PLL2 Feedback N-divider, A Counter, range 0..4. */
|
||||
uint8_t pll2_ndiv_a_cnt;
|
||||
/** PLL2 Feedback N-divider, B Counter, range 0..63. */
|
||||
uint8_t pll2_ndiv_b_cnt;
|
||||
/** PLL2 frequency doubler enable. */
|
||||
uint8_t pll2_freq_doubler_en;
|
||||
/** PLL2 R2 divider, range 0..31. */
|
||||
uint8_t pll2_r2_div;
|
||||
/** VCO1 divider, range 3..5. */
|
||||
uint8_t pll2_vco_diff_m1;
|
||||
/** VCO2 divider, range 3..5. */
|
||||
uint8_t pll2_vco_diff_m2;
|
||||
|
||||
/* Loop Filter PLL2 */
|
||||
/** PLL2 loop filter Rpole resistor value. */
|
||||
uint8_t rpole2;
|
||||
/** PLL2 loop filter Rzero resistor value. */
|
||||
uint8_t rzero;
|
||||
/** PLL2 loop filter Cpole capacitor value. */
|
||||
uint8_t cpole1;
|
||||
/** PLL2 loop filter Rzero bypass enable. */
|
||||
uint8_t rzero_bypass_en;
|
||||
|
||||
/* Output Channel Configuration */
|
||||
/** Array size of struct ad9523_channel_spec. */
|
||||
int32_t num_channels;
|
||||
/** Pointer to channel array. */
|
||||
struct ad9523_channel_spec *channels;
|
||||
|
||||
/** Optional alternative iio device name. */
|
||||
int8_t name[16];
|
||||
};
|
||||
|
||||
struct ad9523_state {
|
||||
struct ad9523_platform_data *pdata;
|
||||
uint32_t vcxo_freq;
|
||||
uint32_t vco_freq;
|
||||
uint32_t vco_out_freq[3];
|
||||
uint8_t vco_out_map[14];
|
||||
};
|
||||
|
||||
enum ad9523_out_frequencies {
|
||||
AD9523_VCO1,
|
||||
AD9523_VCO2,
|
||||
AD9523_VCXO,
|
||||
AD9523_NUM_CLK_SRC,
|
||||
};
|
||||
|
||||
struct ad9523_dev {
|
||||
/* SPI */
|
||||
struct no_os_spi_desc *spi_desc;
|
||||
/* Device Settings */
|
||||
struct ad9523_state ad9523_st;
|
||||
struct ad9523_platform_data *pdata;
|
||||
};
|
||||
|
||||
struct ad9523_init_param {
|
||||
/* SPI */
|
||||
struct no_os_spi_init_param spi_init;
|
||||
/* Device Settings */
|
||||
struct ad9523_platform_data *pdata;
|
||||
};
|
||||
|
||||
/* Reads the value of the selected register. */
|
||||
int32_t ad9523_spi_read(struct ad9523_dev *dev,
|
||||
uint32_t reg_addr,
|
||||
uint32_t *reg_data);
|
||||
|
||||
/* Writes a value to the selected register. */
|
||||
int32_t ad9523_spi_write(struct ad9523_dev *dev,
|
||||
uint32_t reg_addr,
|
||||
uint32_t reg_data);
|
||||
|
||||
/* Updates the AD9523 configuration */
|
||||
int32_t ad9523_io_update(struct ad9523_dev *dev);
|
||||
|
||||
/* Sets the clock provider for selected channel. */
|
||||
int32_t ad9523_vco_out_map(struct ad9523_dev *dev,
|
||||
uint32_t ch,
|
||||
uint32_t out);
|
||||
|
||||
/* Updates the AD9523 configuration. */
|
||||
int32_t ad9523_sync(struct ad9523_dev *dev);
|
||||
|
||||
/* Initialize the AD9523 data structure*/
|
||||
int32_t ad9523_init(struct ad9523_init_param *init_param);
|
||||
|
||||
/* Configure the AD9523. */
|
||||
int32_t ad9523_setup(struct ad9523_dev **device,
|
||||
const struct ad9523_init_param *init_param);
|
||||
|
||||
/* Free the resources allocated by ad9523_setup(). */
|
||||
int32_t ad9523_remove(struct ad9523_dev *dev);
|
||||
|
||||
int32_t ad9523_status(struct ad9523_dev *dev);
|
||||
#endif // __AD9523_H__
|
||||
693
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adar1000.c
Normal file
693
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adar1000.c
Normal file
@@ -0,0 +1,693 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 Jimmy Pentz
|
||||
*
|
||||
* Reach me at: github.com/jgpentz, jpentz1(at)gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sells
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
/* ADAR1000 4-Channel, X Band and Ku Band Beamformer */
|
||||
// ----------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "main.h"
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "stm32f7xx_hal_spi.h"
|
||||
#include "stm32f7xx_hal_gpio.h"
|
||||
#include "adar1000.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Preprocessor Definitions and Constants
|
||||
// ----------------------------------------------------------------------------
|
||||
// VM_GAIN is 15 dB of gain in 128 steps. ~0.12 dB per step.
|
||||
// A 15 dB attenuator can be applied on top of these values.
|
||||
const uint8_t VM_GAIN[128] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
};
|
||||
|
||||
// VM_I and VM_Q are the settings for the vector modulator. 128 steps in 360 degrees. ~2.813 degrees per step.
|
||||
const uint8_t VM_I[128] = {
|
||||
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D, 0x3C, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x37,
|
||||
0x36, 0x35, 0x34, 0x33, 0x32, 0x30, 0x2F, 0x2E, 0x2C, 0x2B, 0x2A, 0x28, 0x27, 0x25, 0x24, 0x22,
|
||||
0x21, 0x01, 0x03, 0x04, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13, 0x14,
|
||||
0x16, 0x17, 0x18, 0x19, 0x19, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F,
|
||||
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E, 0x1D, 0x1D, 0x1C, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17,
|
||||
0x16, 0x15, 0x14, 0x13, 0x12, 0x10, 0x0F, 0x0E, 0x0C, 0x0B, 0x0A, 0x08, 0x07, 0x05, 0x04, 0x02,
|
||||
0x01, 0x21, 0x23, 0x24, 0x26, 0x27, 0x28, 0x2A, 0x2B, 0x2D, 0x2E, 0x2F, 0x31, 0x32, 0x33, 0x34,
|
||||
0x36, 0x37, 0x38, 0x39, 0x39, 0x3A, 0x3B, 0x3C, 0x3C, 0x3D, 0x3E, 0x3E, 0x3E, 0x3F, 0x3F, 0x3F,
|
||||
};
|
||||
|
||||
const uint8_t VM_Q[128] = {
|
||||
0x20, 0x21, 0x23, 0x24, 0x26, 0x27, 0x28, 0x2A, 0x2B, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x33, 0x34,
|
||||
0x35, 0x36, 0x37, 0x38, 0x38, 0x39, 0x3A, 0x3A, 0x3B, 0x3C, 0x3C, 0x3C, 0x3D, 0x3D, 0x3D, 0x3D,
|
||||
0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3C, 0x3C, 0x3C, 0x3B, 0x3A, 0x3A, 0x39, 0x38, 0x38, 0x37, 0x36,
|
||||
0x35, 0x34, 0x33, 0x31, 0x30, 0x2F, 0x2E, 0x2D, 0x2B, 0x2A, 0x28, 0x27, 0x26, 0x24, 0x23, 0x21,
|
||||
0x20, 0x01, 0x03, 0x04, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x14,
|
||||
0x15, 0x16, 0x17, 0x18, 0x18, 0x19, 0x1A, 0x1A, 0x1B, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D,
|
||||
0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1B, 0x1A, 0x1A, 0x19, 0x18, 0x18, 0x17, 0x16,
|
||||
0x15, 0x14, 0x13, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01,
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Function Definitions
|
||||
// ----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Initialize the ADC on the ADAR by setting the ADC with a 2 MHz clk,
|
||||
* and then enable it.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @warning This is setup to only read temperature sensor data, not the power detectors.
|
||||
*/
|
||||
void Adar_AdcInit(const AdarDevice * p_adar, uint8_t broadcast)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
data = ADAR1000_ADC_2MHZ_CLK | ADAR1000_ADC_EN;
|
||||
|
||||
Adar_Write(p_adar, REG_ADC_CONTROL, data, broadcast);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read a byte of data from the ADAR.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @return Returns a byte of data that has been converted from the temperature sensor.
|
||||
*
|
||||
* @warning This is setup to only read temperature sensor data, not the power detectors.
|
||||
*/
|
||||
uint8_t Adar_AdcRead(const AdarDevice * p_adar, uint8_t broadcast)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
// Start the ADC conversion
|
||||
Adar_Write(p_adar, REG_ADC_CONTROL, ADAR1000_ADC_ST_CONV, broadcast);
|
||||
|
||||
// This is blocking for now... wait until data is converted, then read it
|
||||
while (!(Adar_Read(p_adar, REG_ADC_CONTROL) & 0x01))
|
||||
{
|
||||
}
|
||||
|
||||
data = Adar_Read(p_adar, REG_ADC_OUT);
|
||||
|
||||
return(data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Requests the device info from a specific ADAR and stores it in the
|
||||
* provided AdarDeviceInfo struct.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param info[out] Struct that contains the device info fields.
|
||||
*
|
||||
* @return Returns ADAR_ERROR_NOERROR if information was successfully received and stored in the struct.
|
||||
*/
|
||||
uint8_t Adar_GetDeviceInfo(const AdarDevice * p_adar, AdarDeviceInfo * info)
|
||||
{
|
||||
*((uint8_t *)info) = Adar_Read(p_adar, 0x002);
|
||||
info->chip_type = Adar_Read(p_adar, 0x003);
|
||||
info->product_id = ((uint16_t)Adar_Read(p_adar, 0x004)) << 8;
|
||||
info->product_id |= ((uint16_t)Adar_Read(p_adar, 0x005)) & 0x00ff;
|
||||
info->scratchpad = Adar_Read(p_adar, 0x00A);
|
||||
info->spi_rev = Adar_Read(p_adar, 0x00B);
|
||||
info->vendor_id = ((uint16_t)Adar_Read(p_adar, 0x00C)) << 8;
|
||||
info->vendor_id |= ((uint16_t)Adar_Read(p_adar, 0x00D)) & 0x00ff;
|
||||
info->rev_id = Adar_Read(p_adar, 0x045);
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read the data that is stored in a single ADAR register.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param mem_addr Memory address of the register you wish to read from.
|
||||
*
|
||||
* @return Returns the byte of data that is stored in the desired register.
|
||||
*
|
||||
* @warning This function will clear ADDR_ASCN bits.
|
||||
* @warning The ADAR does not allow for block reads.
|
||||
*/
|
||||
uint8_t Adar_Read(const AdarDevice * p_adar, uint32_t mem_addr)
|
||||
{
|
||||
uint8_t instruction[3];
|
||||
|
||||
// Set SDO active
|
||||
Adar_Write(p_adar, REG_INTERFACE_CONFIG_A, INTERFACE_CONFIG_A_SDO_ACTIVE, 0);
|
||||
|
||||
instruction[0] = 0x80 | ((p_adar->dev_addr & 0x03) << 5);
|
||||
instruction[0] |= ((0xff00 & mem_addr) >> 8);
|
||||
instruction[1] = (0xff & mem_addr);
|
||||
instruction[2] = 0x00;
|
||||
|
||||
p_adar->Transfer(instruction, p_adar->p_rx_buffer, ADAR1000_RD_SIZE);
|
||||
|
||||
// Set SDO Inactive
|
||||
Adar_Write(p_adar, REG_INTERFACE_CONFIG_A, 0, 0);
|
||||
|
||||
return(p_adar->p_rx_buffer[2]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Block memory write to an ADAR device.
|
||||
*
|
||||
* @pre ADDR_ASCN bits in register zero must be set!
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param mem_addr Memory address of the register you wish to read from.
|
||||
* @param p_data Pointer to block of data to transfer (must have two unused bytes preceding the data for instruction).
|
||||
* @param size Size of data in bytes, including the two additional leading bytes.
|
||||
*
|
||||
* @warning First two bytes of data will be corrupted if you do not provide two unused leading bytes!
|
||||
*/
|
||||
void Adar_ReadBlock(const AdarDevice * p_adar, uint16_t mem_addr, uint8_t * p_data, uint32_t size)
|
||||
{
|
||||
// Set SDO active
|
||||
Adar_Write(p_adar, REG_INTERFACE_CONFIG_A, INTERFACE_CONFIG_A_SDO_ACTIVE | INTERFACE_CONFIG_A_ADDR_ASCN, 0);
|
||||
|
||||
// Prepare command
|
||||
p_data[0] = 0x80 | ((p_adar->dev_addr & 0x03) << 5);
|
||||
p_data[0] |= ((mem_addr) >> 8) & 0x1F;
|
||||
p_data[1] = (0xFF & mem_addr);
|
||||
|
||||
// Start the transfer
|
||||
p_adar->Transfer(p_data, p_data, size);
|
||||
|
||||
Adar_Write(p_adar, REG_INTERFACE_CONFIG_A, 0, 0);
|
||||
// Return nothing since we assume this is non-blocking and won't wait around
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sets the Rx/Tx bias currents for the LNA, VM, and VGA to be in either
|
||||
* low power setting or nominal setting.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param p_bias[in] An AdarBiasCurrents struct filled with bias settings
|
||||
* as seen in the datasheet Table 6. SPI Settings for
|
||||
* Different Power Modules
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @return Returns ADAR_ERR_NOERROR if the bias currents were set
|
||||
*/
|
||||
uint8_t Adar_SetBiasCurrents(const AdarDevice * p_adar, AdarBiasCurrents * p_bias, uint8_t broadcast)
|
||||
{
|
||||
uint8_t bias = 0;
|
||||
|
||||
// RX LNA/VGA/VM bias
|
||||
bias = (p_bias->rx_lna & 0x0f);
|
||||
Adar_Write(p_adar, REG_BIAS_CURRENT_RX_LNA, bias, broadcast); // RX LNA bias
|
||||
bias = (p_bias->rx_vga & 0x07 << 3) | (p_bias->rx_vm & 0x07);
|
||||
Adar_Write(p_adar, REG_BIAS_CURRENT_RX, bias, broadcast); // RX VM/VGA bias
|
||||
|
||||
// TX VGA/VM/DRV bias
|
||||
bias = (p_bias->tx_vga & 0x07 << 3) | (p_bias->tx_vm & 0x07);
|
||||
Adar_Write(p_adar, REG_BIAS_CURRENT_TX, bias, broadcast); // TX VM/VGA bias
|
||||
bias = (p_bias->tx_drv & 0x07);
|
||||
Adar_Write(p_adar, REG_BIAS_CURRENT_TX_DRV, bias, broadcast); // TX DRV bias
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the bias ON and bias OFF voltages for the four PA's and one LNA.
|
||||
*
|
||||
* @pre This will set all 5 bias ON values and all 5 bias OFF values at once.
|
||||
* To enable these bias values, please see the data sheet and ensure that the BIAS_CTRL,
|
||||
* LNA_BIAS_OUT_EN, TR_SOURCE, TX_EN, RX_EN, TR (input to chip), and PA_ON (input to chip)
|
||||
* bits have all been properly set.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param bias_on_voltage Array that contains the bias ON voltages.
|
||||
* @param bias_off_voltage Array that contains the bias OFF voltages.
|
||||
*
|
||||
* @return Returns ADAR_ERR_NOERROR if the bias currents were set
|
||||
*/
|
||||
uint8_t Adar_SetBiasVoltages(const AdarDevice * p_adar, uint8_t bias_on_voltage[5], uint8_t bias_off_voltage[5])
|
||||
{
|
||||
Adar_SetBit(p_adar, 0x30, 6, BROADCAST_OFF);
|
||||
Adar_SetBit(p_adar, 0x31, 2, BROADCAST_OFF);
|
||||
Adar_SetBit(p_adar, 0x38, 5, BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_PA_CH1_BIAS_ON,bias_on_voltage[0], BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_PA_CH2_BIAS_ON,bias_on_voltage[1], BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_PA_CH3_BIAS_ON,bias_on_voltage[2], BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_PA_CH4_BIAS_ON,bias_on_voltage[3], BROADCAST_OFF);
|
||||
|
||||
Adar_Write(p_adar, REG_PA_CH1_BIAS_OFF,bias_off_voltage[0], BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_PA_CH2_BIAS_OFF,bias_off_voltage[1], BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_PA_CH3_BIAS_OFF,bias_off_voltage[2], BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_PA_CH4_BIAS_OFF,bias_off_voltage[3], BROADCAST_OFF);
|
||||
|
||||
Adar_SetBit(p_adar, 0x30, 4, BROADCAST_OFF);
|
||||
Adar_SetBit(p_adar, 0x30, 6, BROADCAST_OFF);
|
||||
Adar_SetBit(p_adar, 0x31, 2, BROADCAST_OFF);
|
||||
Adar_SetBit(p_adar, 0x38, 5, BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_LNA_BIAS_ON,bias_on_voltage[4], BROADCAST_OFF);
|
||||
Adar_Write(p_adar, REG_LNA_BIAS_OFF,bias_off_voltage[4], BROADCAST_OFF);
|
||||
|
||||
Adar_ResetBit(p_adar, 0x30, 7, BROADCAST_OFF);
|
||||
Adar_SetBit(p_adar, 0x31, 2, BROADCAST_OFF);
|
||||
Adar_SetBit(p_adar, 0x31, 4, BROADCAST_OFF);
|
||||
Adar_SetBit(p_adar, 0x31, 7, BROADCAST_OFF);
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Setup the ADAR to use settings that are transferred over SPI.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @return Returns ADAR_ERR_NOERROR if the bias currents were set
|
||||
*/
|
||||
uint8_t Adar_SetRamBypass(const AdarDevice * p_adar, uint8_t broadcast)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
data = (MEM_CTRL_BIAS_RAM_BYPASS | MEM_CTRL_BEAM_RAM_BYPASS);
|
||||
|
||||
Adar_Write(p_adar, REG_MEM_CTL, data, broadcast);
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the VGA gain value of a Receive channel in dB.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param channel Channel in which to set the gain (1-4).
|
||||
* @param vga_gain_db Gain to be applied to the channel, ranging from 0 - 30 dB.
|
||||
* (Intended operation >16 dB).
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @return Returns ADAR_ERROR_NOERROR if the gain was successfully set.
|
||||
* ADAR_ERROR_FAILED if an invalid channel was selected.
|
||||
*
|
||||
* @warning 0 dB or 15 dB step attenuator may also be turned on, which is why intended operation is >16 dB.
|
||||
*/
|
||||
uint8_t Adar_SetRxVgaGain(const AdarDevice * p_adar, uint8_t channel, uint8_t vga_gain_db, uint8_t broadcast)
|
||||
{
|
||||
uint8_t vga_gain_bits = (uint8_t)(255*vga_gain_db/16);
|
||||
uint32_t mem_addr = 0;
|
||||
|
||||
if((channel == 0) || (channel > 4))
|
||||
{
|
||||
return(ADAR_ERROR_FAILED);
|
||||
}
|
||||
|
||||
mem_addr = REG_CH1_RX_GAIN + (channel & 0x03);
|
||||
|
||||
// Set gain
|
||||
Adar_Write(p_adar, mem_addr, vga_gain_bits, broadcast);
|
||||
|
||||
// Load the new setting
|
||||
Adar_Write(p_adar, REG_LOAD_WORKING, 0x1, broadcast);
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the phase of a given receive channel using the I/Q vector modulator.
|
||||
*
|
||||
* @pre According to the given @param phase, this sets the polarity (bit 5) and gain (bits 4-0)
|
||||
* of the @param channel, and then loads them into the working register.
|
||||
* A vector modulator I/Q look-up table has been provided at the beginning of this library.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param channel Channel in which to set the gain (1-4).
|
||||
* @param phase Byte that is used to set the polarity (bit 5) and gain (bits 4-0).
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @return Returns ADAR_ERROR_NOERROR if the phase was successfully set.
|
||||
* ADAR_ERROR_FAILED if an invalid channel was selected.
|
||||
*
|
||||
* @note To obtain your phase:
|
||||
* phase = degrees * 128;
|
||||
* phase /= 360;
|
||||
*/
|
||||
uint8_t Adar_SetRxPhase(const AdarDevice * p_adar, uint8_t channel, uint8_t phase, uint8_t broadcast)
|
||||
{
|
||||
uint8_t i_val = 0;
|
||||
uint8_t q_val = 0;
|
||||
uint32_t mem_addr_i, mem_addr_q;
|
||||
|
||||
if((channel == 0) || (channel > 4))
|
||||
{
|
||||
return(ADAR_ERROR_FAILED);
|
||||
}
|
||||
|
||||
//phase = phase % 128;
|
||||
i_val = VM_I[phase];
|
||||
q_val = VM_Q[phase];
|
||||
|
||||
mem_addr_i = REG_CH1_RX_PHS_I + (channel & 0x03) * 2;
|
||||
mem_addr_q = REG_CH1_RX_PHS_Q + (channel & 0x03) * 2;
|
||||
|
||||
Adar_Write(p_adar, mem_addr_i, i_val, broadcast);
|
||||
Adar_Write(p_adar, mem_addr_q, q_val, broadcast);
|
||||
Adar_Write(p_adar, REG_LOAD_WORKING, 0x1, broadcast);
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the VGA gain value of a Tx channel in dB.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @return Returns ADAR_ERROR_NOERROR if the bias was successfully set.
|
||||
* ADAR_ERROR_FAILED if an invalid channel was selected.
|
||||
*
|
||||
* @warning 0 dB or 15 dB step attenuator may also be turned on, which is why intended operation is >16 dB.
|
||||
*/
|
||||
uint8_t Adar_SetTxBias(const AdarDevice * p_adar, uint8_t broadcast)
|
||||
{
|
||||
uint8_t vga_bias_bits;
|
||||
uint8_t drv_bias_bits;
|
||||
uint32_t mem_vga_bias;
|
||||
uint32_t mem_drv_bias;
|
||||
|
||||
mem_vga_bias = REG_BIAS_CURRENT_TX;
|
||||
mem_drv_bias = REG_BIAS_CURRENT_TX_DRV;
|
||||
|
||||
// Set bias to nom
|
||||
vga_bias_bits = 0x2D;
|
||||
drv_bias_bits = 0x06;
|
||||
|
||||
// Set bias
|
||||
Adar_Write(p_adar, mem_vga_bias, vga_bias_bits, broadcast);
|
||||
// Set bias
|
||||
Adar_Write(p_adar, mem_drv_bias, drv_bias_bits, broadcast);
|
||||
|
||||
// Load the new setting
|
||||
Adar_Write(p_adar, REG_LOAD_WORKING, 0x2, broadcast);
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the VGA gain value of a Tx channel.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param channel Tx channel in which to set the gain, ranging from 1 - 4.
|
||||
* @param gain Gain to be applied to the channel, ranging from 0 - 127,
|
||||
* plus the MSb 15dB attenuator (Intended operation >16 dB).
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @return Returns ADAR_ERROR_NOERROR if the gain was successfully set.
|
||||
* ADAR_ERROR_FAILED if an invalid channel was selected.
|
||||
*
|
||||
* @warning 0 dB or 15 dB step attenuator may also be turned on, which is why intended operation is >16 dB.
|
||||
*/
|
||||
uint8_t Adar_SetTxVgaGain(const AdarDevice * p_adar, uint8_t channel, uint8_t gain, uint8_t broadcast)
|
||||
{
|
||||
uint32_t mem_addr;
|
||||
|
||||
if((channel == 0) || (channel > 4))
|
||||
{
|
||||
return(ADAR_ERROR_FAILED);
|
||||
}
|
||||
|
||||
mem_addr = REG_CH1_TX_GAIN + (channel & 0x03);
|
||||
|
||||
// Set gain
|
||||
Adar_Write(p_adar, mem_addr, gain, broadcast);
|
||||
|
||||
// Load the new setting
|
||||
Adar_Write(p_adar, REG_LOAD_WORKING, LD_WRK_REGS_LDTX_OVERRIDE, broadcast);
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the phase of a given transmit channel using the I/Q vector modulator.
|
||||
*
|
||||
* @pre According to the given @param phase, this sets the polarity (bit 5) and gain (bits 4-0)
|
||||
* of the @param channel, and then loads them into the working register.
|
||||
* A vector modulator I/Q look-up table has been provided at the beginning of this library.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param channel Channel in which to set the gain (1-4).
|
||||
* @param phase Byte that is used to set the polarity (bit 5) and gain (bits 4-0).
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*
|
||||
* @return Returns ADAR_ERROR_NOERROR if the phase was successfully set.
|
||||
* ADAR_ERROR_FAILED if an invalid channel was selected.
|
||||
*
|
||||
* @note To obtain your phase:
|
||||
* phase = degrees * 128;
|
||||
* phase /= 360;
|
||||
*/
|
||||
uint8_t Adar_SetTxPhase(const AdarDevice * p_adar, uint8_t channel, uint8_t phase, uint8_t broadcast)
|
||||
{
|
||||
uint8_t i_val = 0;
|
||||
uint8_t q_val = 0;
|
||||
uint32_t mem_addr_i, mem_addr_q;
|
||||
|
||||
if((channel == 0) || (channel > 4))
|
||||
{
|
||||
return(ADAR_ERROR_FAILED);
|
||||
}
|
||||
|
||||
//phase = phase % 128;
|
||||
i_val = VM_I[phase];
|
||||
q_val = VM_Q[phase];
|
||||
|
||||
mem_addr_i = REG_CH1_TX_PHS_I + (channel & 0x03) * 2;
|
||||
mem_addr_q = REG_CH1_TX_PHS_Q + (channel & 0x03) * 2;
|
||||
|
||||
Adar_Write(p_adar, mem_addr_i, i_val, broadcast);
|
||||
Adar_Write(p_adar, mem_addr_q, q_val, broadcast);
|
||||
Adar_Write(p_adar, REG_LOAD_WORKING, 0x1, broadcast);
|
||||
|
||||
return(ADAR_ERROR_NOERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reset the whole ADAR device.
|
||||
*
|
||||
* @param p_adar[in] ADAR pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
*/
|
||||
void Adar_SoftReset(const AdarDevice * p_adar)
|
||||
{
|
||||
uint8_t instruction[3];
|
||||
|
||||
instruction[0] = ((p_adar->dev_addr & 0x03) << 5);
|
||||
instruction[1] = 0x00;
|
||||
instruction[2] = 0x81;
|
||||
|
||||
p_adar->Transfer(instruction, NULL, sizeof(instruction));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reset ALL ADAR devices in the SPI chain.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
*/
|
||||
void Adar_SoftResetAll(const AdarDevice * p_adar)
|
||||
{
|
||||
uint8_t instruction[3];
|
||||
|
||||
instruction[0] = 0x08;
|
||||
instruction[1] = 0x00;
|
||||
instruction[2] = 0x81;
|
||||
|
||||
p_adar->Transfer(instruction, NULL, sizeof(instruction));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write a byte of @param data to the register located at @param mem_addr.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param mem_addr Memory address of the register you wish to read from.
|
||||
* @param data Byte of data to be stored in the register.
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
if this set to BROADCAST_ON.
|
||||
*
|
||||
* @warning If writing the same data to multiple registers, use ADAR_WriteBlock.
|
||||
*/
|
||||
void Adar_Write(const AdarDevice * p_adar, uint32_t mem_addr, uint8_t data, uint8_t broadcast)
|
||||
{
|
||||
uint8_t instruction[3];
|
||||
|
||||
if (broadcast)
|
||||
{
|
||||
instruction[0] = 0x08;
|
||||
}
|
||||
else
|
||||
{
|
||||
instruction[0] = ((p_adar->dev_addr & 0x03) << 5);
|
||||
}
|
||||
|
||||
instruction[0] |= (0x1F00 & mem_addr) >> 8;
|
||||
instruction[1] = (0xFF & mem_addr);
|
||||
instruction[2] = data;
|
||||
|
||||
p_adar->Transfer(instruction, NULL, sizeof(instruction));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Block memory write to an ADAR device.
|
||||
*
|
||||
* @pre ADDR_ASCN BITS IN REGISTER ZERO MUST BE SET!
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param mem_addr Memory address of the register you wish to read from.
|
||||
* @param p_data[in] Pointer to block of data to transfer (must have two unused bytes
|
||||
preceding the data for instruction).
|
||||
* @param size Size of data in bytes, including the two additional leading bytes.
|
||||
*
|
||||
* @warning First two bytes of data will be corrupted if you do not provide two unused leading bytes!
|
||||
*/
|
||||
void Adar_WriteBlock(const AdarDevice * p_adar, uint16_t mem_addr, uint8_t * p_data, uint32_t size)
|
||||
{
|
||||
// Prepare command
|
||||
p_data[0] = ((p_adar->dev_addr & 0x03) << 5);
|
||||
p_data[0] |= ((mem_addr) >> 8) & 0x1F;
|
||||
p_data[1] = (0xFF & mem_addr);
|
||||
|
||||
// Start the transfer
|
||||
p_adar->Transfer(p_data, NULL, size);
|
||||
|
||||
// Return nothing since we assume this is non-blocking and won't wait around
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set contents of the INTERFACE_CONFIG_A register.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param flags #INTERFACE_CONFIG_A_SOFTRESET, #INTERFACE_CONFIG_A_LSB_FIRST,
|
||||
* #INTERFACE_CONFIG_A_ADDR_ASCN, #INTERFACE_CONFIG_A_SDO_ACTIVE
|
||||
* @param broadcast Send the message as a broadcast to all ADARs in the SPI chain
|
||||
* if this set to BROADCAST_ON.
|
||||
*/
|
||||
void Adar_WriteConfigA(const AdarDevice * p_adar, uint8_t flags, uint8_t broadcast)
|
||||
{
|
||||
Adar_Write(p_adar, 0x00, flags, broadcast);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write a byte of @param data to the register located at @param mem_addr and
|
||||
* then read from the device and verify that the register was correctly set.
|
||||
*
|
||||
* @param p_adar[in] Adar pointer Which specifies the device and what function
|
||||
* to use for SPI transfer.
|
||||
* @param mem_addr Memory address of the register you wish to read from.
|
||||
* @param data Byte of data to be stored in the register.
|
||||
*
|
||||
* @return Returns the number of attempts that it took to successfully write to a register,
|
||||
* starting from zero.
|
||||
* @warning This function currently only supports writes to a single regiter in a single ADAR.
|
||||
*/
|
||||
uint8_t Adar_WriteVerify(const AdarDevice * p_adar, uint32_t mem_addr, uint8_t data)
|
||||
{
|
||||
uint8_t rx_data;
|
||||
|
||||
for (uint8_t ii = 0; ii < 3; ii++)
|
||||
{
|
||||
Adar_Write(p_adar, mem_addr, data, 0);
|
||||
|
||||
// Can't read back from an ADAR with HW address 0
|
||||
if (!((p_adar->dev_addr) % 4))
|
||||
{
|
||||
return(ADAR_ERROR_INVALIDADDR);
|
||||
}
|
||||
rx_data = Adar_Read(p_adar, mem_addr);
|
||||
if (rx_data == data)
|
||||
{
|
||||
return(ii);
|
||||
}
|
||||
}
|
||||
|
||||
return(ADAR_ERROR_FAILED);
|
||||
}
|
||||
|
||||
void Adar_SetBit(const AdarDevice * p_adar, uint32_t mem_addr, uint8_t bit, uint8_t broadcast)
|
||||
{
|
||||
uint8_t temp = Adar_Read(p_adar, mem_addr);
|
||||
uint8_t data = temp|(1<<bit);
|
||||
Adar_Write(p_adar,mem_addr, data,broadcast);
|
||||
}
|
||||
|
||||
void Adar_ResetBit(const AdarDevice * p_adar, uint32_t mem_addr, uint8_t bit, uint8_t broadcast)
|
||||
{
|
||||
uint8_t temp = Adar_Read(p_adar, mem_addr);
|
||||
uint8_t data = temp&~(1<<bit);
|
||||
Adar_Write(p_adar,mem_addr, data,broadcast);
|
||||
}
|
||||
|
||||
294
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adar1000.h
Normal file
294
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adar1000.h
Normal file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 Jimmy Pentz
|
||||
*
|
||||
* Reach me at: github.com/jgpentz, jpentz1( at )gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sells
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
/* ADAR1000 4-Channel, X Band and Ku Band Beamformer */
|
||||
#ifndef LIB_ADAR1000_H_
|
||||
#define LIB_ADAR1000_H_
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL (0)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "main.h"
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "stm32f7xx_hal_spi.h"
|
||||
#include "stm32f7xx_hal_gpio.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevent C++ name mangling
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Datatypes
|
||||
// ----------------------------------------------------------------------------
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
extern const uint8_t VM_GAIN[128];
|
||||
extern const uint8_t VM_I[128];
|
||||
extern const uint8_t VM_Q[128];
|
||||
|
||||
/// A function pointer prototype for a SPI transfer, the 3 parameters would be
|
||||
/// p_txData, p_rxData, and size (number of bytes to transfer), respectively.
|
||||
typedef uint32_t (*Adar_SpiTransfer)( uint8_t *, uint8_t *, uint32_t);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t dev_addr; ///< 2-bit device hardware address, 0x00, 0x01, 0x10, 0x11
|
||||
Adar_SpiTransfer Transfer; ///< Function pointer to the function used for SPI transfers
|
||||
uint8_t * p_rx_buffer; ///< Data buffer to store received bytes into
|
||||
}const AdarDevice;
|
||||
|
||||
|
||||
/// Use this to store bias current values into, as seen in the datasheet
|
||||
/// Table 6. SPI Settings for Different Power Modules
|
||||
typedef struct
|
||||
{
|
||||
uint8_t rx_lna; ///< nominal: 8, low power: 5
|
||||
uint8_t rx_vm; ///< nominal: 5, low power: 2
|
||||
uint8_t rx_vga; ///< nominal: 10, low power: 3
|
||||
uint8_t tx_vm; ///< nominal: 5, low power: 2
|
||||
uint8_t tx_vga; ///< nominal: 5, low power: 5
|
||||
uint8_t tx_drv; ///< nominal: 6, low power: 3
|
||||
} AdarBiasCurrents;
|
||||
|
||||
/// Useful for queries regarding the device info
|
||||
typedef struct
|
||||
{
|
||||
uint8_t norm_operating_mode : 2;
|
||||
uint8_t cust_operating_mode : 2;
|
||||
uint8_t dev_status : 4;
|
||||
uint8_t chip_type;
|
||||
uint16_t product_id;
|
||||
uint8_t scratchpad;
|
||||
uint8_t spi_rev;
|
||||
uint16_t vendor_id;
|
||||
uint8_t rev_id;
|
||||
} AdarDeviceInfo;
|
||||
|
||||
/// Return types for functions in this library
|
||||
typedef enum {
|
||||
ADAR_ERROR_NOERROR = 0,
|
||||
ADAR_ERROR_FAILED = 1,
|
||||
ADAR_ERROR_INVALIDADDR = 2,
|
||||
} AdarErrorCodes;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Function Prototypes
|
||||
// ----------------------------------------------------------------------------
|
||||
void Adar_AdcInit(const AdarDevice * p_adar, uint8_t broadcast_bit);
|
||||
|
||||
uint8_t Adar_AdcRead(const AdarDevice * p_adar, uint8_t broadcast_bit);
|
||||
|
||||
uint8_t Adar_GetDeviceInfo(const AdarDevice * p_adar, AdarDeviceInfo * info);
|
||||
|
||||
uint8_t Adar_Read(const AdarDevice * p_adar, uint32_t mem_addr);
|
||||
|
||||
void Adar_ReadBlock(const AdarDevice * p_adar, uint16_t mem_addr, uint8_t * p_data, uint32_t size);
|
||||
|
||||
uint8_t Adar_SetBiasCurrents(const AdarDevice * p_adar, AdarBiasCurrents * p_bias, uint8_t broadcast_bit);
|
||||
|
||||
uint8_t Adar_SetBiasVoltages(const AdarDevice * p_adar, uint8_t bias_on_voltage[5], uint8_t bias_off_voltage[5]);
|
||||
|
||||
uint8_t Adar_SetRamBypass(const AdarDevice * p_adar, uint8_t broadcast_bit);
|
||||
|
||||
uint8_t Adar_SetRxVgaGain(const AdarDevice * p_adar, uint8_t channel, uint8_t vga_gain_db, uint8_t broadcast_bit);
|
||||
|
||||
uint8_t Adar_SetRxPhase(const AdarDevice * p_adar, uint8_t channel, uint8_t phase, uint8_t broadcast_bit);
|
||||
|
||||
uint8_t Adar_SetTxBias(const AdarDevice * p_adar, uint8_t broadcast_bit);
|
||||
|
||||
uint8_t Adar_SetTxVgaGain(const AdarDevice * p_adar, uint8_t channel, uint8_t vga_gain_db, uint8_t broadcast_bit);
|
||||
|
||||
uint8_t Adar_SetTxPhase(const AdarDevice * p_adar, uint8_t channel, uint8_t phase, uint8_t broadcast_bit);
|
||||
|
||||
void Adar_SoftReset(const AdarDevice * p_adar);
|
||||
|
||||
void Adar_SoftResetAll(const AdarDevice * p_adar);
|
||||
|
||||
void Adar_Write(const AdarDevice * p_adar, uint32_t mem_addr, uint8_t data, uint8_t broadcast_bit);
|
||||
|
||||
void Adar_WriteBlock(const AdarDevice * p_adar, uint16_t mem_addr, uint8_t * p_data, uint32_t size);
|
||||
|
||||
void Adar_WriteConfigA(const AdarDevice * p_adar, uint8_t flags, uint8_t broadcast);
|
||||
|
||||
uint8_t Adar_WriteVerify(const AdarDevice * p_adar, uint32_t mem_addr, uint8_t data);
|
||||
|
||||
void Adar_SetBit(const AdarDevice * p_adar, uint32_t mem_addr, uint8_t bit, uint8_t broadcast);
|
||||
|
||||
void Adar_ResetBit(const AdarDevice * p_adar, uint32_t mem_addr, uint8_t bit, uint8_t broadcast);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Preprocessor Definitions and Constants
|
||||
// ----------------------------------------------------------------------------
|
||||
// Using BROADCAST_ON will send a command to all ADARs that share a bus
|
||||
#define BROADCAST_OFF 0
|
||||
#define BROADCAST_ON 1
|
||||
|
||||
// The minimum size of a read from the ADARs consists of 3 bytes
|
||||
#define ADAR1000_RD_SIZE 3
|
||||
|
||||
// Address at which the TX RAM starts
|
||||
#define ADAR_TX_RAM_START_ADDR 0x1800
|
||||
|
||||
// ADC Defines
|
||||
#define ADAR1000_ADC_2MHZ_CLK 0x00
|
||||
#define ADAR1000_ADC_EN 0x60
|
||||
#define ADAR1000_ADC_ST_CONV 0x70
|
||||
|
||||
/* REGISTER DEFINITIONS */
|
||||
#define REG_INTERFACE_CONFIG_A 0x000
|
||||
#define REG_INTERFACE_CONFIG_B 0x001
|
||||
#define REG_DEV_CONFIG 0x002
|
||||
#define REG_SCRATCHPAD 0x00A
|
||||
#define REG_TRANSFER 0x00F
|
||||
#define REG_CH1_RX_GAIN 0x010
|
||||
#define REG_CH2_RX_GAIN 0x011
|
||||
#define REG_CH3_RX_GAIN 0x012
|
||||
#define REG_CH4_RX_GAIN 0x013
|
||||
#define REG_CH1_RX_PHS_I 0x014
|
||||
#define REG_CH1_RX_PHS_Q 0x015
|
||||
#define REG_CH2_RX_PHS_I 0x016
|
||||
#define REG_CH2_RX_PHS_Q 0x017
|
||||
#define REG_CH3_RX_PHS_I 0x018
|
||||
#define REG_CH3_RX_PHS_Q 0x019
|
||||
#define REG_CH4_RX_PHS_I 0x01A
|
||||
#define REG_CH4_RX_PHS_Q 0x01B
|
||||
#define REG_CH1_TX_GAIN 0x01C
|
||||
#define REG_CH2_TX_GAIN 0x01D
|
||||
#define REG_CH3_TX_GAIN 0x01E
|
||||
#define REG_CH4_TX_GAIN 0x01F
|
||||
#define REG_CH1_TX_PHS_I 0x020
|
||||
#define REG_CH1_TX_PHS_Q 0x021
|
||||
#define REG_CH2_TX_PHS_I 0x022
|
||||
#define REG_CH2_TX_PHS_Q 0x023
|
||||
#define REG_CH3_TX_PHS_I 0x024
|
||||
#define REG_CH3_TX_PHS_Q 0x025
|
||||
#define REG_CH4_TX_PHS_I 0x026
|
||||
#define REG_CH4_TX_PHS_Q 0x027
|
||||
#define REG_LOAD_WORKING 0x028
|
||||
#define REG_PA_CH1_BIAS_ON 0x029
|
||||
#define REG_PA_CH2_BIAS_ON 0x02A
|
||||
#define REG_PA_CH3_BIAS_ON 0x02B
|
||||
#define REG_PA_CH4_BIAS_ON 0x02C
|
||||
#define REG_LNA_BIAS_ON 0x02D
|
||||
#define REG_RX_ENABLES 0x02E
|
||||
#define REG_TX_ENABLES 0x02F
|
||||
#define REG_MISC_ENABLES 0x030
|
||||
#define REG_SW_CONTROL 0x031
|
||||
#define REG_ADC_CONTROL 0x032
|
||||
#define REG_ADC_CONTROL_TEMP_EN 0xf0
|
||||
#define REG_ADC_OUT 0x033
|
||||
#define REG_BIAS_CURRENT_RX_LNA 0x034
|
||||
#define REG_BIAS_CURRENT_RX 0x035
|
||||
#define REG_BIAS_CURRENT_TX 0x036
|
||||
#define REG_BIAS_CURRENT_TX_DRV 0x037
|
||||
#define REG_MEM_CTL 0x038
|
||||
#define REG_RX_CHX_MEM 0x039
|
||||
#define REG_TX_CHX_MEM 0x03A
|
||||
#define REG_RX_CH1_MEM 0x03D
|
||||
#define REG_RX_CH2_MEM 0x03E
|
||||
#define REG_RX_CH3_MEM 0x03F
|
||||
#define REG_RX_CH4_MEM 0x040
|
||||
#define REG_TX_CH1_MEM 0x041
|
||||
#define REG_TX_CH2_MEM 0x042
|
||||
#define REG_TX_CH3_MEM 0x043
|
||||
#define REG_TX_CH4_MEM 0x044
|
||||
#define REG_PA_CH1_BIAS_OFF 0x046
|
||||
#define REG_PA_CH2_BIAS_OFF 0x047
|
||||
#define REG_PA_CH3_BIAS_OFF 0x048
|
||||
#define REG_PA_CH4_BIAS_OFF 0x049
|
||||
#define REG_LNA_BIAS_OFF 0x04A
|
||||
#define REG_TX_BEAM_STEP_START 0x04D
|
||||
#define REG_TX_BEAM_STEP_STOP 0x04E
|
||||
#define REG_RX_BEAM_STEP_START 0x04F
|
||||
#define REG_RX_BEAM_STEP_STOP 0x050
|
||||
|
||||
// REGISTER CONSTANTS
|
||||
#define INTERFACE_CONFIG_A_SOFTRESET ((1 << 7) | (1 << 0))
|
||||
#define INTERFACE_CONFIG_A_LSB_FIRST ((1 << 6) | (1 << 1))
|
||||
#define INTERFACE_CONFIG_A_ADDR_ASCN ((1 << 5) | (1 << 2))
|
||||
#define INTERFACE_CONFIG_A_SDO_ACTIVE ((1 << 4) | (1 << 3))
|
||||
|
||||
#define LD_WRK_REGS_LDRX_OVERRIDE (1 << 0)
|
||||
#define LD_WRK_REGS_LDTX_OVERRIDE (1 << 1)
|
||||
|
||||
#define RX_ENABLES_TX_VGA_EN (1 << 0)
|
||||
#define RX_ENABLES_TX_VM_EN (1 << 1)
|
||||
#define RX_ENABLES_TX_DRV_EN (1 << 2)
|
||||
#define RX_ENABLES_CH3_TX_EN (1 << 3)
|
||||
#define RX_ENABLES_CH2_TX_EN (1 << 4)
|
||||
#define RX_ENABLES_CH1_TX_EN (1 << 5)
|
||||
#define RX_ENABLES_CH0_TX_EN (1 << 6)
|
||||
|
||||
#define TX_ENABLES_TX_VGA_EN (1 << 0)
|
||||
#define TX_ENABLES_TX_VM_EN (1 << 1)
|
||||
#define TX_ENABLES_TX_DRV_EN (1 << 2)
|
||||
#define TX_ENABLES_CH3_TX_EN (1 << 3)
|
||||
#define TX_ENABLES_CH2_TX_EN (1 << 4)
|
||||
#define TX_ENABLES_CH1_TX_EN (1 << 5)
|
||||
#define TX_ENABLES_CH0_TX_EN (1 << 6)
|
||||
|
||||
#define MISC_ENABLES_CH4_DET_EN (1 << 0)
|
||||
#define MISC_ENABLES_CH3_DET_EN (1 << 1)
|
||||
#define MISC_ENABLES_CH2_DET_EN (1 << 2)
|
||||
#define MISC_ENABLES_CH1_DET_EN (1 << 3)
|
||||
#define MISC_ENABLES_LNA_BIAS_OUT_EN (1 << 4)
|
||||
#define MISC_ENABLES_BIAS_EN (1 << 5)
|
||||
#define MISC_ENABLES_BIAS_CTRL (1 << 6)
|
||||
#define MISC_ENABLES_SW_DRV_TR_MODE_SEL (1 << 7)
|
||||
|
||||
#define SW_CTRL_POL (1 << 0)
|
||||
#define SW_CTRL_TR_SPI (1 << 1)
|
||||
#define SW_CTRL_TR_SOURCE (1 << 2)
|
||||
#define SW_CTRL_SW_DRV_EN_POL (1 << 3)
|
||||
#define SW_CTRL_SW_DRV_EN_TR (1 << 4)
|
||||
#define SW_CTRL_RX_EN (1 << 5)
|
||||
#define SW_CTRL_TX_EN (1 << 6)
|
||||
#define SW_CTRL_SW_DRV_TR_STATE (1 << 7)
|
||||
|
||||
#define MEM_CTRL_RX_CHX_RAM_BYPASS (1 << 0)
|
||||
#define MEM_CTRL_TX_CHX_RAM_BYPASS (1 << 1)
|
||||
#define MEM_CTRL_RX_BEAM_STEP_EN (1 << 2)
|
||||
#define MEM_CTRL_TX_BEAM_STEP_EN (1 << 3)
|
||||
#define MEM_CTRL_BIAS_RAM_BYPASS (1 << 5)
|
||||
#define MEM_CTRL_BEAM_RAM_BYPASS (1 << 6)
|
||||
#define MEM_CTRL_SCAN_MODE_EN (1 << 7)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // End extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* LIB_ADAR1000_H_ */
|
||||
|
||||
2120
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.c
Normal file
2120
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.c
Normal file
File diff suppressed because it is too large
Load Diff
809
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.h
Normal file
809
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adf4382.h
Normal file
@@ -0,0 +1,809 @@
|
||||
/***************************************************************************//**
|
||||
* @file adf4382.h
|
||||
* @brief Implementation of adf4382 Driver.
|
||||
* @author Ciprian Hegbeli (ciprian.hegbeli@analog.com)
|
||||
* @author Jude Osemene (jude.osemene@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2024(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef _ADF4382_H_
|
||||
#define _ADF4382_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "no_os_units.h"
|
||||
#include "no_os_util.h"
|
||||
#include "no_os_spi.h"
|
||||
|
||||
/* ADF4382 REG0000 Map */
|
||||
#define ADF4382_SOFT_RESET_R_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_LSB_FIRST_R_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_ADDRESS_ASC_R_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_SDO_ACTIVE_R_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_SDO_ACTIVE_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_ADDRESS_ASC_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_LSB_FIRST_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_SOFT_RESET_MSK NO_OS_BIT(0)
|
||||
#define ADF4382_RESET_CMD 0x81
|
||||
|
||||
/* ADF4382 REG0000 NO_OS_BIT Definition */
|
||||
#define ADF4382_SDO_ACTIVE_SPI_3W 0x0
|
||||
#define ADF4382_SDO_ACTIVE_SPI_4W 0x1
|
||||
|
||||
#define ADF4382_ADDR_ASC_AUTO_DECR 0x0
|
||||
#define ADF4382_ADDR_ASC_AUTO_INCR 0x1
|
||||
|
||||
#define ADF4382_LSB_FIRST_MSB 0x0
|
||||
#define ADF4382_LSB_FIRST_LSB 0x1
|
||||
|
||||
#define ADF4382_SOFT_RESET_N_OP 0x0
|
||||
#define ADF4382_SOFT_RESET_EN 0x1
|
||||
|
||||
/* ADF4382 REG0001 Map */
|
||||
#define ADF4382_SINGLE_INSTR_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_MASTER_RB_CTRL_MSK NO_OS_BIT(5)
|
||||
|
||||
/* ADF4382 REG0001 NO_OS_BIT Definition */
|
||||
#define ADF4382_SPI_STREAM_EN 0x0
|
||||
#define ADF4382_SPI_STREAM_DIS 0x1
|
||||
|
||||
#define ADF4382_RB_SLAVE_REG 0x0
|
||||
#define ADF4382_RB_MASTER_REG 0x1
|
||||
|
||||
/* ADF4382 REG0003 NO_OS_BIT Definition */
|
||||
#define ADF4382_CHIP_TYPE 0x06
|
||||
|
||||
/* ADF4382 REG0004 NO_OS_BIT Definition */
|
||||
#define ADF4382_PRODUCT_ID_LSB 0x0005
|
||||
|
||||
/* ADF4382 REG0005 NO_OS_BIT Definition */
|
||||
#define ADF4382_PRODUCT_ID_MSB 0x0005
|
||||
|
||||
/* ADF4382 REG000A Map */
|
||||
#define ADF4382_SCRATCHPAD_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG000C NO_OS_BIT Definition */
|
||||
#define ADF4382_VENDOR_ID_LSB 0x56
|
||||
|
||||
/* ADF4382 REG000D NO_OS_BIT Definition */
|
||||
#define ADF4382_VENDOR_ID_MSB 0x04
|
||||
|
||||
/* ADF4382 REG000F NO_OS_BIT Definition */
|
||||
#define ADF4382_M_S_TRANSF_NO_OS_BIT_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0010 Map*/
|
||||
#define ADF4382_N_INT_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0011 Map*/
|
||||
#define ADF4382_CLKOUT_DIV_MSK NO_OS_GENMASK(7, 5)
|
||||
#define ADF4382_INV_CLK_OUT_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_N_INT_MSB_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG0012 Map */
|
||||
#define ADF4382_FRAC1WORD_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0013 Map */
|
||||
#define ADF4382_FRAC1WORD_MID_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0014 Map */
|
||||
#define ADF4382_FRAC1WORD_MSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0015 Map */
|
||||
#define ADF4382_M_VCO_BAND_LSB_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_M_VCO_CORE_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_BIAS_DEC_MODE_MSK NO_OS_GENMASK(5, 3)
|
||||
#define ADF4382_INT_MODE_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_PFD_POL_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_FRAC1WORD_MSB NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0016 Map */
|
||||
#define ADF4382_M_VCO_BAND_MSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0017 Map */
|
||||
#define ADF4382_FRAC2WORD_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0018 Map */
|
||||
#define ADF4382_FRAC2WORD_MID_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0019 Map */
|
||||
#define ADF4382_FRAC2WORD_MSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG001A Map */
|
||||
#define ADF4382_MOD2WORD_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG001B Map */
|
||||
#define ADF4382_MOD2WORD_MID_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG001C Map */
|
||||
#define ADF4382_MOD2WORD_MSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG001D Map */
|
||||
#define ADF4382_FINE_BLEED_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG001E Map */
|
||||
#define ADF4382_EN_PHASE_RESYNC_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_EN_REF_RST_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_TIMED_SYNC_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_COARSE_BLEED_MSK NO_OS_GENMASK(4, 1)
|
||||
#define ADF4382_FINE_BLEED_MSB_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG001F Map */
|
||||
#define ADF4382_SW_SYNC_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_SPARE_1F_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_BLEED_POL_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_EN_BLEED_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_CP_I_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG0020 Map */
|
||||
#define ADF4382_EN_AUTOCAL_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_EN_RDBLR_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_R_DIV_MSK NO_OS_GENMASK(5, 0)
|
||||
|
||||
/* ADF4382 REG0021 Map */
|
||||
#define ADF4382_PHASE_WORD_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0022 Map */
|
||||
#define ADF4382_PHASE_WORD_MID_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0023 Map */
|
||||
#define ADF4382_PHASE_WORD_MSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0024 Map */
|
||||
#define ADF4382_SPARE_24_MSK NO_OS_GENMASK(7, 5)
|
||||
#define ADF4382_DCLK_DIV_SEL_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_DNCLK_DIV1_MSK NO_OS_GENMASK(3, 2)
|
||||
#define ADF4382_DCLK_DIV1_MSK NO_OS_GENMASK(1, 0)
|
||||
|
||||
/* ADF4382 REG0025 Map */
|
||||
#define ADF4382_RESYNC_WAIT_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0026 Map */
|
||||
#define ADF4382_RESYNC_WAIT_MSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0027 Map */
|
||||
#define ADF4382_CAL_BLEED_FINE_MIN_MSK NO_OS_GENMASK(7, 4)
|
||||
#define ADF4382_BLEED_ADJ_SCALE_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG0028 Map */
|
||||
#define ADF4382_PH_RESYNC_RB_SEL_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_LSB_P1_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_VAR_MOD_EN_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_DITHER1_SCALE_MSK NO_OS_GENMASK(4, 2)
|
||||
#define ADF4382_EN_DITHER2_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_EN_DITHER1_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0029 Map */
|
||||
#define ADF4382_CLK2_OPWR_MSK NO_OS_GENMASK(7, 4)
|
||||
#define ADF4382_CLK1_OPWR_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG002A Map */
|
||||
#define ADF4382_FN_DBL_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_PD_NDIV_TL_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_CLKOUT_BST_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_PD_SYNC_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_PD_CLK_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_PD_RDET_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_PD_ADC_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_PD_CALGEN_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG002B Map */
|
||||
#define ADF4382_PD_ALL_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_PD_RDIV_TL_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_PD_NDIV_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_PD_VCO_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_PD_LD_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_PD_PFDCP_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_PD_CLKOUT1_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_PD_CLKOUT2_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG002C Map */
|
||||
#define ADF4382_LDWIN_PW_MSK NO_OS_GENMASK(7, 5)
|
||||
#define ADF4382_LD_COUNT_OPWR_MSK NO_OS_GENMASK(4, 0)
|
||||
|
||||
/* ADF4382 REG002D Map */
|
||||
#define ADF4382_EN_DNCLK_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_EN_DRCLK_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_EN_LOL_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_EN_LDWIN_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_PDET_POL_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_RST_LD_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_LD_O_CTRL_MSK NO_OS_GENMASK(1, 0)
|
||||
|
||||
/* ADF4382 REG002E Map */
|
||||
#define ADF4382_MUXOUT_MSK NO_OS_GENMASK(7, 4)
|
||||
#define ADF4382_ABPW_WD_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_EN_CPTEST_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_CP_DOWN_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_CP_UP_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG002F Map*/
|
||||
#define ADF4382_BST_REF_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_FILT_REF_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_RDBLR_DC_MSK NO_OS_GENMASK(5, 0)
|
||||
|
||||
/* ADF4382 REG0030 Map */
|
||||
#define ADF4382_MUTE_NCLK_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_MUTE_RCLK_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_REF_SEL_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_INV_RDBLR_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_RDBLR_DEL_SEL_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG0031 Map */
|
||||
#define ADF4382_SYNC_DEL_MSK NO_OS_GENMASK(7, 5)
|
||||
#define ADF4382_RST_SYS_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_EN_ADC_CLK_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_EN_VCAL_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_CAL_CT_SEL_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_DCLK_MODE_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0032 Map */
|
||||
#define ADF4382_SPARE_32_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_BLEED_ADJ_CAL_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_DEL_MODE_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_EN_AUTO_ALIGN_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_PHASE_ADJ_POL_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_EFM3_MODE_MSK NO_OS_GENMASK(2, 0)
|
||||
|
||||
/* ADF4382 REG0033 Map */
|
||||
#define ADF4382_PHASE_ADJUST_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0034 Map */
|
||||
#define ADF4382_PHASE_ADJ_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_DRCLK_DEL_MSK NO_OS_GENMASK(6, 4)
|
||||
#define ADF4382_DNCLK_DEL_MSK NO_OS_GENMASK(3, 1)
|
||||
#define ADF4382_RST_CNTR_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0035 Map */
|
||||
#define ADF4382_SPARE_35_MSK NO_OS_GENMASK(7, 6)
|
||||
#define ADF4382_M_VCO_BIAS_MSK NO_OS_GENMASK(5, 0)
|
||||
|
||||
/* ADF4382 REG0036 Map */
|
||||
#define ADF4382_CLKODIV_DB_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_DCLK_DIV_DB_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_SPARE_36_MSK NO_OS_GENMASK(5, 2)
|
||||
#define ADF4382_EN_LUT_GEN_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_EN_LUT_CAL_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0037 Map */
|
||||
#define ADF4382_CAL_COUNT_TO_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0038 Map */
|
||||
#define ADF4382_CAL_VTUNE_TO_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0039 Map */
|
||||
#define ADF4382_O_VCO_DB_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_CAL_VTUNE_TO_MSB_MSK NO_OS_GENMASK(6, 0)
|
||||
|
||||
/* ADF4382 REG003A Map */
|
||||
#define ADF4382_CAL_VCO_TO_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG003B Map */
|
||||
#define ADF4382_DEL_CTRL_DB_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_CAL_VCO_TO_MSB_MSK NO_OS_GENMASK(6, 0)
|
||||
|
||||
/* ADF4382 REG003C Map */
|
||||
#define ADF4382_CNTR_DIV_WORD_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG003D Map */
|
||||
#define ADF4382_SPARE_3D_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_SYNC_SP_DB_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_CMOS_OV_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_READ_MODE_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_CNTR_DIV_WORD_MSB_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG003E Map */
|
||||
#define ADF4382_ADC_CLK_DIV_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG003F Map */
|
||||
#define ADF4382_EN_ADC_CNV_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_EN_ADC_VTEST_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_ADC_VTEST_SEL_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_ADC_MUX_SEL_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_ADC_F_CONV_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_ADC_C_CONV_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_EN_ADC_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_SPARE_3F_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0040 Map */
|
||||
#define ADF4382_EXT_DIV_DEC_SEL_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_ADC_CLK_TEST_SEL_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_MUTE_CLKOUT2_MSK NO_OS_GENMASK(5, 3)
|
||||
#define ADF4382_MUTE_CLKOUT1_MSK NO_OS_GENMASK(2, 0)
|
||||
|
||||
/* ADF4382 REG0041 Map */
|
||||
#define ADF4382_EXT_DIV_MSK NO_OS_GENMASK(7, 5)
|
||||
#define ADF4382_EN_VCO_CAP_TEST_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_EN_CALGEN_CAP_TEST_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_EN_CP_CAP_TEST_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_CAP_TEST_STATE_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_TRANS_LOOP_SEL_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0042 Map */
|
||||
#define ADF4382_NDIV_PWRUP_TIMEOUT_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0043 Map */
|
||||
#define ADF4382_CAL_BLEED_FINE_MAX_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0044 Map */
|
||||
#define ADF4382_VCAL_ZERO_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_VPTAT_CALGEN_MSK NO_OS_GENMASK(6, 0)
|
||||
|
||||
/* ADF4382 REG0045 Map */
|
||||
#define ADF4382_SPARE_45_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_VCTAT_CALGEN_MSK NO_OS_GENMASK(6, 0)
|
||||
|
||||
/* ADF4382 REG0046 Map */
|
||||
#define ADF4382_NVMDIN_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0047 Map */
|
||||
#define ADF4382_SPARE_47_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_NVMADDR_MSK NO_OS_GENMASK(6, 3)
|
||||
#define ADF4382_NVMNO_OS_BIT_SEL NO_OS_GENMASK(2, 0)
|
||||
|
||||
/* ADF4382 REG0048 Map */
|
||||
#define ADF4382_TRIM_LATCH_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_NVMTEST_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_NVMPROG_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_NVMRD_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_NVMSTART_MSK NO_OS_BIT(3)
|
||||
#define ADF4382_NVMON_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_MARGIN_MSK NO_OS_GENMASK(1, 0)
|
||||
|
||||
/* ADF4382 REG0049 Map */
|
||||
#define ADF4382_NVMDOUT_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG004A Map */
|
||||
#define ADF4382_SCAN_MODE_CODE_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG004B Map */
|
||||
#define ADF4382_TEMP_OFFSET_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG004C Map */
|
||||
#define ADF4382_SPARE_4C_MSK NO_OS_GENMASK(7, 6)
|
||||
#define ADF4382_TEMP_SLOPE_MSK NO_OS_GENMASK(5, 0)
|
||||
|
||||
/* ADF4382 REG004D Map */
|
||||
#define ADF4382_VCO_FSM_TEST_MUX_MSK NO_OS_GENMASK(7, 5)
|
||||
#define ADF4382_SPARE_4D_MSK NO_OS_GENMASK(4, 3)
|
||||
#define ADF4382_O_VCO_BIAS_MSK NO_OS_BIT(2)
|
||||
#define ADF4382_O_VCO_BAND_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_O_VCO_CORE_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG004E Map */
|
||||
#define ADF4382_SPARE_4E_MSK NO_OS_GENMASK(7, 5)
|
||||
#define ADF4382_EN_TWO_PASS_CAL_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_TWO_PASS_BAND_START_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG004F Map */
|
||||
#define ADF4382_LUT_SCALE_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0050 Map */
|
||||
#define ADF4382_SPARE0_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0051 Map */
|
||||
#define ADF4382_SPARE1_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0052 Map */
|
||||
#define ADF4382_SYNC_REF_SPARE_MSK NO_OS_GENMASK(7, 4)
|
||||
#define ADF4382_SYNC_MON_DEL_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG0053 Map */
|
||||
#define ADF4382_SPARE_53_MSK NO_OS_BIT(7)
|
||||
#define ADF4382_PD_SYNC_MON_MSK NO_OS_BIT(6)
|
||||
#define ADF4382_SYNC_SEL_MSK NO_OS_BIT(5)
|
||||
#define ADF4382_RST_SYNC_MON_MSK NO_OS_BIT(4)
|
||||
#define ADF4382_SYNC_SH_DEL_MSK NO_OS_GENMASK(3, 0)
|
||||
|
||||
/* ADF4382 REG0054 Map */
|
||||
#define ADF4382_ADC_ST_CNV_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0058 Map */
|
||||
#define ADF4382_FSM_BUSY_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_LOCKED_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG005E Map */
|
||||
#define ADF4382_VCO_BAND_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG005F Map */
|
||||
#define ADF4382_VCO_CORE_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_VCO_BAND_MSB_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0200 Map */
|
||||
#define ADF4382_LUT_WR_ADDR_MSK NO_OS_GENMASK(5, 1)
|
||||
#define ADF4382_O_VCO_LUT_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0201 Map */
|
||||
#define ADF4382_M_LUT_BAND_LSB_MSK NO_OS_GENMASK(7, 0)
|
||||
|
||||
/* ADF4382 REG0202 Map */
|
||||
#define ADF4382_M_LUT_N_LSB_MSK NO_OS_GENMASK(7, 2)
|
||||
#define ADF4382_M_LUT_CORE_MSK NO_OS_BIT(1)
|
||||
#define ADF4382_M_LUT_BAND_MSB_MSK NO_OS_BIT(0)
|
||||
|
||||
/* ADF4382 REG0203 Map */
|
||||
#define ADF4382_M_LUT_N_MSB_MSK NO_OS_GENMASK(5, 0)
|
||||
|
||||
#define ADF4382_SPI_3W_CFG(x) (no_os_field_prep(ADF4382_SDO_ACTIVE_MSK, x) | \
|
||||
no_os_field_prep(ADF4382_SDO_ACTIVE_R_MSK, x))
|
||||
|
||||
#define ADF4382_BLEED_MSB_MSK (ADF4382_COARSE_BLEED_MSK | \
|
||||
ADF4382_FINE_BLEED_MSB_MSK)
|
||||
|
||||
#define ADF4382_SPI_SCRATCHPAD_TEST 0x5A
|
||||
|
||||
/* Specifications */
|
||||
#define ADF4382_SPI_WRITE_CMD 0x0
|
||||
#define ADF4382_SPI_READ_CMD 0x8000
|
||||
#define ADF4382_SPI_DUMMY_DATA 0x00
|
||||
#define ADF4382_BUFF_SIZE_BYTES 3
|
||||
#define ADF4382_VCO_FREQ_MIN 11000000000U // 11GHz
|
||||
#define ADF4382_VCO_FREQ_MAX 22000000000U // 22GHz
|
||||
#define ADF4383_VCO_FREQ_MIN 10000000000U // 10GHz
|
||||
#define ADF4383_VCO_FREQ_MAX 20000000000U // 20GHz
|
||||
#define ADF4382A_VCO_FREQ_MIN 11500000000U // 11.5GHz
|
||||
#define ADF4382A_VCO_FREQ_MAX 21000000000U // 21GHz
|
||||
#define ADF4382_MOD1WORD 0x2000000U // 2^25
|
||||
#define ADF4382_MOD2WORD_MAX 0xFFFFFFU // 2^24 - 1
|
||||
#define ADF4382_PHASE_RESYNC_MOD2WORD_MAX 0x1FFFFU // 2^17 - 1
|
||||
#define ADF4382_CHANNEL_SPACING_MAX 78125U
|
||||
#define ADF4382_PFD_FREQ_MAX 625000000U // 625MHz
|
||||
#define ADF4382_PFD_FREQ_FRAC_MAX 250000000U // 250MHz
|
||||
#define ADF4382_PFD_FREQ_MIN 5400000U // 5.4MHz
|
||||
#define ADF4382_DCLK_DIV1_0_MAX 160000000U // 160MHz
|
||||
#define ADF4382_DCLK_DIV1_1_MAX 320000000U // 320MHz
|
||||
#define ADF4382_CLKOUT_DIV_REG_VAL_MAX 4
|
||||
#define ADF4382A_CLKOUT_DIV_REG_VAL_MAX 2
|
||||
|
||||
#define ADF4383_RFOUT_MAX 20000000000U
|
||||
#define ADF4383_RFOUT_MIN 625000000U
|
||||
#define ADF4382_RFOUT_MAX 22000000000U
|
||||
#define ADF4382_RFOUT_MIN 687500000U
|
||||
#define ADF4382A_RFOUT_MAX 21000000000U
|
||||
#define ADF4382A_RFOUT_MIN 2875000000U
|
||||
#define ADF4382_REF_CLK_MAX 5000000000U
|
||||
#define ADF4382_REF_CLK_MIN 10000000
|
||||
#define ADF4382_REF_DIV_MAX 63
|
||||
#define ADF4382_OUT_PWR_MAX 15
|
||||
#define ADF4382_CPI_VAL_MAX 15
|
||||
#define ADF4382_BLEED_WORD_MAX 8191
|
||||
|
||||
#define ADF4382_VPTAT_CALGEN 46
|
||||
#define ADF4382_VCTAT_CALGEN 82
|
||||
#define ADF4382_FASTCAL_VPTAT_CALGEN 7
|
||||
#define ADF4382_FASTCAL_VCTAT_CALGEN 21
|
||||
#define ADF4382_PHASE_BLEED_CNST 2044000
|
||||
#define ADF4382_VCO_CAL_CNT 183
|
||||
#define ADF4382_VCO_CAL_VTUNE 640
|
||||
#define ADF4382_VCO_CAL_ALC 123
|
||||
#define ADF4382_POR_DELAY_US 200
|
||||
#define ADF4382_LKD_DELAY_US 1000
|
||||
#define ADF4382_COARSE_BLEED_CONST 180U // 180 microseconds
|
||||
#define ADF4382_FINE_BLEED_CONST_1 512U // 512 microseconds
|
||||
#define ADF4382_FINE_BLEED_CONST_2 250U // 250 microseconds
|
||||
#define ADF4382_CAL_VTUNE_TO 124U
|
||||
#define ADF4382_FSM_BUSY_LOOP_CNT 100U
|
||||
|
||||
#define MHZ MEGA
|
||||
#define S_TO_NS NANO
|
||||
#define PS_TO_S PICO
|
||||
#define NS_TO_PS KHZ_PER_MHZ
|
||||
|
||||
/**
|
||||
* @brief Supported device ids.
|
||||
*/
|
||||
enum adf4382_dev_id {
|
||||
ID_ADF4382,
|
||||
ID_ADF4382A,
|
||||
ID_ADF4383,
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct adf4382_init_param
|
||||
* @brief ADF4382 Initialization Parameters structure.
|
||||
*/
|
||||
struct adf4382_init_param {
|
||||
/** SPI Initialization parameters */
|
||||
struct no_os_spi_init_param *spi_init;
|
||||
bool spi_3wire_en;
|
||||
bool cmos_3v3;
|
||||
uint64_t ref_freq_hz;
|
||||
uint64_t freq;
|
||||
bool ref_doubler_en;
|
||||
uint8_t ref_div;
|
||||
uint8_t cp_i;
|
||||
uint16_t bleed_word;
|
||||
uint8_t ld_count;
|
||||
uint8_t en_lut_gen;
|
||||
uint8_t en_lut_cal;
|
||||
uint8_t max_lpf_cap_value_uf;
|
||||
enum adf4382_dev_id id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct adf4382_dev
|
||||
* @brief ADF4382 Device Descriptor.
|
||||
*/
|
||||
struct adf4382_dev {
|
||||
/** SPI Descriptor */
|
||||
struct no_os_spi_desc *spi_desc;
|
||||
bool spi_3wire_en;
|
||||
bool cmos_3v3;
|
||||
uint64_t ref_freq_hz;
|
||||
uint64_t freq;
|
||||
bool ref_doubler_en;
|
||||
uint8_t ref_div;
|
||||
uint8_t cp_i;
|
||||
uint16_t bleed_word;
|
||||
uint8_t ld_count;
|
||||
uint32_t phase_adj;
|
||||
uint8_t en_lut_gen;
|
||||
uint8_t en_lut_cal;
|
||||
uint64_t vco_max;
|
||||
uint64_t vco_min;
|
||||
uint64_t freq_max;
|
||||
uint64_t freq_min;
|
||||
uint8_t clkout_div_reg_val_max;
|
||||
uint8_t max_lpf_cap_value_uf;
|
||||
uint32_t cal_vtune_to;
|
||||
// N_INT variable to trigger auto calibration
|
||||
uint16_t n_int;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct reg_sequence
|
||||
* @brief ADF4382 register format structure for default values
|
||||
*/
|
||||
struct reg_sequence {
|
||||
uint16_t reg;
|
||||
uint8_t val;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct adf4382_reg_defaults
|
||||
* @brief ADF4382 register initialization
|
||||
*/
|
||||
static const struct reg_sequence adf4382_reg_defaults[] = {
|
||||
{ 0x000, 0x18 },
|
||||
{ 0x00a, 0xA5 },
|
||||
{ 0x200, 0x00 },
|
||||
{ 0x201, 0x00 },
|
||||
{ 0x202, 0x00 },
|
||||
{ 0x203, 0x00 },
|
||||
{ 0x203, 0x00 },
|
||||
{ 0x203, 0x00 },
|
||||
{ 0x100, 0x25 },
|
||||
{ 0x101, 0x3F },
|
||||
{ 0x102, 0x3F },
|
||||
{ 0x103, 0x3F },
|
||||
{ 0x104, 0x3F },
|
||||
{ 0x105, 0x3F },
|
||||
{ 0x106, 0x3F },
|
||||
{ 0x107, 0x3F },
|
||||
{ 0x108, 0x3F },
|
||||
{ 0x109, 0x25 },
|
||||
{ 0x10A, 0x25 },
|
||||
{ 0x10B, 0x3F },
|
||||
{ 0x10C, 0x3F },
|
||||
{ 0x10D, 0x3F },
|
||||
{ 0x10E, 0x3F },
|
||||
{ 0x10F, 0x3F },
|
||||
{ 0x110, 0x3F },
|
||||
{ 0x111, 0x3F },
|
||||
{ 0x054, 0x00 },
|
||||
{ 0x053, 0x45 },
|
||||
{ 0x052, 0x00 },
|
||||
{ 0x051, 0x00 },
|
||||
{ 0x050, 0x00 },
|
||||
{ 0x04f, 0x08 },
|
||||
{ 0x04e, 0x06 },
|
||||
{ 0x04d, 0x00 },
|
||||
{ 0x04c, 0x2B },
|
||||
{ 0x04b, 0x5D },
|
||||
{ 0x04a, 0x00 },
|
||||
{ 0x048, 0x00 },
|
||||
{ 0x047, 0x00 },
|
||||
{ 0x046, 0x00 },
|
||||
{ 0x045, 0x52 },
|
||||
{ 0x044, 0x2E },
|
||||
{ 0x043, 0xB8 },
|
||||
{ 0x042, 0x01 },
|
||||
{ 0x041, 0x00 },
|
||||
{ 0x040, 0x00 },
|
||||
{ 0x03f, 0x82 },
|
||||
{ 0x03e, 0x4E },
|
||||
{ 0x03d, 0x00 },
|
||||
{ 0x03c, 0x00 },
|
||||
{ 0x03b, 0x00 },
|
||||
{ 0x03a, 0xFA },
|
||||
{ 0x039, 0x00 },
|
||||
{ 0x038, 0x7C },
|
||||
{ 0x037, 0xCA },
|
||||
{ 0x036, 0xC0 },
|
||||
{ 0x035, 0x00 },
|
||||
{ 0x034, 0x36 },
|
||||
{ 0x033, 0x00 },
|
||||
{ 0x032, 0x40 },
|
||||
{ 0x031, 0x63 },
|
||||
{ 0x030, 0x0F },
|
||||
{ 0x02f, 0x3F },
|
||||
{ 0x02e, 0x00 },
|
||||
{ 0x02d, 0xF1 },
|
||||
{ 0x02c, 0x0E },
|
||||
{ 0x02b, 0x01 },
|
||||
{ 0x02a, 0x30 },
|
||||
{ 0x029, 0x09 },
|
||||
{ 0x028, 0x00 },
|
||||
{ 0x027, 0xF0 },
|
||||
{ 0x026, 0x00 },
|
||||
{ 0x025, 0x01 },
|
||||
{ 0x024, 0x01 },
|
||||
{ 0x023, 0x00 },
|
||||
{ 0x022, 0x00 },
|
||||
{ 0x021, 0x00 },
|
||||
{ 0x020, 0xC1 },
|
||||
{ 0x01f, 0x0F },
|
||||
{ 0x01e, 0x20 },
|
||||
{ 0x01d, 0x00 },
|
||||
{ 0x01c, 0x00 },
|
||||
{ 0x01b, 0x00 },
|
||||
{ 0x01a, 0x00 },
|
||||
{ 0x019, 0x00 },
|
||||
{ 0x018, 0x00 },
|
||||
{ 0x017, 0x00 },
|
||||
{ 0x016, 0x00 },
|
||||
{ 0x015, 0x06 },
|
||||
{ 0x014, 0x00 },
|
||||
{ 0x013, 0x00 },
|
||||
{ 0x012, 0x00 },
|
||||
{ 0x011, 0x00 },
|
||||
{ 0x010, 0x50 },
|
||||
};
|
||||
|
||||
/** ADF4382 SPI write */
|
||||
int adf4382_spi_write(struct adf4382_dev *dev, uint16_t reg_addr, uint8_t data);
|
||||
|
||||
/** ADF4382 SPI Read */
|
||||
int adf4382_spi_read(struct adf4382_dev *dev, uint16_t reg_addr, uint8_t *data);
|
||||
|
||||
/** ADF4382 updates a bit in the register space over SPI */
|
||||
int adf4382_spi_update_bits(struct adf4382_dev *dev, uint16_t reg_addr,
|
||||
uint8_t mask, uint8_t data);
|
||||
|
||||
/** ADF4382 Register dump */
|
||||
int adf4382_reg_dump(struct adf4382_dev *dev);
|
||||
|
||||
/** ADF4382 Set reference frequency attribute */
|
||||
int adf4382_set_ref_clk(struct adf4382_dev *dev, uint64_t val);
|
||||
|
||||
/** ADF4382 Get reference frequency attribute */
|
||||
int adf4382_get_ref_clk(struct adf4382_dev *dev, uint64_t *val);
|
||||
|
||||
/** ADF4382 Set reference doubler attribute */
|
||||
int adf4382_set_en_ref_doubler(struct adf4382_dev *dev, bool en);
|
||||
|
||||
/** ADF4382 Get reference doubler attribute */
|
||||
int adf4382_get_en_ref_doubler(struct adf4382_dev *dev, bool *en);
|
||||
|
||||
/** ADF4382 Set reference divider attribute */
|
||||
int adf4382_set_ref_div(struct adf4382_dev *dev, int32_t div);
|
||||
|
||||
/** ADF4382 Get reference divider attribute */
|
||||
int adf4382_get_ref_div(struct adf4382_dev *dev, int32_t *div);
|
||||
|
||||
/** ADF4382 Set charge pump current attribute */
|
||||
int adf4382_set_cp_i(struct adf4382_dev *dev, int32_t reg_val);
|
||||
|
||||
/** ADF4382 Get charge pump current attribute */
|
||||
int adf4382_get_cp_i(struct adf4382_dev *dev, int32_t *reg_val);
|
||||
|
||||
/** ADF4382 Set bleed current attribute */
|
||||
int adf4382_set_bleed_word(struct adf4382_dev *dev, int32_t word);
|
||||
|
||||
/** ADF4382 Get bleed current attribute */
|
||||
int adf4382_get_bleed_word(struct adf4382_dev *dev, int32_t *word);
|
||||
|
||||
/** ADF4382 Set output frequency attribute */
|
||||
int adf4382_set_rfout(struct adf4382_dev *dev, uint64_t val);
|
||||
|
||||
/** ADF4382 Get output frequency attribute */
|
||||
int adf4382_get_rfout(struct adf4382_dev *dev, uint64_t *val);
|
||||
|
||||
/** ADF4382 Set output power attributes */
|
||||
int adf4382_set_out_power(struct adf4382_dev *dev, uint8_t ch, int32_t pwr);
|
||||
|
||||
/** ADF4382 Get output power attributes */
|
||||
int adf4382_get_out_power(struct adf4382_dev *dev, uint8_t ch, int32_t *pwr);
|
||||
|
||||
/** ADF4382 Set channel enable attributes */
|
||||
int adf4382_set_en_chan(struct adf4382_dev *dev, uint8_t ch, bool en);
|
||||
|
||||
/** ADF4382 Get channel enable attributes */
|
||||
int adf4382_get_en_chan(struct adf4382_dev *dev, uint8_t ch, bool *en);
|
||||
|
||||
/** ADF4382 Sets frequency */
|
||||
int adf4382_set_freq(struct adf4382_dev *dev);
|
||||
|
||||
/** ADF4382 Set fast calibration attributes */
|
||||
int adf4382_set_en_fast_calibration(struct adf4382_dev *dev, bool en_fast_cal);
|
||||
|
||||
/** ADF4382 Set fast calibration LUT calibration attributes */
|
||||
int adf4382_set_en_lut_calibration(struct adf4382_dev *dev, bool en_lut_cal);
|
||||
|
||||
/** ADF4382 Get Fast Calibration LUT Calibration attributes */
|
||||
int adf4382_get_en_lut_calibration(struct adf4382_dev *dev, bool *en);
|
||||
|
||||
/** ADF4382 Set Output Frequency without writing the Ndiv Register */
|
||||
int adf4382_set_change_freq(struct adf4382_dev *dev);
|
||||
|
||||
/** ADF4382 Get Change Output Frequency attribute value */
|
||||
int adf4382_get_change_rfout(struct adf4382_dev *dev, uint64_t *val);
|
||||
|
||||
/** ADF4382 Set Change Output Frequency attribute value */
|
||||
int adf4382_set_change_rfout(struct adf4382_dev *dev, uint64_t val);
|
||||
|
||||
/** ADF4382 Set the NDIV register attribute value */
|
||||
int adf4382_set_start_calibration(struct adf4382_dev *dev);
|
||||
|
||||
/** ADF4382 Get the NDIV register attribute value as 0 */
|
||||
int adf4382_get_start_calibration(struct adf4382_dev *dev, bool *start_cal);
|
||||
|
||||
/** ADF4382 Sets Phase adjustment */
|
||||
int adf4382_set_phase_adjust(struct adf4382_dev *dev, uint32_t phase_ps);
|
||||
|
||||
/** ADF4382 Sets Phase adjustment polarity*/
|
||||
int adf4382_set_phase_pol(struct adf4382_dev *dev, bool polarity);
|
||||
|
||||
/** ADF4382 Gets Phase adjustment polarity*/
|
||||
int adf4382_get_phase_pol(struct adf4382_dev *dev, bool *polarity);
|
||||
|
||||
/** ADF4382 Set EZSYNC feature attributes */
|
||||
int adf4382_set_ezsync_setup(struct adf4382_dev *dev, bool sync);
|
||||
|
||||
/** ADF4382 Set Timed SYNC feature attributes */
|
||||
int adf4382_set_timed_sync_setup(struct adf4382_dev *dev, bool sync);
|
||||
|
||||
/** ADF4382 Get EZSYNC and Timed SYNC feature attributes */
|
||||
int adf4382_get_phase_sync_setup(struct adf4382_dev *dev, bool *en);
|
||||
|
||||
/** ADF4382 Set sw_sync attribute */
|
||||
int adf4382_set_sw_sync(struct adf4382_dev *dev, bool sw_sync);
|
||||
|
||||
/** ADF4382 Get sw_sync attribute */
|
||||
int adf4382_get_sw_sync(struct adf4382_dev *dev, bool *sw_sync);
|
||||
|
||||
/** ADF4382 Set VCO calibration settings attributes */
|
||||
int adf4382_set_vco_cal_timeout(struct adf4382_dev *dev);
|
||||
|
||||
/** ADF4382 Initialization */
|
||||
int adf4382_init(struct adf4382_dev **device,
|
||||
struct adf4382_init_param *init_param);
|
||||
|
||||
/** ADF4382 Remove */
|
||||
int adf4382_remove(struct adf4382_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,510 @@
|
||||
#include "adf4382a_manager.h"
|
||||
#include "no_os_delay.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// External SPI handle
|
||||
extern SPI_HandleTypeDef hspi4;
|
||||
|
||||
// Static function prototypes
|
||||
static void set_chip_enable(uint8_t ce_pin, bool state);
|
||||
static void set_deladj_pin(uint8_t device, bool state);
|
||||
static void set_delstr_pin(uint8_t device, bool state);
|
||||
static uint16_t phase_ps_to_duty_cycle(uint16_t phase_ps);
|
||||
|
||||
int ADF4382A_Manager_Init(ADF4382A_Manager *manager, SyncMethod method)
|
||||
{
|
||||
struct adf4382_init_param tx_param, rx_param;
|
||||
int ret;
|
||||
|
||||
if (!manager) {
|
||||
return ADF4382A_MANAGER_ERROR_INVALID;
|
||||
}
|
||||
|
||||
// Initialize manager structure
|
||||
manager->tx_dev = NULL;
|
||||
manager->rx_dev = NULL;
|
||||
manager->initialized = false;
|
||||
manager->sync_method = method;
|
||||
manager->tx_phase_shift_ps = 0;
|
||||
manager->rx_phase_shift_ps = 0;
|
||||
|
||||
// Initialize SPI parameters in manager
|
||||
memset(&manager->spi_tx_param, 0, sizeof(manager->spi_tx_param));
|
||||
memset(&manager->spi_rx_param, 0, sizeof(manager->spi_rx_param));
|
||||
|
||||
// Setup TX SPI parameters for SPI4
|
||||
manager->spi_tx_param.device_id = ADF4382A_SPI_DEVICE_ID;
|
||||
manager->spi_tx_param.max_speed_hz = ADF4382A_SPI_SPEED_HZ;
|
||||
manager->spi_tx_param.mode = NO_OS_SPI_MODE_0;
|
||||
manager->spi_tx_param.chip_select = TX_CS_Pin;
|
||||
manager->spi_tx_param.bit_order = NO_OS_SPI_BIT_ORDER_MSB_FIRST;
|
||||
manager->spi_tx_param.platform_ops = NULL;
|
||||
manager->spi_tx_param.extra = &hspi4;
|
||||
|
||||
// Setup RX SPI parameters for SPI4
|
||||
manager->spi_rx_param.device_id = ADF4382A_SPI_DEVICE_ID;
|
||||
manager->spi_rx_param.max_speed_hz = ADF4382A_SPI_SPEED_HZ;
|
||||
manager->spi_rx_param.mode = NO_OS_SPI_MODE_0;
|
||||
manager->spi_rx_param.chip_select = RX_CS_Pin;
|
||||
manager->spi_rx_param.bit_order = NO_OS_SPI_BIT_ORDER_MSB_FIRST;
|
||||
manager->spi_rx_param.platform_ops = NULL;
|
||||
manager->spi_rx_param.extra = &hspi4;
|
||||
|
||||
// Configure TX parameters (10.5 GHz)
|
||||
memset(&tx_param, 0, sizeof(tx_param));
|
||||
tx_param.spi_3wire_en = 0;
|
||||
tx_param.cmos_3v3 = 1;
|
||||
tx_param.ref_freq_hz = REF_FREQ_HZ;
|
||||
tx_param.ref_div = 1;
|
||||
tx_param.ref_doubler_en = false;
|
||||
tx_param.freq = TX_FREQ_HZ;
|
||||
tx_param.id = ID_ADF4382A;
|
||||
tx_param.cp_i = 3;
|
||||
tx_param.bleed_word = 1000;
|
||||
tx_param.ld_count = 0x07;
|
||||
tx_param.spi_init = &manager->spi_tx_param;
|
||||
|
||||
// Configure RX parameters (10.38 GHz)
|
||||
memset(&rx_param, 0, sizeof(rx_param));
|
||||
rx_param.spi_3wire_en = 0;
|
||||
rx_param.cmos_3v3 = 1;
|
||||
rx_param.ref_freq_hz = REF_FREQ_HZ;
|
||||
rx_param.ref_div = 1;
|
||||
rx_param.ref_doubler_en = false;
|
||||
rx_param.freq = RX_FREQ_HZ;
|
||||
rx_param.id = ID_ADF4382A;
|
||||
rx_param.cp_i = 4;
|
||||
rx_param.bleed_word = 1200;
|
||||
rx_param.ld_count = 0x07;
|
||||
rx_param.spi_init = &manager->spi_rx_param;
|
||||
|
||||
// Enable chips
|
||||
set_chip_enable(TX_CE_Pin, true);
|
||||
set_chip_enable(RX_CE_Pin, true);
|
||||
no_os_udelay(1000);
|
||||
|
||||
// Initialize DELADJ and DELSTR pins
|
||||
set_deladj_pin(0, false); // TX device
|
||||
set_deladj_pin(1, false); // RX device
|
||||
set_delstr_pin(0, false); // TX device
|
||||
set_delstr_pin(1, false); // RX device
|
||||
|
||||
// Initialize TX device first
|
||||
printf("Initializing TX ADF4382A (10.5 GHz) on SPI4...\n");
|
||||
ret = adf4382_init(&manager->tx_dev, &tx_param);
|
||||
if (ret) {
|
||||
printf("TX ADF4382A initialization failed: %d\n", ret);
|
||||
set_chip_enable(TX_CE_Pin, false);
|
||||
set_chip_enable(RX_CE_Pin, false);
|
||||
return ADF4382A_MANAGER_ERROR_SPI;
|
||||
}
|
||||
|
||||
// Small delay between initializations
|
||||
no_os_udelay(5000);
|
||||
|
||||
// Initialize RX device
|
||||
printf("Initializing RX ADF4382A (10.38 GHz) on SPI4...\n");
|
||||
ret = adf4382_init(&manager->rx_dev, &rx_param);
|
||||
if (ret) {
|
||||
printf("RX ADF4382A initialization failed: %d\n", ret);
|
||||
adf4382_remove(manager->tx_dev);
|
||||
set_chip_enable(TX_CE_Pin, false);
|
||||
set_chip_enable(RX_CE_Pin, false);
|
||||
return ADF4382A_MANAGER_ERROR_SPI;
|
||||
}
|
||||
|
||||
// Set output power
|
||||
adf4382_set_out_power(manager->tx_dev, 0, 12);
|
||||
adf4382_set_out_power(manager->tx_dev, 1, 12);
|
||||
adf4382_set_out_power(manager->rx_dev, 0, 12);
|
||||
adf4382_set_out_power(manager->rx_dev, 1, 12);
|
||||
|
||||
// Enable outputs
|
||||
adf4382_set_en_chan(manager->tx_dev, 0, true);
|
||||
adf4382_set_en_chan(manager->tx_dev, 1, false);
|
||||
adf4382_set_en_chan(manager->rx_dev, 0, true);
|
||||
adf4382_set_en_chan(manager->rx_dev, 1, false);
|
||||
|
||||
// Setup synchronization based on selected method
|
||||
if (method == SYNC_METHOD_TIMED) {
|
||||
ret = ADF4382A_SetupTimedSync(manager);
|
||||
if (ret) {
|
||||
printf("Timed sync setup failed: %d\n", ret);
|
||||
}
|
||||
} else {
|
||||
ret = ADF4382A_SetupEZSync(manager);
|
||||
if (ret) {
|
||||
printf("EZSync setup failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
manager->initialized = true;
|
||||
printf("ADF4382A Manager initialized with %s synchronization on SPI4\n",
|
||||
(method == SYNC_METHOD_TIMED) ? "TIMED" : "EZSYNC");
|
||||
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_SetupTimedSync(ADF4382A_Manager *manager)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!manager || !manager->initialized) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
printf("Setting up Timed Synchronization (60 MHz SYNCP/SYNCN)...\n");
|
||||
|
||||
// Setup TX for timed sync
|
||||
ret = adf4382_set_timed_sync_setup(manager->tx_dev, true);
|
||||
if (ret) {
|
||||
printf("TX timed sync setup failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Setup RX for timed sync
|
||||
ret = adf4382_set_timed_sync_setup(manager->rx_dev, true);
|
||||
if (ret) {
|
||||
printf("RX timed sync setup failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
manager->sync_method = SYNC_METHOD_TIMED;
|
||||
printf("Timed synchronization configured for 60 MHz SYNCP/SYNCN\n");
|
||||
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_SetupEZSync(ADF4382A_Manager *manager)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!manager || !manager->initialized) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
printf("Setting up EZSync (SPI-based synchronization)...\n");
|
||||
|
||||
// Setup TX for EZSync
|
||||
ret = adf4382_set_ezsync_setup(manager->tx_dev, true);
|
||||
if (ret) {
|
||||
printf("TX EZSync setup failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Setup RX for EZSync
|
||||
ret = adf4382_set_ezsync_setup(manager->rx_dev, true);
|
||||
if (ret) {
|
||||
printf("RX EZSync setup failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
manager->sync_method = SYNC_METHOD_EZSYNC;
|
||||
printf("EZSync configured\n");
|
||||
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_TriggerTimedSync(ADF4382A_Manager *manager)
|
||||
{
|
||||
if (!manager || !manager->initialized || manager->sync_method != SYNC_METHOD_TIMED) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
printf("Timed sync ready - SYNC pin will trigger synchronization\n");
|
||||
printf("Ensure 60 MHz phase-aligned clocks are present on SYNCP/SYNCN pins\n");
|
||||
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_TriggerEZSync(ADF4382A_Manager *manager)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!manager || !manager->initialized || manager->sync_method != SYNC_METHOD_EZSYNC) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Trigger software sync on both devices
|
||||
ret = adf4382_set_sw_sync(manager->tx_dev, true);
|
||||
if (ret) {
|
||||
printf("TX software sync failed: %d\n", ret);
|
||||
return ADF4382A_MANAGER_ERROR_SPI;
|
||||
}
|
||||
|
||||
ret = adf4382_set_sw_sync(manager->rx_dev, true);
|
||||
if (ret) {
|
||||
printf("RX software sync failed: %d\n", ret);
|
||||
return ADF4382A_MANAGER_ERROR_SPI;
|
||||
}
|
||||
|
||||
// Small delay for sync to take effect
|
||||
no_os_udelay(10);
|
||||
|
||||
// Clear software sync
|
||||
ret = adf4382_set_sw_sync(manager->tx_dev, false);
|
||||
if (ret) {
|
||||
printf("TX sync clear failed: %d\n", ret);
|
||||
return ADF4382A_MANAGER_ERROR_SPI;
|
||||
}
|
||||
|
||||
ret = adf4382_set_sw_sync(manager->rx_dev, false);
|
||||
if (ret) {
|
||||
printf("RX sync clear failed: %d\n", ret);
|
||||
return ADF4382A_MANAGER_ERROR_SPI;
|
||||
}
|
||||
|
||||
printf("EZSync triggered via SPI\n");
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_Manager_Deinit(ADF4382A_Manager *manager)
|
||||
{
|
||||
if (!manager || !manager->initialized) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Disable outputs first
|
||||
if (manager->tx_dev) {
|
||||
adf4382_set_en_chan(manager->tx_dev, 0, false);
|
||||
adf4382_set_en_chan(manager->tx_dev, 1, false);
|
||||
}
|
||||
|
||||
if (manager->rx_dev) {
|
||||
adf4382_set_en_chan(manager->rx_dev, 0, false);
|
||||
adf4382_set_en_chan(manager->rx_dev, 1, false);
|
||||
}
|
||||
|
||||
// Remove devices
|
||||
if (manager->tx_dev) {
|
||||
adf4382_remove(manager->tx_dev);
|
||||
manager->tx_dev = NULL;
|
||||
}
|
||||
|
||||
if (manager->rx_dev) {
|
||||
adf4382_remove(manager->rx_dev);
|
||||
manager->rx_dev = NULL;
|
||||
}
|
||||
|
||||
// Disable chips and phase control pins
|
||||
set_chip_enable(TX_CE_Pin, false);
|
||||
set_chip_enable(RX_CE_Pin, false);
|
||||
set_deladj_pin(0, false);
|
||||
set_deladj_pin(1, false);
|
||||
set_delstr_pin(0, false);
|
||||
set_delstr_pin(1, false);
|
||||
|
||||
manager->initialized = false;
|
||||
|
||||
printf("ADF4382A Manager deinitialized\n");
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_CheckLockStatus(ADF4382A_Manager *manager, bool *tx_locked, bool *rx_locked)
|
||||
{
|
||||
uint8_t tx_status, rx_status;
|
||||
int ret;
|
||||
|
||||
if (!manager || !manager->initialized || !tx_locked || !rx_locked) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Read lock status from registers
|
||||
ret = adf4382_spi_read(manager->tx_dev, 0x58, &tx_status);
|
||||
if (ret) {
|
||||
printf("TX lock status read failed: %d\n", ret);
|
||||
return ADF4382A_MANAGER_ERROR_SPI;
|
||||
}
|
||||
|
||||
ret = adf4382_spi_read(manager->rx_dev, 0x58, &rx_status);
|
||||
if (ret) {
|
||||
printf("RX lock status read failed: %d\n", ret);
|
||||
return ADF4382A_MANAGER_ERROR_SPI;
|
||||
}
|
||||
|
||||
*tx_locked = (tx_status & ADF4382_LOCKED_MSK) != 0;
|
||||
*rx_locked = (rx_status & ADF4382_LOCKED_MSK) != 0;
|
||||
|
||||
// Also check GPIO lock detect pins as backup
|
||||
bool tx_gpio_locked = HAL_GPIO_ReadPin(TX_LKDET_GPIO_Port, TX_LKDET_Pin) == GPIO_PIN_SET;
|
||||
bool rx_gpio_locked = HAL_GPIO_ReadPin(RX_LKDET_GPIO_Port, RX_LKDET_Pin) == GPIO_PIN_SET;
|
||||
|
||||
// Use both register and GPIO status
|
||||
*tx_locked = *tx_locked && tx_gpio_locked;
|
||||
*rx_locked = *rx_locked && rx_gpio_locked;
|
||||
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_SetOutputPower(ADF4382A_Manager *manager, uint8_t tx_power, uint8_t rx_power)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!manager || !manager->initialized) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Clamp power values (0-15)
|
||||
tx_power = (tx_power > 15) ? 15 : tx_power;
|
||||
rx_power = (rx_power > 15) ? 15 : rx_power;
|
||||
|
||||
// Set TX power for both channels
|
||||
ret = adf4382_set_out_power(manager->tx_dev, 0, tx_power);
|
||||
if (ret) return ret;
|
||||
ret = adf4382_set_out_power(manager->tx_dev, 1, tx_power);
|
||||
if (ret) return ret;
|
||||
|
||||
// Set RX power for both channels
|
||||
ret = adf4382_set_out_power(manager->rx_dev, 0, rx_power);
|
||||
if (ret) return ret;
|
||||
ret = adf4382_set_out_power(manager->rx_dev, 1, rx_power);
|
||||
|
||||
printf("Output power set: TX=%d, RX=%d\n", tx_power, rx_power);
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_EnableOutputs(ADF4382A_Manager *manager, bool tx_enable, bool rx_enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!manager || !manager->initialized) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Enable/disable TX outputs
|
||||
ret = adf4382_set_en_chan(manager->tx_dev, 0, tx_enable);
|
||||
if (ret) return ret;
|
||||
ret = adf4382_set_en_chan(manager->tx_dev, 1, tx_enable);
|
||||
if (ret) return ret;
|
||||
|
||||
// Enable/disable RX outputs
|
||||
ret = adf4382_set_en_chan(manager->rx_dev, 0, rx_enable);
|
||||
if (ret) return ret;
|
||||
ret = adf4382_set_en_chan(manager->rx_dev, 1, rx_enable);
|
||||
|
||||
printf("Outputs: TX=%s, RX=%s\n",
|
||||
tx_enable ? "ENABLED" : "DISABLED",
|
||||
rx_enable ? "ENABLED" : "DISABLED");
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
// New phase delay functions
|
||||
|
||||
int ADF4382A_SetPhaseShift(ADF4382A_Manager *manager, uint16_t tx_phase_ps, uint16_t rx_phase_ps)
|
||||
{
|
||||
if (!manager || !manager->initialized) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Clamp phase shift values
|
||||
tx_phase_ps = (tx_phase_ps > PHASE_SHIFT_MAX_PS) ? PHASE_SHIFT_MAX_PS : tx_phase_ps;
|
||||
rx_phase_ps = (rx_phase_ps > PHASE_SHIFT_MAX_PS) ? PHASE_SHIFT_MAX_PS : rx_phase_ps;
|
||||
|
||||
// Convert phase shift to duty cycle and apply
|
||||
if (tx_phase_ps != manager->tx_phase_shift_ps) {
|
||||
uint16_t duty_cycle = phase_ps_to_duty_cycle(tx_phase_ps);
|
||||
ADF4382A_SetFinePhaseShift(manager, 0, duty_cycle); // 0 = TX device
|
||||
manager->tx_phase_shift_ps = tx_phase_ps;
|
||||
}
|
||||
|
||||
if (rx_phase_ps != manager->rx_phase_shift_ps) {
|
||||
uint16_t duty_cycle = phase_ps_to_duty_cycle(rx_phase_ps);
|
||||
ADF4382A_SetFinePhaseShift(manager, 1, duty_cycle); // 1 = RX device
|
||||
manager->rx_phase_shift_ps = rx_phase_ps;
|
||||
}
|
||||
|
||||
printf("Phase shift set: TX=%d ps, RX=%d ps\n", tx_phase_ps, rx_phase_ps);
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_GetPhaseShift(ADF4382A_Manager *manager, uint16_t *tx_phase_ps, uint16_t *rx_phase_ps)
|
||||
{
|
||||
if (!manager || !manager->initialized || !tx_phase_ps || !rx_phase_ps) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
*tx_phase_ps = manager->tx_phase_shift_ps;
|
||||
*rx_phase_ps = manager->rx_phase_shift_ps;
|
||||
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_SetFinePhaseShift(ADF4382A_Manager *manager, uint8_t device, uint16_t duty_cycle)
|
||||
{
|
||||
if (!manager || !manager->initialized) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Clamp duty cycle
|
||||
duty_cycle = (duty_cycle > DELADJ_MAX_DUTY_CYCLE) ? DELADJ_MAX_DUTY_CYCLE : duty_cycle;
|
||||
|
||||
// For simplicity, we'll use a basic implementation
|
||||
// In a real system, you would generate a PWM signal on DELADJ pin
|
||||
// Here we just set the pin state based on a simplified approach
|
||||
|
||||
if (duty_cycle == 0) {
|
||||
set_deladj_pin(device, false);
|
||||
} else if (duty_cycle >= DELADJ_MAX_DUTY_CYCLE) {
|
||||
set_deladj_pin(device, true);
|
||||
} else {
|
||||
// For intermediate values, you would need PWM generation
|
||||
// This is a simplified implementation
|
||||
set_deladj_pin(device, true);
|
||||
}
|
||||
|
||||
printf("Device %d DELADJ duty cycle set to %d/%d\n",
|
||||
device, duty_cycle, DELADJ_MAX_DUTY_CYCLE);
|
||||
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
int ADF4382A_StrobePhaseShift(ADF4382A_Manager *manager, uint8_t device)
|
||||
{
|
||||
if (!manager || !manager->initialized) {
|
||||
return ADF4382A_MANAGER_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Generate a pulse on DELSTR pin to latch the current DELADJ value
|
||||
set_delstr_pin(device, true);
|
||||
no_os_udelay(DELADJ_PULSE_WIDTH_US);
|
||||
set_delstr_pin(device, false);
|
||||
|
||||
printf("Device %d phase shift strobed\n", device);
|
||||
|
||||
return ADF4382A_MANAGER_OK;
|
||||
}
|
||||
|
||||
// Static helper functions
|
||||
|
||||
static void set_chip_enable(uint8_t ce_pin, bool state)
|
||||
{
|
||||
GPIO_TypeDef* port = (ce_pin == TX_CE_Pin) ? TX_CE_GPIO_Port : RX_CE_GPIO_Port;
|
||||
HAL_GPIO_WritePin(port, ce_pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
static void set_deladj_pin(uint8_t device, bool state)
|
||||
{
|
||||
if (device == 0) { // TX device
|
||||
HAL_GPIO_WritePin(TX_DELADJ_GPIO_Port, TX_DELADJ_Pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
} else { // RX device
|
||||
HAL_GPIO_WritePin(RX_DELADJ_GPIO_Port, RX_DELADJ_Pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_delstr_pin(uint8_t device, bool state)
|
||||
{
|
||||
if (device == 0) { // TX device
|
||||
HAL_GPIO_WritePin(TX_DELSTR_GPIO_Port, TX_DELSTR_Pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
} else { // RX device
|
||||
HAL_GPIO_WritePin(RX_DELSTR_GPIO_Port, RX_DELSTR_Pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t phase_ps_to_duty_cycle(uint16_t phase_ps)
|
||||
{
|
||||
// Convert phase shift in picoseconds to DELADJ duty cycle
|
||||
// This is a linear mapping - adjust based on your specific requirements
|
||||
uint32_t duty = (uint32_t)phase_ps * DELADJ_MAX_DUTY_CYCLE / PHASE_SHIFT_MAX_PS;
|
||||
return (uint16_t)duty;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef ADF4382A_MANAGER_H
|
||||
#define ADF4382A_MANAGER_H
|
||||
|
||||
#include "main.h"
|
||||
#include "adf4382.h"
|
||||
#include "no_os_spi.h"
|
||||
|
||||
// GPIO Definitions
|
||||
#define TX_CE_Pin GPIO_PIN_0
|
||||
#define TX_CE_GPIO_Port GPIOG
|
||||
#define TX_CS_Pin GPIO_PIN_1
|
||||
#define TX_CS_GPIO_Port GPIOG
|
||||
#define TX_DELADJ_Pin GPIO_PIN_2
|
||||
#define TX_DELADJ_GPIO_Port GPIOG
|
||||
#define TX_DELSTR_Pin GPIO_PIN_3
|
||||
#define TX_DELSTR_GPIO_Port GPIOG
|
||||
#define TX_LKDET_Pin GPIO_PIN_4
|
||||
#define TX_LKDET_GPIO_Port GPIOG
|
||||
|
||||
#define RX_CE_Pin GPIO_PIN_5
|
||||
#define RX_CE_GPIO_Port GPIOG
|
||||
#define RX_CS_Pin GPIO_PIN_6
|
||||
#define RX_CS_GPIO_Port GPIOG
|
||||
#define RX_DELADJ_Pin GPIO_PIN_7
|
||||
#define RX_DELADJ_GPIO_Port GPIOG
|
||||
#define RX_DELSTR_Pin GPIO_PIN_8
|
||||
#define RX_DELSTR_GPIO_Port GPIOG
|
||||
#define RX_LKDET_Pin GPIO_PIN_9
|
||||
#define RX_LKDET_GPIO_Port GPIOG
|
||||
|
||||
// Frequency definitions
|
||||
#define REF_FREQ_HZ 300000000ULL // 300 MHz
|
||||
#define TX_FREQ_HZ 10500000000ULL // 10.5 GHz
|
||||
#define RX_FREQ_HZ 10380000000ULL // 10.38 GHz
|
||||
#define SYNC_CLOCK_FREQ 60000000ULL // 60 MHz sync clock
|
||||
|
||||
// SPI Configuration
|
||||
#define ADF4382A_SPI_DEVICE_ID 4 // Using SPI4
|
||||
#define ADF4382A_SPI_SPEED_HZ 10000000 // 10 MHz
|
||||
|
||||
// Phase delay configuration
|
||||
#define DELADJ_MAX_DUTY_CYCLE 1000 // Maximum duty cycle for DELADJ PWM (1000 = 100%)
|
||||
#define DELADJ_PULSE_WIDTH_US 10 // Width of DELSTR pulse in microseconds
|
||||
#define PHASE_SHIFT_MAX_PS 10000 // Maximum phase shift in picoseconds
|
||||
|
||||
// Error code definitions
|
||||
#define ADF4382A_MANAGER_OK 0
|
||||
#define ADF4382A_MANAGER_ERROR_INVALID -1
|
||||
#define ADF4382A_MANAGER_ERROR_NOT_INIT -2
|
||||
#define ADF4382A_MANAGER_ERROR_SPI -3
|
||||
|
||||
typedef enum {
|
||||
SYNC_METHOD_EZSYNC = 0, // Software synchronization via SPI
|
||||
SYNC_METHOD_TIMED = 1 // Hardware synchronization via SYNCP/SYNCN
|
||||
} SyncMethod;
|
||||
|
||||
typedef struct {
|
||||
struct adf4382_dev *tx_dev;
|
||||
struct adf4382_dev *rx_dev;
|
||||
struct no_os_spi_init_param spi_tx_param;
|
||||
struct no_os_spi_init_param spi_rx_param;
|
||||
bool initialized;
|
||||
SyncMethod sync_method;
|
||||
uint16_t tx_phase_shift_ps; // Current TX phase shift in picoseconds
|
||||
uint16_t rx_phase_shift_ps; // Current RX phase shift in picoseconds
|
||||
} ADF4382A_Manager;
|
||||
|
||||
// Public functions
|
||||
int ADF4382A_Manager_Init(ADF4382A_Manager *manager, SyncMethod method);
|
||||
int ADF4382A_Manager_Deinit(ADF4382A_Manager *manager);
|
||||
int ADF4382A_SetupTimedSync(ADF4382A_Manager *manager);
|
||||
int ADF4382A_SetupEZSync(ADF4382A_Manager *manager);
|
||||
int ADF4382A_TriggerTimedSync(ADF4382A_Manager *manager);
|
||||
int ADF4382A_TriggerEZSync(ADF4382A_Manager *manager);
|
||||
int ADF4382A_CheckLockStatus(ADF4382A_Manager *manager, bool *tx_locked, bool *rx_locked);
|
||||
int ADF4382A_SetOutputPower(ADF4382A_Manager *manager, uint8_t tx_power, uint8_t rx_power);
|
||||
int ADF4382A_EnableOutputs(ADF4382A_Manager *manager, bool tx_enable, bool rx_enable);
|
||||
|
||||
// New phase delay functions
|
||||
int ADF4382A_SetPhaseShift(ADF4382A_Manager *manager, uint16_t tx_phase_ps, uint16_t rx_phase_ps);
|
||||
int ADF4382A_GetPhaseShift(ADF4382A_Manager *manager, uint16_t *tx_phase_ps, uint16_t *rx_phase_ps);
|
||||
int ADF4382A_SetFinePhaseShift(ADF4382A_Manager *manager, uint8_t device, uint16_t duty_cycle);
|
||||
int ADF4382A_StrobePhaseShift(ADF4382A_Manager *manager, uint8_t device);
|
||||
|
||||
#endif // ADF4382A_MANAGER_H
|
||||
100
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/errno.h
Normal file
100
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/errno.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/***************************************************************************//**
|
||||
* @file errno.h
|
||||
* @brief Error macro definition for ARM Compiler
|
||||
********************************************************************************
|
||||
* Copyright (c) 2021-2022 Analog Devices, Inc.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef MBED_ERRNO_H_
|
||||
#define MBED_ERRNO_H_
|
||||
|
||||
// Platform drivers needs to be C-compatible to work with other drivers
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // _cplusplus
|
||||
|
||||
#if defined(__ARMCC_VERSION)
|
||||
#if !defined(__ELASTERROR)
|
||||
#define __ELASTERROR 2000
|
||||
#endif
|
||||
#if !defined(ENOTSUP)
|
||||
#define ENOTSUP 9926
|
||||
#endif
|
||||
#if !defined(EBADMSG)
|
||||
#define EBADMSG 9905
|
||||
#endif
|
||||
#if !defined(ETIME)
|
||||
#define ETIME 9935
|
||||
#endif
|
||||
#if !defined(EACCES)
|
||||
#define EACCES 9973
|
||||
#endif
|
||||
#if !defined(ETIMEDOUT)
|
||||
#define ETIMEDOUT 9938
|
||||
#endif
|
||||
#if !defined(ENODEV)
|
||||
#define ENODEV 9967
|
||||
#endif
|
||||
#if !defined(EFAULT)
|
||||
#define EFAULT 9948
|
||||
#endif
|
||||
#if !defined(EIO)
|
||||
#define EIO 9961
|
||||
#endif
|
||||
#if !defined(ENOENT)
|
||||
#define ENOENT 9968
|
||||
#endif
|
||||
#if !defined(EBUSY)
|
||||
#define EBUSY 9952
|
||||
#endif
|
||||
#if !defined(EAGAIN)
|
||||
#define EAGAIN 9976
|
||||
#endif
|
||||
#if !defined(EINVAL)
|
||||
#define EINVAL 9943
|
||||
#endif
|
||||
#if !defined(ENOMEM)
|
||||
#define ENOMEM 9971
|
||||
#endif
|
||||
#if !defined(ENOSYS)
|
||||
#define ENOSYS 88
|
||||
#endif
|
||||
#if !defined(ENOTCONN)
|
||||
#define ENOTCONN 128
|
||||
#endif
|
||||
|
||||
// End of defined(__ARMCC_VERSION)
|
||||
#endif
|
||||
|
||||
#include_next <errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // _cplusplus
|
||||
|
||||
#endif // MBED_ERRNO_H_
|
||||
@@ -0,0 +1,119 @@
|
||||
// gps_handler.cpp
|
||||
#include "gps_handler.h"
|
||||
#include <cmath>
|
||||
|
||||
// UART handle for communication with GUI
|
||||
static UART_HandleTypeDef* gui_huart = NULL;
|
||||
|
||||
// GPS data buffer
|
||||
static GPS_Data_t current_gps = {0};
|
||||
|
||||
void GPS_Init(UART_HandleTypeDef* huart)
|
||||
{
|
||||
gui_huart = huart;
|
||||
memset(¤t_gps, 0, sizeof(GPS_Data_t));
|
||||
}
|
||||
|
||||
uint8_t GPS_IsDataValid(GPS_Data_t* gps_data)
|
||||
{
|
||||
// Check if GPS data is within valid ranges
|
||||
if (gps_data->latitude < -90.0 || gps_data->latitude > 90.0)
|
||||
return 0;
|
||||
if (gps_data->longitude < -180.0 || gps_data->longitude > 180.0)
|
||||
return 0;
|
||||
if (gps_data->altitude < -1000.0 || gps_data->altitude > 10000.0) // -1km to 10km
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GPS_ProcessData(GPS_Data_t* gps_data)
|
||||
{
|
||||
// Validate GPS data
|
||||
if (!GPS_IsDataValid(gps_data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update current GPS data
|
||||
memcpy(¤t_gps, gps_data, sizeof(GPS_Data_t));
|
||||
current_gps.timestamp = HAL_GetTick();
|
||||
|
||||
// Send to GUI
|
||||
GPS_SendToGUI(¤t_gps);
|
||||
}
|
||||
|
||||
void GPS_SendToGUI(GPS_Data_t* gps_data)
|
||||
{
|
||||
if (gui_huart == NULL) return;
|
||||
|
||||
// Create packet: "GPS:lat,lon,alt\r\n"
|
||||
char buffer[64];
|
||||
|
||||
// Convert double and float to string with high precision
|
||||
int len = snprintf(buffer, sizeof(buffer), "GPS:%.8f,%.8f,%.2f\r\n",
|
||||
gps_data->latitude,
|
||||
gps_data->longitude,
|
||||
gps_data->altitude);
|
||||
|
||||
if (len > 0 && len < (int)sizeof(buffer)) {
|
||||
// Send via UART3 to GUI
|
||||
HAL_UART_Transmit(gui_huart, (uint8_t*)buffer, len, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Alternative binary protocol version (more efficient)
|
||||
void GPS_SendBinaryToGUI(GPS_Data_t* gps_data)
|
||||
{
|
||||
if (gui_huart == NULL) return;
|
||||
|
||||
// Binary packet structure:
|
||||
// [Header 4 bytes][Latitude 8 bytes][Longitude 8 bytes][Altitude 4 bytes][Pitch 4 bytes][CRC 2 bytes]
|
||||
|
||||
uint8_t packet[30]; // 4 + 8 + 8 + 4 + 4 + 2 = 30 bytes
|
||||
uint16_t crc = 0;
|
||||
|
||||
// Header: "GPSB"
|
||||
packet[0] = 'G';
|
||||
packet[1] = 'P';
|
||||
packet[2] = 'S';
|
||||
packet[3] = 'B';
|
||||
|
||||
// Convert double latitude to bytes (big-endian)
|
||||
uint64_t lat_bits;
|
||||
memcpy(&lat_bits, &gps_data->latitude, sizeof(double));
|
||||
for(int i = 0; i < 8; i++) {
|
||||
packet[4 + i] = (lat_bits >> (56 - i*8)) & 0xFF;
|
||||
}
|
||||
|
||||
// Convert double longitude to bytes (big-endian)
|
||||
uint64_t lon_bits;
|
||||
memcpy(&lon_bits, &gps_data->longitude, sizeof(double));
|
||||
for(int i = 0; i < 8; i++) {
|
||||
packet[12 + i] = (lon_bits >> (56 - i*8)) & 0xFF;
|
||||
}
|
||||
|
||||
// Convert float altitude to bytes (big-endian)
|
||||
uint32_t alt_bits;
|
||||
memcpy(&alt_bits, &gps_data->altitude, sizeof(float));
|
||||
for(int i = 0; i < 4; i++) {
|
||||
packet[20 + i] = (alt_bits >> (24 - i*8)) & 0xFF;
|
||||
}
|
||||
|
||||
// Convert float altitude to bytes (big-endian)
|
||||
uint32_t pitch_bits;
|
||||
memcpy(&pitch_bits, &gps_data->pitch, sizeof(float));
|
||||
for(int i = 0; i < 4; i++) {
|
||||
packet[24 + i] = (pitch_bits >> (24 - i*8)) & 0xFF;
|
||||
}
|
||||
|
||||
// Calculate simple checksum (you can use CRC16 instead)
|
||||
for(int i = 0; i < 28; i++) {
|
||||
crc += packet[i];
|
||||
}
|
||||
|
||||
packet[28] = (crc >> 8) & 0xFF;
|
||||
packet[29] = crc & 0xFF;
|
||||
|
||||
// Send binary packet
|
||||
CDC_Transmit_FS(packet, sizeof(packet));
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// gps_handler.h
|
||||
#ifndef GPS_HANDLER_H
|
||||
#define GPS_HANDLER_H
|
||||
|
||||
#include "main.h"
|
||||
#include "usb_device.h"
|
||||
#include "usbd_cdc_if.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
double latitude;
|
||||
double longitude;
|
||||
float altitude;
|
||||
float pitch;
|
||||
uint32_t timestamp;
|
||||
} GPS_Data_t;
|
||||
|
||||
void GPS_Init(UART_HandleTypeDef* huart);
|
||||
void GPS_ProcessData(GPS_Data_t* gps_data);
|
||||
void GPS_SendToGUI(GPS_Data_t* gps_data);
|
||||
void GPS_SendBinaryToGUI(GPS_Data_t* gps_data);
|
||||
uint8_t GPS_IsDataValid(GPS_Data_t* gps_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GPS_HANDLER_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
/* platform_noos_stm32.h */
|
||||
#ifndef PLATFORM_NOOS_STM32_H
|
||||
#define PLATFORM_NOOS_STM32_H
|
||||
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Export the HAL SPI handle that will be used by no-OS SPI wrapper */
|
||||
extern SPI_HandleTypeDef hspi4;
|
||||
|
||||
/* Simple wrapper prototypes for no-OS */
|
||||
int32_t platform_spi_init(void **desc, uint32_t max_speed_hz, uint8_t mode);
|
||||
int32_t platform_spi_write_and_read(void *desc, uint8_t *data, uint16_t len);
|
||||
int32_t platform_spi_remove(void *desc);
|
||||
|
||||
int32_t platform_gpio_init(void *gpio_desc, uint8_t port_pin, bool is_output);
|
||||
int32_t platform_gpio_direction_output(void *gpio_desc, uint8_t port_pin, uint8_t value);
|
||||
int32_t platform_gpio_set_value(void *gpio_desc, uint8_t port_pin, uint8_t value);
|
||||
int32_t platform_gpio_remove(void *gpio_desc);
|
||||
|
||||
void platform_delay_ms(uint32_t ms);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
/* platform_noos_stm32.c */
|
||||
#include "platform_noos_stm32.h"
|
||||
|
||||
/* Use existing CubeMX handles */
|
||||
extern SPI_HandleTypeDef hspi4;
|
||||
|
||||
/* SPI descriptor we pass to no-OS (just a pointer to HAL handle) */
|
||||
int32_t platform_spi_init(void **desc, uint32_t max_speed_hz, uint8_t mode)
|
||||
{
|
||||
/* For STM32 HAL we already configured hspi4 in CubeMX,
|
||||
so just return that pointer as the descriptor. */
|
||||
if (!desc) return -1;
|
||||
*desc = (void*)&hspi4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SPI write/read - single transaction (no-OS expects raw transfer) */
|
||||
int32_t platform_spi_write_and_read(void *desc, uint8_t *data, uint16_t len)
|
||||
{
|
||||
SPI_HandleTypeDef *hdl = (SPI_HandleTypeDef*)desc;
|
||||
if (!hdl) return -1;
|
||||
/* ADI no-OS SPI wrappers often do full-duplex transfers */
|
||||
if (HAL_SPI_Transmit(hdl, data, len, HAL_MAX_DELAY) != HAL_OK)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t platform_spi_remove(void *desc)
|
||||
{
|
||||
(void)desc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Minimal GPIO wrapper: we will just use HAL GPIO directly */
|
||||
/* For simplicity we store nothing in gpio_desc, port_pin encodes both port and pin:
|
||||
You'll map an enum (0..n) -> HAL GPIO Port/Pin in your code. */
|
||||
|
||||
int32_t platform_gpio_init(void *gpio_desc, uint8_t port_pin, bool is_output)
|
||||
{
|
||||
(void)gpio_desc; (void)port_pin; (void)is_output;
|
||||
/* Assume CubeMX already configured the GPIO pins: nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t platform_gpio_direction_output(void *gpio_desc, uint8_t port_pin, uint8_t value)
|
||||
{
|
||||
(void)gpio_desc;
|
||||
/* Implement mapping here from port_pin index to actual port/pin */
|
||||
/* Example stub: user must implement mapping function: hal_set_gpio_by_index(port_pin, value) */
|
||||
extern void hal_set_gpio_by_index(uint8_t idx, uint8_t value);
|
||||
hal_set_gpio_by_index(port_pin, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t platform_gpio_set_value(void *gpio_desc, uint8_t port_pin, uint8_t value)
|
||||
{
|
||||
extern void hal_set_gpio_by_index(uint8_t idx, uint8_t value);
|
||||
hal_set_gpio_by_index(port_pin, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t platform_gpio_remove(void *gpio_desc) { (void)gpio_desc; return 0; }
|
||||
|
||||
void platform_delay_ms(uint32_t ms) { HAL_Delay(ms); }
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "no_os_delay.h"
|
||||
|
||||
/* microsecond delay using DWT cycle counter */
|
||||
void no_os_udelay(uint32_t usec)
|
||||
{
|
||||
uint32_t start = DWT->CYCCNT;
|
||||
uint32_t cycles = (HAL_RCC_GetHCLKFreq() / 1000000U) * usec;
|
||||
while ((DWT->CYCCNT - start) < cycles);
|
||||
}
|
||||
|
||||
/* millisecond delay wrapper */
|
||||
void no_os_mdelay(uint32_t msec)
|
||||
{
|
||||
HAL_Delay(msec);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef _STM32_DELAY_H_
|
||||
#define _STM32_DELAY_H_
|
||||
|
||||
#include "stm32f7xx_hal.h"
|
||||
|
||||
/* prototypes for compatibility */
|
||||
void no_os_udelay(uint32_t usec);
|
||||
void no_os_mdelay(uint32_t msec);
|
||||
|
||||
#endif /* _STM32_DELAY_H_ */
|
||||
287
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.c
Normal file
287
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_dma.c
|
||||
* @brief Implementation of stm32 DMA functionality.
|
||||
* @author Janani Sunil (janani.sunil@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2024(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "stm32_dma.h"
|
||||
#include "no_os_error.h"
|
||||
#include "no_os_alloc.h"
|
||||
#include "stm32_irq.h"
|
||||
|
||||
/**
|
||||
* @brief There is only one DMA controller
|
||||
*/
|
||||
static struct no_os_dma_desc *dma_descriptor;
|
||||
|
||||
/**
|
||||
* @brief Configure a DMA channel for a transfer.
|
||||
* @param channel - The DMA channel descriptor.
|
||||
* @param xfer - Descriptor for the transfer.
|
||||
* @return 0 in case of success, negative error codes otherwise
|
||||
*/
|
||||
int stm32_dma_config_xfer(struct no_os_dma_ch *channel,
|
||||
struct no_os_dma_xfer_desc *xfer)
|
||||
{
|
||||
struct stm32_dma_channel* sdma_ch;
|
||||
int ret;
|
||||
|
||||
if (!channel || !xfer || !channel->extra)
|
||||
return -EINVAL;
|
||||
|
||||
sdma_ch = channel->extra;
|
||||
|
||||
/* Note: Channel number is assigned via the Instance for MCU
|
||||
* families other than STM32F2, STM32F4 and STM32F7 */
|
||||
#if defined (STM32F2) || defined (STM32F4) || defined (STM32F7)
|
||||
sdma_ch->hdma->Init.Channel = sdma_ch->ch_num;
|
||||
#else
|
||||
sdma_ch->hdma->Instance = sdma_ch->ch_num;
|
||||
#endif
|
||||
sdma_ch->hdma->Init.MemInc = sdma_ch->mem_increment ? DMA_MINC_ENABLE :
|
||||
DMA_MINC_DISABLE;
|
||||
sdma_ch->hdma->Init.PeriphInc = sdma_ch->per_increment ? DMA_PINC_ENABLE :
|
||||
DMA_PINC_DISABLE;
|
||||
|
||||
switch (sdma_ch->mem_data_alignment) {
|
||||
case DATA_ALIGN_BYTE:
|
||||
sdma_ch->hdma->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
break;
|
||||
case DATA_ALIGN_HALF_WORD:
|
||||
sdma_ch->hdma->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
break;
|
||||
case DATA_ALIGN_WORD:
|
||||
sdma_ch->hdma->Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (sdma_ch->per_data_alignment) {
|
||||
case DATA_ALIGN_BYTE:
|
||||
sdma_ch->hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
break;
|
||||
case DATA_ALIGN_HALF_WORD:
|
||||
sdma_ch->hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
break;
|
||||
case DATA_ALIGN_WORD:
|
||||
sdma_ch->hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (sdma_ch->dma_mode) {
|
||||
case DMA_NORMAL_MODE:
|
||||
sdma_ch->hdma->Init.Mode = DMA_NORMAL;
|
||||
break;
|
||||
case DMA_CIRCULAR_MODE:
|
||||
sdma_ch->hdma->Init.Mode = DMA_CIRCULAR;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (xfer->xfer_type) {
|
||||
case MEM_TO_MEM:
|
||||
sdma_ch->hdma->Init.Direction = DMA_MEMORY_TO_MEMORY;
|
||||
break;
|
||||
case MEM_TO_DEV:
|
||||
sdma_ch->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
break;
|
||||
case DEV_TO_MEM:
|
||||
sdma_ch->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sdma_ch->src = xfer->src;
|
||||
sdma_ch->dst = xfer->dst;
|
||||
sdma_ch->length = xfer->length;
|
||||
|
||||
ret = HAL_DMA_Init(sdma_ch->hdma);
|
||||
if (ret != HAL_OK)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize a DMA controller.
|
||||
* @param desc - Descriptor to be initialized.
|
||||
* @param param - Initialization parameter for the decriptor.
|
||||
* @return 0 in case of success
|
||||
* -ENOMEM if there is not enough free memory
|
||||
*/
|
||||
int stm32_dma_init(struct no_os_dma_desc** desc,
|
||||
const struct no_os_dma_init_param* param)
|
||||
{
|
||||
struct no_os_dma_desc* descriptor;
|
||||
int ret;
|
||||
uint8_t i;
|
||||
struct no_os_irq_init_param irq_param = {
|
||||
.irq_ctrl_id = 0,
|
||||
.platform_ops = &stm32_irq_ops,
|
||||
.extra = NULL
|
||||
};
|
||||
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
if (dma_descriptor) {
|
||||
/*
|
||||
* There is only one DMA controller and it's already
|
||||
* initialized.
|
||||
*/
|
||||
*desc = dma_descriptor;
|
||||
return 0;
|
||||
}
|
||||
|
||||
descriptor = no_os_calloc(1, sizeof(*descriptor));
|
||||
if (!descriptor)
|
||||
return -ENOMEM;
|
||||
|
||||
descriptor->channels = no_os_calloc(param->num_ch,
|
||||
sizeof(*descriptor->channels));
|
||||
if (!descriptor->channels) {
|
||||
ret = -ENOMEM;
|
||||
goto free_descriptor;
|
||||
}
|
||||
|
||||
descriptor->id = param->id;
|
||||
descriptor->num_ch = param->num_ch;
|
||||
descriptor->sg_handler = param->sg_handler;
|
||||
|
||||
for (i = 0; i < param->num_ch; i++) {
|
||||
descriptor->channels[i].free = true;
|
||||
}
|
||||
|
||||
no_os_irq_ctrl_init(&descriptor->irq_ctrl, &irq_param);
|
||||
|
||||
*desc = descriptor;
|
||||
|
||||
return 0;
|
||||
|
||||
free_descriptor:
|
||||
no_os_free(descriptor);
|
||||
descriptor = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a DMA transfer for a specific channel .
|
||||
* @param desc - Descriptor for the DMA controller.
|
||||
* @param chan - The DMA Channel
|
||||
* @return 0 in case of success, negative error codes otherwise
|
||||
*/
|
||||
int stm32_dma_xfer_start(struct no_os_dma_desc *desc,
|
||||
struct no_os_dma_ch *chan)
|
||||
{
|
||||
int ret;
|
||||
struct stm32_dma_channel* sdma_chan;
|
||||
|
||||
if (!desc || !chan || !chan->extra)
|
||||
return -EINVAL;
|
||||
|
||||
sdma_chan = chan->extra;
|
||||
|
||||
if (chan->irq_num) {
|
||||
ret = HAL_DMA_Start_IT(sdma_chan->hdma, (uint32_t)sdma_chan->src,
|
||||
(uint32_t)sdma_chan->dst, sdma_chan->length);
|
||||
} else {
|
||||
ret = HAL_DMA_Start(sdma_chan->hdma, (uint32_t)sdma_chan->src,
|
||||
(uint32_t)sdma_chan->dst, sdma_chan->length);
|
||||
}
|
||||
|
||||
if (ret != HAL_OK)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a DMA channel.
|
||||
* @param desc - Descriptor for the DMA controller.
|
||||
* @param chan - The DMA Channel
|
||||
* @return 0 in case of success, negative error codes otherwise
|
||||
*/
|
||||
int stm32_dma_xfer_abort(struct no_os_dma_desc* desc,
|
||||
struct no_os_dma_ch* chan)
|
||||
{
|
||||
int ret;
|
||||
struct stm32_dma_channel* sdma_chan;
|
||||
|
||||
if (!desc || !chan || !chan->extra)
|
||||
return -EINVAL;
|
||||
|
||||
sdma_chan = chan->extra;
|
||||
|
||||
if (chan->irq_num)
|
||||
ret = HAL_DMA_Abort_IT(sdma_chan->hdma);
|
||||
else
|
||||
ret = HAL_DMA_Abort(sdma_chan->hdma);
|
||||
|
||||
if (ret != HAL_OK)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated for a DMA descriptor.
|
||||
* @param desc - Descriptor to be freed.
|
||||
* @return 0 in case of success, negative error code otherwise
|
||||
*/
|
||||
int stm32_dma_remove(struct no_os_dma_desc* desc)
|
||||
{
|
||||
no_os_irq_ctrl_remove(desc->irq_ctrl);
|
||||
|
||||
no_os_free(desc->channels);
|
||||
|
||||
no_os_free(desc);
|
||||
|
||||
dma_descriptor = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stm32 platform specific DMA platform ops structure
|
||||
*/
|
||||
const struct no_os_dma_platform_ops stm32_dma_ops = {
|
||||
.dma_init = stm32_dma_init,
|
||||
.dma_config_xfer = stm32_dma_config_xfer,
|
||||
.dma_xfer_start = stm32_dma_xfer_start,
|
||||
.dma_xfer_abort = stm32_dma_xfer_abort,
|
||||
.dma_remove = stm32_dma_remove
|
||||
};
|
||||
|
||||
101
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.h
Normal file
101
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_dma.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32_dma.h
|
||||
* @brief Platform independent function definitions and data types
|
||||
* for the DMA API.
|
||||
* @author Janani Sunil (janani.sunil@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2024(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef STM32_DMA_H_
|
||||
#define STM32_DMA_H_
|
||||
|
||||
#include "no_os_dma.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
/**
|
||||
* @enum stm32_dma_data_alignment
|
||||
* @brief DMA Data alignment
|
||||
*/
|
||||
enum stm32_dma_data_alignment {
|
||||
DATA_ALIGN_BYTE = 0,
|
||||
DATA_ALIGN_HALF_WORD = 1,
|
||||
DATA_ALIGN_WORD = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum stm32_dma_mode
|
||||
* @brief DMA Data Modes
|
||||
*/
|
||||
enum stm32_dma_mode {
|
||||
DMA_NORMAL_MODE = 0,
|
||||
DMA_CIRCULAR_MODE = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct stm32_dma_channel
|
||||
* @brief STM32 DMA Channels
|
||||
*/
|
||||
struct stm32_dma_channel {
|
||||
/* DMA Handle */
|
||||
DMA_HandleTypeDef *hdma;
|
||||
/* Channel Number */
|
||||
uint32_t ch_num;
|
||||
/* Memory Increment */
|
||||
bool mem_increment;
|
||||
/* Peripheral Increment */
|
||||
bool per_increment;
|
||||
/* Memory Data Alignment */
|
||||
enum stm32_dma_data_alignment mem_data_alignment;
|
||||
/* Peripheral Data Alignment */
|
||||
enum stm32_dma_data_alignment per_data_alignment;
|
||||
/* DMA Mode */
|
||||
enum stm32_dma_mode dma_mode;
|
||||
/* Source Address for the data */
|
||||
uint8_t* src;
|
||||
/* Destination Address for the data */
|
||||
uint8_t* dst;
|
||||
/* Transfer length in Bytes */
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
struct stm32_dma_init_param {
|
||||
/* DMA Channel descriptor */
|
||||
struct stm32_dma_channel *chn;
|
||||
};
|
||||
|
||||
struct stm32_dma_desc {
|
||||
/* DMA Channel Descriptor */
|
||||
struct stm32_dma_channel* chn;
|
||||
};
|
||||
|
||||
extern const struct no_os_dma_platform_ops stm32_dma_ops;
|
||||
extern const struct no_os_dma_platform_ops stm32_gpdma_ops;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,394 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_gpio.c
|
||||
* @brief Implementation of stm32 gpio functionality.
|
||||
* @author Darius Berghe (darius.berghe@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "no_os_util.h"
|
||||
#include "no_os_gpio.h"
|
||||
#include "no_os_alloc.h"
|
||||
#include "stm32_gpio.h"
|
||||
|
||||
/**
|
||||
* @brief Prepare the GPIO decriptor.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - The structure that contains the GPIO parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
static int32_t _gpio_init(struct no_os_gpio_desc *desc,
|
||||
const struct no_os_gpio_init_param *param)
|
||||
{
|
||||
int32_t ret = 0;
|
||||
struct stm32_gpio_desc *extra = desc->extra;
|
||||
struct stm32_gpio_init_param *pextra = param->extra;
|
||||
uint32_t mode = GPIO_MODE_INPUT;
|
||||
uint32_t speed = GPIO_SPEED_FREQ_LOW;
|
||||
|
||||
if (!param)
|
||||
return -EINVAL;
|
||||
|
||||
/* enable gpio port in RCC */
|
||||
if (param->port == 0) {
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
extra->port = GPIOA;
|
||||
}
|
||||
#ifdef GPIOB
|
||||
else if (param->port == 1) {
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
extra->port = GPIOB;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOC
|
||||
else if (param->port == 2) {
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
extra->port = GPIOC;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOD
|
||||
else if (param->port == 3) {
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
extra->port = GPIOD;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOE
|
||||
else if (param->port == 4) {
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
extra->port = GPIOE;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOF
|
||||
else if (param->port == 5) {
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
extra->port = GPIOF;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOG
|
||||
else if (param->port == 6) {
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
extra->port = GPIOG;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOH
|
||||
else if (param->port == 7) {
|
||||
__HAL_RCC_GPIOH_CLK_ENABLE();
|
||||
extra->port = GPIOH;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOI
|
||||
else if (param->port == 8) {
|
||||
__HAL_RCC_GPIOI_CLK_ENABLE();
|
||||
extra->port = GPIOI;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOJ
|
||||
else if (param->port == 9) {
|
||||
__HAL_RCC_GPIOJ_CLK_ENABLE();
|
||||
extra->port = GPIOJ;
|
||||
}
|
||||
#endif
|
||||
#ifdef GPIOK
|
||||
else if (param->port == 10) {
|
||||
__HAL_RCC_GPIOK_CLK_ENABLE();
|
||||
extra->port = GPIOK;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
if (param->extra) {
|
||||
mode = pextra->mode;
|
||||
speed = pextra->speed;
|
||||
}
|
||||
|
||||
if (!IS_GPIO_MODE(mode))
|
||||
return -EINVAL;
|
||||
|
||||
switch (mode) {
|
||||
case GPIO_MODE_INPUT:
|
||||
case GPIO_MODE_OUTPUT_PP:
|
||||
case GPIO_MODE_OUTPUT_OD:
|
||||
break;
|
||||
case GPIO_MODE_AF_PP:
|
||||
extra->gpio_config.Alternate = pextra->alternate;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* copy the settings to gpio descriptor */
|
||||
desc->port = param->port;
|
||||
desc->number = param->number;
|
||||
desc->pull = param->pull;
|
||||
|
||||
switch (param->pull) {
|
||||
case NO_OS_PULL_NONE:
|
||||
extra->gpio_config.Pull = GPIO_NOPULL;
|
||||
break;
|
||||
case NO_OS_PULL_UP:
|
||||
case NO_OS_PULL_UP_WEAK:
|
||||
extra->gpio_config.Pull = GPIO_PULLUP;
|
||||
break;
|
||||
case NO_OS_PULL_DOWN:
|
||||
case NO_OS_PULL_DOWN_WEAK:
|
||||
extra->gpio_config.Pull = GPIO_PULLDOWN;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* configure gpio with user configuration */
|
||||
extra->gpio_config.Pin = NO_OS_BIT(param->number);
|
||||
extra->gpio_config.Mode = mode;
|
||||
extra->gpio_config.Speed = speed;
|
||||
|
||||
HAL_GPIO_Init(extra->port, &extra->gpio_config);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Obtain the GPIO decriptor.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO initialization parameters
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_gpio_get(struct no_os_gpio_desc **desc,
|
||||
const struct no_os_gpio_init_param *param)
|
||||
{
|
||||
struct no_os_gpio_desc *descriptor;
|
||||
struct stm32_gpio_desc *extra;
|
||||
int32_t ret;
|
||||
|
||||
if (!desc || !param)
|
||||
return -EINVAL;
|
||||
|
||||
descriptor = (struct no_os_gpio_desc *)no_os_malloc(sizeof(*descriptor));
|
||||
if (!descriptor) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
extra = (struct stm32_gpio_desc*)no_os_malloc(sizeof(*extra));
|
||||
if (!extra) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
descriptor->extra = extra;
|
||||
ret = _gpio_init(descriptor, param);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
*desc = descriptor;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
no_os_free(extra);
|
||||
no_os_free(descriptor);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of an optional GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param param - GPIO Initialization parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_gpio_get_optional(struct no_os_gpio_desc **desc,
|
||||
const struct no_os_gpio_init_param *param)
|
||||
{
|
||||
if (param == NULL) {
|
||||
*desc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return stm32_gpio_get(desc, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by no_os_gpio_get().
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_gpio_remove(struct no_os_gpio_desc *desc)
|
||||
{
|
||||
if (desc != NULL)
|
||||
no_os_free(desc->extra);
|
||||
|
||||
no_os_free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the input direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_gpio_direction_input(struct no_os_gpio_desc *desc)
|
||||
{
|
||||
struct stm32_gpio_desc *extra;
|
||||
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->extra)
|
||||
return -EFAULT;
|
||||
|
||||
extra = desc->extra;
|
||||
|
||||
/* configure gpio with user configuration */
|
||||
extra->gpio_config.Mode = GPIO_MODE_INPUT;
|
||||
HAL_GPIO_Init(extra->port, &extra->gpio_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the output direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: NO_OS_GPIO_HIGH
|
||||
* NO_OS_GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_gpio_direction_output(struct no_os_gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
struct stm32_gpio_desc *extra;
|
||||
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->extra)
|
||||
return -EFAULT;
|
||||
|
||||
extra = desc->extra;
|
||||
|
||||
/* configure gpio output level */
|
||||
HAL_GPIO_WritePin(extra->port, NO_OS_BIT(desc->number), (GPIO_PinState)value);
|
||||
|
||||
/* configure gpio with user configuration */
|
||||
if (extra->gpio_config.Mode == GPIO_MODE_INPUT)
|
||||
extra->gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
HAL_GPIO_Init(extra->port, &extra->gpio_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the direction of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param direction - The direction.
|
||||
* Example: NO_OS_GPIO_OUT
|
||||
* NO_OS_GPIO_IN
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_gpio_get_direction(struct no_os_gpio_desc *desc,
|
||||
uint8_t *direction)
|
||||
{
|
||||
if (!desc || !direction)
|
||||
return -EINVAL;
|
||||
|
||||
struct stm32_gpio_desc *extra = desc->extra;
|
||||
if (!extra->gpio_config.Mode)
|
||||
*direction = NO_OS_GPIO_IN;
|
||||
else
|
||||
*direction = NO_OS_GPIO_OUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: NO_OS_GPIO_HIGH
|
||||
* NO_OS_GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_gpio_set_value(struct no_os_gpio_desc *desc,
|
||||
uint8_t value)
|
||||
{
|
||||
struct stm32_gpio_desc *extra;
|
||||
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->extra)
|
||||
return -EFAULT;
|
||||
|
||||
extra = desc->extra;
|
||||
|
||||
/* configure gpio output level */
|
||||
HAL_GPIO_WritePin(extra->port, NO_OS_BIT(desc->number), (GPIO_PinState)value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of the specified GPIO.
|
||||
* @param desc - The GPIO descriptor.
|
||||
* @param value - The value.
|
||||
* Example: NO_OS_GPIO_HIGH
|
||||
* NO_OS_GPIO_LOW
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_gpio_get_value(struct no_os_gpio_desc *desc,
|
||||
uint8_t *value)
|
||||
{
|
||||
struct stm32_gpio_desc *extra;
|
||||
|
||||
if (!desc || !value)
|
||||
return -EINVAL;
|
||||
|
||||
if (!desc->extra)
|
||||
return -EFAULT;
|
||||
|
||||
extra = desc->extra;
|
||||
|
||||
*value = (uint8_t)HAL_GPIO_ReadPin(extra->port, NO_OS_BIT(desc->number));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stm32 platform specific GPIO platform ops structure
|
||||
*/
|
||||
const struct no_os_gpio_platform_ops stm32_gpio_ops = {
|
||||
.gpio_ops_get = &stm32_gpio_get,
|
||||
.gpio_ops_get_optional = &stm32_gpio_get_optional,
|
||||
.gpio_ops_remove = &stm32_gpio_remove,
|
||||
.gpio_ops_direction_input = &stm32_gpio_direction_input,
|
||||
.gpio_ops_direction_output = &stm32_gpio_direction_output,
|
||||
.gpio_ops_get_direction = &stm32_gpio_get_direction,
|
||||
.gpio_ops_set_value = &stm32_gpio_set_value,
|
||||
.gpio_ops_get_value = &stm32_gpio_get_value,
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_gpio.h
|
||||
* @brief Header file for stm32 gpio specifics.
|
||||
* @author Darius Berghe (darius.berghe@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef STM32_GPIO_H_
|
||||
#define STM32_GPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "stm32_hal.h"
|
||||
|
||||
/**
|
||||
* @struct stm32_gpio_init_param
|
||||
* @brief Structure holding the initialization parameters for stm32 platform
|
||||
*/
|
||||
struct stm32_gpio_init_param {
|
||||
/** Output mode */
|
||||
uint32_t mode;
|
||||
/** Speed grade */
|
||||
uint32_t speed;
|
||||
/** Alternate functionality */
|
||||
uint32_t alternate;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct stm32_gpio_desc
|
||||
* @brief stm32 platform specific gpio descriptor
|
||||
*/
|
||||
struct stm32_gpio_desc {
|
||||
/** Port */
|
||||
GPIO_TypeDef *port;
|
||||
/** GPIO configuration */
|
||||
GPIO_InitTypeDef gpio_config;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief stm32 platform specific gpio platform ops structure
|
||||
*/
|
||||
extern const struct no_os_gpio_platform_ops stm32_gpio_ops;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,463 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_gpio_irq.c
|
||||
* @brief Source file for GPIO IRQ driver.
|
||||
* @author Ramona Bolboaca (ramona.bolboaca@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2022(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "no_os_list.h"
|
||||
#include "no_os_irq.h"
|
||||
#include "no_os_util.h"
|
||||
#include "no_os_alloc.h"
|
||||
#include "stm32_gpio_irq.h"
|
||||
|
||||
#define STM32_IRQ_CTRL_NB 16
|
||||
|
||||
/**
|
||||
* @brief Struct used to store a (peripheral, callback) pair
|
||||
*/
|
||||
struct irq_action {
|
||||
uint32_t irq_id;
|
||||
void (*callback)(void *context);
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
static struct no_os_list_desc *actions;
|
||||
|
||||
static int32_t irq_action_cmp(void *data1, void *data2)
|
||||
{
|
||||
return ((struct irq_action *)data1)->irq_id -
|
||||
((struct irq_action *)data2)->irq_id;
|
||||
}
|
||||
|
||||
static bool initialized[STM32_IRQ_CTRL_NB] = {false};
|
||||
|
||||
/**
|
||||
* @brief Generic Interrupt handler callback
|
||||
* @param pin pin number on which the interrupt occurred (GPIO_PIN_pin)
|
||||
*/
|
||||
static inline void stm32_handle_generic_callback(uint16_t pin)
|
||||
{
|
||||
int ret;
|
||||
struct irq_action *action;
|
||||
struct irq_action key;
|
||||
|
||||
key.irq_id = no_os_find_first_set_bit(pin);
|
||||
|
||||
ret = no_os_list_read_find(actions, (void **)&action, &key);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
if (action->callback)
|
||||
action->callback(action->ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXTI GPIO Interrupt handler callback
|
||||
* @param pin pin number on which the interrupt occurred (GPIO_PIN_pin)
|
||||
*/
|
||||
void HAL_GPIO_EXTI_Callback(uint16_t pin)
|
||||
{
|
||||
stm32_handle_generic_callback(pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXTI GPIO Interrupt handler callback for rising edge detection
|
||||
* @param pin pin number on which the interrupt occurred (GPIO_PIN_pin)
|
||||
*/
|
||||
void HAL_GPIO_EXTI_Rising_Callback(uint16_t pin)
|
||||
{
|
||||
stm32_handle_generic_callback(pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXTI GPIO Interrupt handler callback for falling edge detection
|
||||
* @param pin pin number on which the interrupt occurred (GPIO_PIN_pin)
|
||||
*/
|
||||
void HAL_GPIO_EXTI_Falling_Callback(uint16_t pin)
|
||||
{
|
||||
stm32_handle_generic_callback(pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the GPIO interrupt controller
|
||||
* @param desc - Pointer where the configured instance is stored
|
||||
* @param param - Configuration information for the instance
|
||||
* @return 0 in case of success, errno error codes otherwise.
|
||||
*/
|
||||
static int stm32_gpio_irq_ctrl_init(struct no_os_irq_ctrl_desc **desc,
|
||||
const struct no_os_irq_init_param *param)
|
||||
{
|
||||
static struct no_os_irq_ctrl_desc *gpio_irq_desc_arr[STM32_IRQ_CTRL_NB];
|
||||
|
||||
int ret;
|
||||
struct no_os_irq_ctrl_desc *gpio_irq_desc;
|
||||
struct stm32_gpio_irq_desc *sdesc;
|
||||
struct stm32_gpio_irq_init_param *gpio_irq_ip;
|
||||
|
||||
if (!param || !param->extra)
|
||||
return -EINVAL;
|
||||
|
||||
gpio_irq_ip = param->extra;
|
||||
|
||||
/* Check port number */
|
||||
if (!IS_EXTI_GPIO_PORT(gpio_irq_ip->port_nb))
|
||||
return -EINVAL;
|
||||
|
||||
/* Check pin number */
|
||||
if (!IS_EXTI_GPIO_PIN(param->irq_ctrl_id))
|
||||
return -EINVAL;
|
||||
|
||||
if (!initialized[param->irq_ctrl_id]) {
|
||||
|
||||
gpio_irq_desc = no_os_calloc(1, sizeof(*gpio_irq_desc));
|
||||
if (!gpio_irq_desc)
|
||||
return -ENOMEM;
|
||||
|
||||
sdesc = (struct stm32_gpio_irq_desc*)no_os_calloc(1, sizeof(*sdesc));
|
||||
if (!sdesc) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
/* Add port number */
|
||||
sdesc->port_nb = gpio_irq_ip->port_nb;
|
||||
|
||||
gpio_irq_desc->extra = sdesc;
|
||||
gpio_irq_desc->irq_ctrl_id = param->irq_ctrl_id;
|
||||
|
||||
ret = no_os_list_init(&actions, NO_OS_LIST_PRIORITY_LIST, irq_action_cmp);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
gpio_irq_desc_arr[param->irq_ctrl_id] = gpio_irq_desc;
|
||||
initialized[param->irq_ctrl_id] = true;
|
||||
}
|
||||
|
||||
*desc = gpio_irq_desc_arr[param->irq_ctrl_id];
|
||||
|
||||
return 0;
|
||||
error:
|
||||
no_os_list_remove(actions);
|
||||
no_os_free(gpio_irq_desc);
|
||||
no_os_free(sdesc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by irq_ctrl_init()
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @return 0 in case of success, errno error codes otherwise.
|
||||
*/
|
||||
static int stm32_gpio_irq_ctrl_remove(struct no_os_irq_ctrl_desc *desc)
|
||||
{
|
||||
struct no_os_callback_desc *discard;
|
||||
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
while (0 == no_os_list_get_first(actions, (void **)&discard))
|
||||
no_os_free(discard);
|
||||
|
||||
no_os_list_remove(actions);
|
||||
|
||||
initialized[desc->irq_ctrl_id] = false;
|
||||
|
||||
no_os_free(desc->extra);
|
||||
no_os_free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the trigger condition.
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @param irq_id - Not used, pin id is already present in desc.
|
||||
* @param level - the trigger condition.
|
||||
* @return 0 in case of success, errno error codes otherwise
|
||||
*/
|
||||
static int stm32_gpio_irq_trigger_level_set(struct no_os_irq_ctrl_desc
|
||||
*desc,
|
||||
uint32_t irq_id,
|
||||
enum no_os_irq_trig_level level)
|
||||
{
|
||||
int ret;
|
||||
EXTI_ConfigTypeDef config;
|
||||
struct stm32_gpio_irq_desc *sdesc;
|
||||
|
||||
if (!desc || !desc->extra || !IS_EXTI_GPIO_PIN(desc->irq_ctrl_id))
|
||||
return -EINVAL;
|
||||
|
||||
sdesc = desc->extra;
|
||||
|
||||
ret = HAL_EXTI_GetConfigLine(&sdesc->hexti, &config);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
|
||||
switch (level) {
|
||||
case NO_OS_IRQ_EDGE_FALLING:
|
||||
config.Trigger = EXTI_TRIGGER_FALLING;
|
||||
break;
|
||||
case NO_OS_IRQ_EDGE_RISING:
|
||||
config.Trigger = EXTI_TRIGGER_RISING;
|
||||
break;
|
||||
case NO_OS_IRQ_EDGE_BOTH:
|
||||
config.Trigger = EXTI_TRIGGER_RISING_FALLING;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config.GPIOSel = sdesc->port_nb;
|
||||
ret = HAL_EXTI_SetConfigLine(&sdesc->hexti, &config);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a callback function to be triggered when an
|
||||
* interrupt occurs.
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @param irq_id - Not used, pin id is already present in desc.
|
||||
* @param cb - Descriptor of the callback.
|
||||
* @return 0 if successful, negative error code otherwise.
|
||||
*/
|
||||
static int stm32_gpio_irq_register_callback(struct no_os_irq_ctrl_desc
|
||||
*desc,
|
||||
uint32_t irq_id,
|
||||
struct no_os_callback_desc *cb)
|
||||
{
|
||||
int ret;
|
||||
struct irq_action *action;
|
||||
struct irq_action action_key = {.irq_id = desc->irq_ctrl_id};
|
||||
struct stm32_gpio_irq_desc *sdesc;
|
||||
|
||||
if (!desc || !desc->extra || !cb || !IS_EXTI_GPIO_PIN(desc->irq_ctrl_id))
|
||||
return -EINVAL;
|
||||
|
||||
sdesc = desc->extra;
|
||||
|
||||
ret = no_os_list_read_find(actions, (void **)&action, &action_key);
|
||||
/*
|
||||
* If no action was found, insert a new one, otherwise update it
|
||||
*/
|
||||
if (ret) {
|
||||
action = no_os_calloc(1, sizeof(*action));
|
||||
if (!action)
|
||||
return -ENOMEM;
|
||||
|
||||
action->irq_id = desc->irq_ctrl_id;
|
||||
action->ctx = cb->ctx;
|
||||
action->callback = cb->callback;
|
||||
|
||||
ret = no_os_list_add_last(actions, action);
|
||||
if (ret)
|
||||
goto free_action;
|
||||
} else {
|
||||
action->irq_id = desc->irq_ctrl_id;
|
||||
action->ctx = cb->ctx;
|
||||
action->callback = cb->callback;
|
||||
}
|
||||
|
||||
EXTI_ConfigTypeDef config;
|
||||
config.Mode = EXTI_MODE_INTERRUPT;
|
||||
config.GPIOSel = sdesc->port_nb;
|
||||
config.Line = EXTI_GPIO | desc->irq_ctrl_id;
|
||||
ret = HAL_EXTI_SetConfigLine(&sdesc->hexti, &config);
|
||||
if (ret) {
|
||||
ret = -EFAULT;
|
||||
goto free_action;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
free_action:
|
||||
no_os_free(action);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister a callback.
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @param irq_id - Not used, pin id is already present in desc.
|
||||
* @param cb - Descriptor of the callback.
|
||||
* @return 0 if successful, negative error code otherwise.
|
||||
*/
|
||||
static int stm32_gpio_irq_unregister_callback(struct no_os_irq_ctrl_desc
|
||||
*desc,
|
||||
uint32_t irq_id, struct no_os_callback_desc *cb)
|
||||
{
|
||||
int ret;
|
||||
struct irq_action *discard_action = NULL;
|
||||
struct irq_action action_key = {.irq_id = desc->irq_ctrl_id};
|
||||
|
||||
if (!desc || !cb || !IS_EXTI_GPIO_PIN(desc->irq_ctrl_id))
|
||||
return -EINVAL;
|
||||
|
||||
ret = no_os_list_read_find(actions, (void **)&discard_action, &action_key);
|
||||
if (ret)
|
||||
return -ENODEV;
|
||||
|
||||
no_os_free(discard_action);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unused
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @return -ENOSYS
|
||||
*/
|
||||
static int stm32_gpio_irq_global_enable(struct no_os_irq_ctrl_desc *desc)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unused
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @return -ENOSYS
|
||||
*/
|
||||
static int stm32_gpio_irq_global_disable(struct no_os_irq_ctrl_desc *desc)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable a specific gpio interrupt.
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @param irq_id - Not used, pin id is already present in desc.
|
||||
* @return 0 in case of success, -EINVAL otherwise.
|
||||
*/
|
||||
static int stm32_gpio_irq_enable(struct no_os_irq_ctrl_desc *desc,
|
||||
uint32_t irq_id)
|
||||
{
|
||||
IRQn_Type nvic_irq_id;
|
||||
int ret;
|
||||
|
||||
if (!desc || !desc->extra || !IS_EXTI_GPIO_PIN(desc->irq_ctrl_id))
|
||||
return -EINVAL;
|
||||
|
||||
ret = stm32_get_exti_irq_id_from_pin(desc->irq_ctrl_id, &nvic_irq_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
HAL_NVIC_EnableIRQ(nvic_irq_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a specific gpio interrupt.
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @param irq_id - Not used, pin id is already present in desc.
|
||||
* @return 0 in case of success, -EINVAL otherwise.
|
||||
*/
|
||||
static int stm32_gpio_irq_disable(struct no_os_irq_ctrl_desc *desc,
|
||||
uint32_t irq_id)
|
||||
{
|
||||
IRQn_Type nvic_irq_id;
|
||||
int ret;
|
||||
|
||||
if (!desc || !desc->extra || !IS_EXTI_GPIO_PIN(desc->irq_ctrl_id))
|
||||
return -EINVAL;
|
||||
|
||||
ret = stm32_get_exti_irq_id_from_pin(desc->irq_ctrl_id, &nvic_irq_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
HAL_NVIC_DisableIRQ(nvic_irq_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Set the interrupt priority for the current GPIO pin.
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @param irq_id - Not used, pin id is already present in desc.
|
||||
* @param priority_level - The interrupt priority level.
|
||||
* @return 0
|
||||
*/
|
||||
static int stm32_gpio_irq_set_priority(struct no_os_irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
uint32_t priority_level)
|
||||
{
|
||||
IRQn_Type nvic_irq_id;
|
||||
int ret;
|
||||
|
||||
if (!desc || !desc->extra || !IS_EXTI_GPIO_PIN(desc->irq_ctrl_id))
|
||||
return -EINVAL;
|
||||
|
||||
ret = stm32_get_exti_irq_id_from_pin(desc->irq_ctrl_id, &nvic_irq_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
NVIC_SetPriority(nvic_irq_id, priority_level);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Clear the pending interrupt for the current GPIO pin.
|
||||
* @param desc - GPIO interrupt controller descriptor.
|
||||
* @param irq_id - Not used, pin id is already present in desc.
|
||||
* @return 0
|
||||
*/
|
||||
static int stm32_irq_clear_pending(struct no_os_irq_ctrl_desc* desc,
|
||||
uint32_t irq_id)
|
||||
{
|
||||
if (!desc || !desc->extra || !IS_EXTI_GPIO_PIN(desc->irq_ctrl_id))
|
||||
return -EINVAL;
|
||||
|
||||
if (__HAL_GPIO_EXTI_GET_IT(1 << (desc->irq_ctrl_id)))
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(1 << (desc->irq_ctrl_id));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stm32 specific IRQ platform ops structure
|
||||
*/
|
||||
const struct no_os_irq_platform_ops stm32_gpio_irq_ops = {
|
||||
.init = &stm32_gpio_irq_ctrl_init,
|
||||
.trigger_level_set = &stm32_gpio_irq_trigger_level_set,
|
||||
.register_callback = &stm32_gpio_irq_register_callback,
|
||||
.unregister_callback = &stm32_gpio_irq_unregister_callback,
|
||||
.global_enable = &stm32_gpio_irq_global_enable,
|
||||
.global_disable = &stm32_gpio_irq_global_disable,
|
||||
.enable = &stm32_gpio_irq_enable,
|
||||
.disable = &stm32_gpio_irq_disable,
|
||||
.set_priority = &stm32_gpio_irq_set_priority,
|
||||
.remove = &stm32_gpio_irq_ctrl_remove,
|
||||
.clear_pending = &stm32_irq_clear_pending
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_gpio_irq.h
|
||||
* @brief Header file for stm32 gpio irq specifics.
|
||||
* @author Ramona Bolboaca (ramona.bolboaca@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2022(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef STM32_GPIO_IRQ_H
|
||||
#define STM32_GPIO_IRQ_H
|
||||
|
||||
#include "no_os_irq.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
/**
|
||||
* @struct stm32_gpio_irq_init_param
|
||||
* @brief Structure holding the initialization parameters for stm32 platform
|
||||
* specific GPIO IRQ parameters.
|
||||
*/
|
||||
struct stm32_gpio_irq_init_param {
|
||||
uint8_t port_nb;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct stm32_gpio_irq_desc
|
||||
* @brief stm32 platform specific GPIO IRQ descriptor
|
||||
*/
|
||||
struct stm32_gpio_irq_desc {
|
||||
/** EXTI line instance */
|
||||
EXTI_HandleTypeDef hexti;
|
||||
/** Port number */
|
||||
uint8_t port_nb;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief stm32 platform specific irq platform ops structure
|
||||
*/
|
||||
extern const struct no_os_irq_platform_ops stm32_gpio_irq_ops;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _STM32_HAL_H
|
||||
#define _STM32_HAL_H
|
||||
|
||||
#include "main.h"
|
||||
|
||||
int stm32_init(void);
|
||||
int stm32_get_exti_irq_id_from_pin(uint8_t pin_nb, IRQn_Type *irq_id);
|
||||
|
||||
#endif
|
||||
227
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.c
Normal file
227
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_i2c.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_i2c.c
|
||||
* @brief Implementation of stm32 i2c driver.
|
||||
* @author Darius Berghe (darius.berghe@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "no_os_util.h"
|
||||
#include "no_os_alloc.h"
|
||||
#include "no_os_i2c.h"
|
||||
#include "stm32_i2c.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize the I2C communication peripheral.
|
||||
* @param desc - The I2C descriptor.
|
||||
* @param param - The structure that contains the I2C parameters.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_i2c_init(struct no_os_i2c_desc **desc,
|
||||
const struct no_os_i2c_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
struct no_os_i2c_desc *descriptor;
|
||||
struct stm32_i2c_desc *xdesc;
|
||||
struct stm32_i2c_init_param *i2cinit;
|
||||
I2C_TypeDef *base = NULL;
|
||||
|
||||
if (!desc || !param)
|
||||
return -EINVAL;
|
||||
|
||||
descriptor = (struct no_os_i2c_desc *)no_os_calloc(1,
|
||||
sizeof(struct no_os_i2c_desc));
|
||||
if (!descriptor)
|
||||
return -ENOMEM;
|
||||
|
||||
xdesc = (struct stm32_i2c_desc *)no_os_calloc(1, sizeof(struct stm32_i2c_desc));
|
||||
if (!xdesc) {
|
||||
ret = -ENOMEM;
|
||||
goto error_1;
|
||||
}
|
||||
|
||||
i2cinit = param->extra;
|
||||
descriptor->extra = xdesc;
|
||||
|
||||
switch (param->device_id) {
|
||||
#if defined(I2C1)
|
||||
case 1:
|
||||
base = I2C1;
|
||||
break;
|
||||
#endif
|
||||
#if defined(I2C2)
|
||||
case 2:
|
||||
base = I2C2;
|
||||
break;
|
||||
#endif
|
||||
#if defined(I2C3)
|
||||
case 3:
|
||||
base = I2C3;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto error_2;
|
||||
};
|
||||
|
||||
xdesc->hi2c.Instance = base;
|
||||
#if defined (STM32F4) || defined (STM32F1) || defined (STM32F2) || defined (STM32L1)
|
||||
xdesc->hi2c.Init.ClockSpeed = param->max_speed_hz;
|
||||
xdesc->hi2c.Init.DutyCycle = I2C_DUTYCYCLE_2;
|
||||
#else
|
||||
xdesc->hi2c.Init.Timing = i2cinit->i2c_timing;
|
||||
#endif
|
||||
xdesc->hi2c.Init.OwnAddress1 = 0;
|
||||
xdesc->hi2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
xdesc->hi2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
xdesc->hi2c.Init.OwnAddress2 = 0;
|
||||
xdesc->hi2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
xdesc->hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
|
||||
ret = HAL_I2C_Init(&xdesc->hi2c);
|
||||
if (ret != HAL_OK) {
|
||||
ret = -EIO;
|
||||
goto error_2;
|
||||
}
|
||||
|
||||
/* copy settings to device descriptor */
|
||||
descriptor->device_id = param->device_id;
|
||||
descriptor->max_speed_hz = param->max_speed_hz;
|
||||
descriptor->slave_address = param->slave_address;
|
||||
*desc = descriptor;
|
||||
|
||||
return 0;
|
||||
error_2:
|
||||
no_os_free(xdesc);
|
||||
error_1:
|
||||
no_os_free(descriptor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by no_os_i2c_init().
|
||||
* @param desc - The I2C descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_i2c_remove(struct no_os_i2c_desc *desc)
|
||||
{
|
||||
struct stm32_i2c_desc *sdesc;
|
||||
|
||||
if (!desc || !desc->extra)
|
||||
return -EINVAL;
|
||||
|
||||
sdesc = desc->extra;
|
||||
HAL_I2C_DeInit(&sdesc->hi2c);
|
||||
no_os_free(desc->extra);
|
||||
no_os_free(desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C write transaction as master.
|
||||
* @param desc - The I2C descriptor.
|
||||
* @param data - The buffer with the data to transmit.
|
||||
* @param bytes_number - Number of bytes in the buffer.
|
||||
* @param stop_bit - Specifis whether to end the transaction with a stop bit.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
int32_t stm32_i2c_write(struct no_os_i2c_desc *desc,
|
||||
uint8_t *data,
|
||||
uint8_t bytes_number,
|
||||
uint8_t stop_bit)
|
||||
{
|
||||
int ret;
|
||||
struct stm32_i2c_desc *xdesc;
|
||||
|
||||
if (!desc || !desc->extra || !data)
|
||||
return -EINVAL;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
if (!stop_bit) {
|
||||
ret = HAL_I2C_Master_Seq_Transmit_IT(&xdesc->hi2c, desc->slave_address << 1,
|
||||
data,
|
||||
bytes_number, I2C_FIRST_FRAME);
|
||||
} else {
|
||||
ret = HAL_I2C_Master_Transmit(&xdesc->hi2c, desc->slave_address << 1, data,
|
||||
bytes_number, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
if (ret != HAL_OK)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C read transaction as master.
|
||||
* @param desc - The I2C descriptor.
|
||||
* @param data - The buffer where received data is to be stored.
|
||||
* @param bytes_number - Number of bytes to receive.
|
||||
* @param stop_bit - Specifis whether to end the transaction with a stop bit.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
|
||||
int32_t stm32_i2c_read(struct no_os_i2c_desc *desc,
|
||||
uint8_t *data,
|
||||
uint8_t bytes_number,
|
||||
uint8_t stop_bit)
|
||||
{
|
||||
int ret;
|
||||
struct stm32_i2c_desc *xdesc;
|
||||
|
||||
if (!desc || !desc->extra || !data)
|
||||
return -EINVAL;
|
||||
|
||||
xdesc = desc->extra;
|
||||
|
||||
if (!stop_bit) {
|
||||
ret = HAL_I2C_Master_Seq_Receive_IT(&xdesc->hi2c, desc->slave_address << 1,
|
||||
data,
|
||||
bytes_number, I2C_LAST_FRAME);
|
||||
} else {
|
||||
ret = HAL_I2C_Master_Receive(&xdesc->hi2c, desc->slave_address << 1, data,
|
||||
bytes_number, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
if (ret != HAL_OK)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stm32 platform specific I2C platform ops structure
|
||||
*/
|
||||
const struct no_os_i2c_platform_ops stm32_i2c_ops = {
|
||||
.i2c_ops_init = &stm32_i2c_init,
|
||||
.i2c_ops_write = &stm32_i2c_write,
|
||||
.i2c_ops_read = &stm32_i2c_read,
|
||||
.i2c_ops_remove = &stm32_i2c_remove
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_i2c.h
|
||||
* @brief Header file for the stm32 i2c driver.
|
||||
* @author Darius Berghe (darius.berghe@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2021(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef STM32_I2C_H_
|
||||
#define STM32_I2C_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "no_os_i2c.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
/**
|
||||
* @struct stm32_i2c_desc
|
||||
* @brief stm32 platform specific I2C descriptor
|
||||
*/
|
||||
struct stm32_i2c_desc {
|
||||
/** I2C instance */
|
||||
I2C_HandleTypeDef hi2c;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct stm32_i2c_init_param
|
||||
* @brief Structure holding the initialization parameters for stm32 platform
|
||||
* specific I2C parameters.
|
||||
*/
|
||||
struct stm32_i2c_init_param {
|
||||
/** I2C Timing */
|
||||
uint32_t i2c_timing;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief stm32 specific I2C platform ops structure
|
||||
*/
|
||||
extern const struct no_os_i2c_platform_ops stm32_i2c_ops;
|
||||
|
||||
#endif // STM32_I2C_H_
|
||||
701
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.c
Normal file
701
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_irq.c
Normal file
@@ -0,0 +1,701 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_irq.c
|
||||
* @brief Implementation of external irq driver.
|
||||
* @author Darius Berghe (darius.berghe@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2022(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "main.h"
|
||||
#include "no_os_list.h"
|
||||
#include "no_os_irq.h"
|
||||
#include "no_os_util.h"
|
||||
#include "no_os_alloc.h"
|
||||
#include "stm32_irq.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "stm32f7xx_hal.h"
|
||||
#include "stm32f7xx_hal_uart.h"
|
||||
#include "stm32f7xx_hal_conf.h"
|
||||
#include "stm32f7xx_hal_def.h"
|
||||
#include "stm32f7xx_hal_tim.h"
|
||||
|
||||
struct irq_action {
|
||||
void *handle;
|
||||
void (*callback)(void *context);
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
struct event_list {
|
||||
enum no_os_irq_event event;
|
||||
uint32_t hal_event;
|
||||
struct no_os_list_desc *actions;
|
||||
};
|
||||
|
||||
static bool initialized = false;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_UART_TX_HALFCOMPLETE_CB_ID = 0x00U, /*!< UART Tx Half Complete Callback ID */
|
||||
HAL_UART_TX_COMPLETE_CB_ID = 0x01U, /*!< UART Tx Complete Callback ID */
|
||||
HAL_UART_RX_HALFCOMPLETE_CB_ID = 0x02U, /*!< UART Rx Half Complete Callback ID */
|
||||
HAL_UART_RX_COMPLETE_CB_ID = 0x03U, /*!< UART Rx Complete Callback ID */
|
||||
HAL_UART_ERROR_CB_ID = 0x04U, /*!< UART Error Callback ID */
|
||||
HAL_UART_ABORT_COMPLETE_CB_ID = 0x05U, /*!< UART Abort Complete Callback ID */
|
||||
HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x06U, /*!< UART Abort Transmit Complete Callback ID */
|
||||
HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID = 0x07U, /*!< UART Abort Receive Complete Callback ID */
|
||||
HAL_UART_WAKEUP_CB_ID = 0x08U, /*!< UART Wakeup Callback ID */
|
||||
|
||||
HAL_UART_MSPINIT_CB_ID = 0x0BU, /*!< UART MspInit callback ID */
|
||||
HAL_UART_MSPDEINIT_CB_ID = 0x0CU /*!< UART MspDeInit callback ID */
|
||||
|
||||
} HAL_UART_CallbackIDTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HAL_TIM_BASE_MSPINIT_CB_ID = 0x00U /*!< TIM Base MspInit Callback ID */
|
||||
, HAL_TIM_BASE_MSPDEINIT_CB_ID = 0x01U /*!< TIM Base MspDeInit Callback ID */
|
||||
, HAL_TIM_IC_MSPINIT_CB_ID = 0x02U /*!< TIM IC MspInit Callback ID */
|
||||
, HAL_TIM_IC_MSPDEINIT_CB_ID = 0x03U /*!< TIM IC MspDeInit Callback ID */
|
||||
, HAL_TIM_OC_MSPINIT_CB_ID = 0x04U /*!< TIM OC MspInit Callback ID */
|
||||
, HAL_TIM_OC_MSPDEINIT_CB_ID = 0x05U /*!< TIM OC MspDeInit Callback ID */
|
||||
, HAL_TIM_PWM_MSPINIT_CB_ID = 0x06U /*!< TIM PWM MspInit Callback ID */
|
||||
, HAL_TIM_PWM_MSPDEINIT_CB_ID = 0x07U /*!< TIM PWM MspDeInit Callback ID */
|
||||
, HAL_TIM_ONE_PULSE_MSPINIT_CB_ID = 0x08U /*!< TIM One Pulse MspInit Callback ID */
|
||||
, HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID = 0x09U /*!< TIM One Pulse MspDeInit Callback ID */
|
||||
, HAL_TIM_ENCODER_MSPINIT_CB_ID = 0x0AU /*!< TIM Encoder MspInit Callback ID */
|
||||
, HAL_TIM_ENCODER_MSPDEINIT_CB_ID = 0x0BU /*!< TIM Encoder MspDeInit Callback ID */
|
||||
, HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID = 0x0CU /*!< TIM Hall Sensor MspDeInit Callback ID */
|
||||
, HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID = 0x0DU /*!< TIM Hall Sensor MspDeInit Callback ID */
|
||||
, HAL_TIM_PERIOD_ELAPSED_CB_ID = 0x0EU /*!< TIM Period Elapsed Callback ID */
|
||||
, HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID = 0x0FU /*!< TIM Period Elapsed half complete Callback ID */
|
||||
, HAL_TIM_TRIGGER_CB_ID = 0x10U /*!< TIM Trigger Callback ID */
|
||||
, HAL_TIM_TRIGGER_HALF_CB_ID = 0x11U /*!< TIM Trigger half complete Callback ID */
|
||||
, HAL_TIM_IC_CAPTURE_CB_ID = 0x12U /*!< TIM Input Capture Callback ID */
|
||||
, HAL_TIM_IC_CAPTURE_HALF_CB_ID = 0x13U /*!< TIM Input Capture half complete Callback ID */
|
||||
, HAL_TIM_OC_DELAY_ELAPSED_CB_ID = 0x14U /*!< TIM Output Compare Delay Elapsed Callback ID */
|
||||
, HAL_TIM_PWM_PULSE_FINISHED_CB_ID = 0x15U /*!< TIM PWM Pulse Finished Callback ID */
|
||||
, HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID = 0x16U /*!< TIM PWM Pulse Finished half complete Callback ID */
|
||||
, HAL_TIM_ERROR_CB_ID = 0x17U /*!< TIM Error Callback ID */
|
||||
, HAL_TIM_COMMUTATION_CB_ID = 0x18U /*!< TIM Commutation Callback ID */
|
||||
, HAL_TIM_COMMUTATION_HALF_CB_ID = 0x19U /*!< TIM Commutation half complete Callback ID */
|
||||
, HAL_TIM_BREAK_CB_ID = 0x1AU /*!< TIM Break Callback ID */
|
||||
, HAL_TIM_BREAK2_CB_ID = 0x1BU /*!< TIM Break2 Callback ID */
|
||||
} HAL_TIM_CallbackIDTypeDef;
|
||||
|
||||
static struct event_list _events[] = {
|
||||
[NO_OS_EVT_GPIO] = {.event = NO_OS_EVT_GPIO, .hal_event = HAL_EXTI_COMMON_CB_ID},
|
||||
[NO_OS_EVT_UART_TX_COMPLETE] = {.event = NO_OS_EVT_UART_TX_COMPLETE, .hal_event = HAL_UART_TX_COMPLETE_CB_ID},
|
||||
[NO_OS_EVT_UART_RX_COMPLETE] = {.event = NO_OS_EVT_UART_RX_COMPLETE, .hal_event = HAL_UART_RX_COMPLETE_CB_ID},
|
||||
[NO_OS_EVT_UART_ERROR] = {.event = NO_OS_EVT_UART_ERROR, .hal_event = HAL_UART_ERROR_CB_ID},
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
[NO_OS_EVT_TIM_ELAPSED] = {.event = NO_OS_EVT_TIM_ELAPSED, .hal_event = HAL_TIM_PERIOD_ELAPSED_CB_ID},
|
||||
[NO_OS_EVT_TIM_PWM_PULSE_FINISHED] = {.event = NO_OS_EVT_TIM_PWM_PULSE_FINISHED, .hal_event = HAL_TIM_PWM_PULSE_FINISHED_CB_ID},
|
||||
#endif
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
[NO_OS_EVT_LPTIM_PWM_PULSE_FINISHED] = {.event = NO_OS_EVT_LPTIM_PWM_PULSE_FINISHED, .hal_event = HAL_LPTIM_COMPARE_MATCH_CB_ID},
|
||||
#endif
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
[NO_OS_EVT_DMA_RX_COMPLETE] = {.event = NO_OS_EVT_DMA_RX_COMPLETE, .hal_event = HAL_DMA_XFER_CPLT_CB_ID},
|
||||
[NO_OS_EVT_DMA_RX_HALF_COMPLETE] = {.event = NO_OS_EVT_DMA_RX_HALF_COMPLETE, .hal_event = HAL_DMA_XFER_HALFCPLT_CB_ID},
|
||||
[NO_OS_EVT_DMA_TX_COMPLETE] = {.event = NO_OS_EVT_DMA_TX_COMPLETE, .hal_event = HAL_DMA_XFER_CPLT_CB_ID},
|
||||
#endif
|
||||
};
|
||||
|
||||
static int32_t irq_action_cmp(void *data1, void *data2)
|
||||
{
|
||||
return (int32_t)((struct irq_action *)data1)->handle -
|
||||
(int32_t)((struct irq_action *)data2)->handle;
|
||||
}
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
struct event_list *ee = &_events[NO_OS_EVT_TIM_ELAPSED];
|
||||
struct irq_action *a;
|
||||
struct irq_action key = {.handle = htim};
|
||||
int ret;
|
||||
|
||||
/* Find & call callback */
|
||||
ret = no_os_list_read_find(ee->actions, (void **)&a, &key);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (a->callback)
|
||||
a->callback(a->ctx);
|
||||
}
|
||||
|
||||
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
struct event_list *ee = &_events[NO_OS_EVT_TIM_PWM_PULSE_FINISHED];
|
||||
struct irq_action *a;
|
||||
struct irq_action key = {.handle = htim};
|
||||
int ret;
|
||||
|
||||
/* Find & call callback */
|
||||
ret = no_os_list_read_find(ee->actions, (void **)&a, &key);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (a->callback)
|
||||
a->callback(a->ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
struct event_list *ee = &_events[NO_OS_EVT_LPTIM_PWM_PULSE_FINISHED];
|
||||
struct irq_action *a;
|
||||
struct irq_action key = {.handle = hlptim};
|
||||
int ret;
|
||||
|
||||
/* Find & call callback */
|
||||
ret = no_os_list_read_find(ee->actions, (void **)&a, &key);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (a->callback)
|
||||
a->callback(a->ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void _common_uart_callback(UART_HandleTypeDef *huart,
|
||||
uint32_t no_os_event)
|
||||
{
|
||||
struct event_list *ue = &_events[no_os_event];
|
||||
struct irq_action *a;
|
||||
struct irq_action key = {.handle = huart};
|
||||
int ret;
|
||||
ret = no_os_list_read_find(ue->actions, (void **)&a, &key);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (a->callback)
|
||||
a->callback(a->ctx);
|
||||
}
|
||||
|
||||
#if defined (HAL_SAI_MODULE_ENABLED)
|
||||
static inline void _common_sai_dma_callback(SAI_HandleTypeDef *hsai,
|
||||
uint32_t no_os_event)
|
||||
{
|
||||
struct event_list *ue = &_events[no_os_event];
|
||||
struct irq_action *a;
|
||||
struct irq_action key = {.handle = hsai};
|
||||
int ret;
|
||||
ret = no_os_list_read_find(ue->actions, (void **)&a, &key);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (a->callback)
|
||||
a->callback(a->ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (HAL_DMA_MODULE_ENABLED)
|
||||
static inline void _common_dma_callback(DMA_HandleTypeDef *hdma,
|
||||
uint32_t no_os_event)
|
||||
{
|
||||
struct event_list *ue = &_events[no_os_event];
|
||||
struct irq_action *a;
|
||||
struct irq_action key = {.handle = hdma};
|
||||
int ret;
|
||||
ret = no_os_list_read_find(ue->actions, (void **)&a, &key);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (a->callback)
|
||||
a->callback(a->ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
// equivalent of HAL_UART_TxCpltCallback
|
||||
void _TxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
_common_uart_callback(huart, NO_OS_EVT_UART_TX_COMPLETE);
|
||||
}
|
||||
|
||||
// equivalent of HAL_UART_RxCpltCallback
|
||||
void _RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
_common_uart_callback(huart, NO_OS_EVT_UART_RX_COMPLETE);
|
||||
}
|
||||
|
||||
#if defined (HAL_SAI_MODULE_ENABLED)
|
||||
void _SAIRxCpltCallback(SAI_HandleTypeDef *hsai)
|
||||
{
|
||||
_common_sai_dma_callback(hsai, NO_OS_EVT_DMA_RX_COMPLETE);
|
||||
}
|
||||
|
||||
void _SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
|
||||
{
|
||||
_common_sai_dma_callback(hsai, NO_OS_EVT_DMA_RX_HALF_COMPLETE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (HAL_DMA_MODULE_ENABLED)
|
||||
void _DMA_RX_CpltCallback(DMA_HandleTypeDef* hdma)
|
||||
{
|
||||
_common_dma_callback(hdma, NO_OS_EVT_DMA_RX_COMPLETE);
|
||||
}
|
||||
|
||||
void _DMA_TX_CpltCallback(DMA_HandleTypeDef* hdma)
|
||||
{
|
||||
_common_dma_callback(hdma, NO_OS_EVT_DMA_TX_COMPLETE);
|
||||
}
|
||||
|
||||
void _DMA_HalfCpltCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
_common_dma_callback(hdma, NO_OS_EVT_DMA_RX_HALF_COMPLETE);
|
||||
}
|
||||
#endif
|
||||
|
||||
// equivalent of HAL_UART_ErrorCallback
|
||||
void _ErrorCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
_common_uart_callback(huart, NO_OS_EVT_UART_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialized the controller for the STM32 external interrupts
|
||||
* @param desc - Pointer where the configured instance is stored
|
||||
* @param param - Configuration information for the instance
|
||||
* @return 0 in case of success, errno error codes otherwise.
|
||||
*/
|
||||
int stm32_irq_ctrl_init(struct no_os_irq_ctrl_desc **desc,
|
||||
const struct no_os_irq_init_param *param)
|
||||
{
|
||||
static struct no_os_irq_ctrl_desc *descriptor;
|
||||
if (!param)
|
||||
return -EINVAL;
|
||||
|
||||
if (!initialized) {
|
||||
descriptor = no_os_calloc(1, sizeof(*descriptor));
|
||||
if (!descriptor)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
// unused, there is only 1 interrupt controller and that is NVIC
|
||||
descriptor->irq_ctrl_id = param->irq_ctrl_id;
|
||||
descriptor->extra = param->extra;
|
||||
|
||||
*desc = descriptor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by irq_ctrl_init()
|
||||
* @param desc - Interrupt controller descriptor.
|
||||
* @return 0 in case of success, errno error codes otherwise.
|
||||
*/
|
||||
int stm32_irq_ctrl_remove(struct no_os_irq_ctrl_desc *desc)
|
||||
{
|
||||
initialized = false;
|
||||
|
||||
if (desc)
|
||||
no_os_free(desc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unused.
|
||||
* @param desc -irq descriptor.
|
||||
* @param irq_id - The interrupt vector entry id of the peripheral.
|
||||
* @param level - the trigger condition.
|
||||
* @return -ENOSYS
|
||||
*/
|
||||
int stm32_trigger_level_set(struct no_os_irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
enum no_os_irq_trig_level level)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a callback.
|
||||
* @param desc - The IRQ controller descriptor.
|
||||
* @param irq_id - Interrupt identifier.
|
||||
* @param cb - Descriptor of the callback.
|
||||
* @return 0 if successfull, negative error code otherwise.
|
||||
*/
|
||||
typedef void (*pUART_CallbackTypeDef)(UART_HandleTypeDef *huart); /*!< pointer to an UART callback function */
|
||||
typedef void (*pTIM_CallbackTypeDef)(TIM_HandleTypeDef *htim); /*!< pointer to the TIM callback function */
|
||||
int stm32_irq_register_callback(struct no_os_irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
struct no_os_callback_desc *cb)
|
||||
{
|
||||
int ret;
|
||||
pUART_CallbackTypeDef pUartCallback;
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
pSAI_CallbackTypeDef pSaiDmaCallback;
|
||||
#endif
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
pTIM_CallbackTypeDef pTimCallback;
|
||||
#endif
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
pLPTIM_CallbackTypeDef pLPTimCallback;
|
||||
#endif
|
||||
struct irq_action action_key = {.handle = cb->handle};
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
DMA_HandleTypeDef pDmaCallback;
|
||||
#endif
|
||||
struct irq_action *li;
|
||||
uint32_t hal_event = _events[cb->event].hal_event;
|
||||
|
||||
switch (cb->peripheral) {
|
||||
case NO_OS_UART_IRQ:
|
||||
switch (hal_event) {
|
||||
case HAL_UART_TX_COMPLETE_CB_ID:
|
||||
pUartCallback = _TxCpltCallback;
|
||||
break;
|
||||
case HAL_UART_RX_COMPLETE_CB_ID:
|
||||
pUartCallback = _RxCpltCallback;
|
||||
break;
|
||||
case HAL_UART_ERROR_CB_ID:
|
||||
pUartCallback = _ErrorCallback;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
ret = HAL_UART_RegisterCallback(cb->handle, hal_event, pUartCallback);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
|
||||
break;
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
case NO_OS_LPTIM_IRQ:
|
||||
switch (hal_event) {
|
||||
case HAL_LPTIM_COMPARE_MATCH_CB_ID:
|
||||
pLPTimCallback = HAL_LPTIM_CompareMatchCallback;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
ret = HAL_LPTIM_RegisterCallback(cb->handle, hal_event, pLPTimCallback);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
case NO_OS_TIM_IRQ:
|
||||
switch (hal_event) {
|
||||
case HAL_TIM_PWM_PULSE_FINISHED_CB_ID:
|
||||
pTimCallback = HAL_TIM_PWM_PulseFinishedCallback;
|
||||
break;
|
||||
case HAL_TIM_PERIOD_ELAPSED_CB_ID:
|
||||
pTimCallback = HAL_TIM_PeriodElapsedCallback;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
ret = HAL_TIM_RegisterCallback(cb->handle, hal_event, pTimCallback);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
break;
|
||||
#endif
|
||||
#if defined(HAL_DMA_MODULE_ENABLED) && defined(HAL_SAI_MODULE_ENABLED)
|
||||
case NO_OS_TDM_DMA_IRQ:
|
||||
switch (hal_event) {
|
||||
case HAL_DMA_XFER_CPLT_CB_ID:
|
||||
pSaiDmaCallback = _SAIRxCpltCallback;
|
||||
ret = HAL_SAI_RegisterCallback(cb->handle, hal_event, pSaiDmaCallback);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
|
||||
break;
|
||||
case HAL_DMA_XFER_HALFCPLT_CB_ID:
|
||||
pSaiDmaCallback = _SAI_RxHalfCpltCallback;
|
||||
ret = HAL_SAI_RegisterCallback(cb->handle, hal_event, pSaiDmaCallback);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined (HAL_TIM_MODULE_ENABLED) && defined(HAL_DMA_MODULE_ENABLED)
|
||||
case NO_OS_TIM_DMA_IRQ:
|
||||
switch (hal_event) {
|
||||
case HAL_DMA_XFER_CPLT_CB_ID:
|
||||
pDmaCallback.XferCpltCallback = _DMA_RX_CpltCallback;
|
||||
ret = HAL_DMA_RegisterCallback(cb->handle, hal_event,
|
||||
pDmaCallback.XferCpltCallback);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
break;
|
||||
case HAL_DMA_XFER_HALFCPLT_CB_ID:
|
||||
pDmaCallback.XferHalfCpltCallback = _DMA_HalfCpltCallback;
|
||||
ret = HAL_DMA_RegisterCallback(cb->handle, hal_event,
|
||||
pDmaCallback.XferHalfCpltCallback);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
break;
|
||||
#endif
|
||||
#if defined (HAL_DMA_MODULE_ENABLED)
|
||||
case NO_OS_DMA_IRQ:
|
||||
switch (hal_event) {
|
||||
case HAL_DMA_XFER_CPLT_CB_ID:
|
||||
if (cb->event == NO_OS_EVT_DMA_RX_COMPLETE)
|
||||
pDmaCallback.XferCpltCallback = _DMA_RX_CpltCallback;
|
||||
|
||||
else
|
||||
pDmaCallback.XferCpltCallback = _DMA_TX_CpltCallback;
|
||||
|
||||
ret = HAL_DMA_RegisterCallback((DMA_HandleTypeDef *)cb->handle, hal_event,
|
||||
pDmaCallback.XferCpltCallback);
|
||||
if (ret != HAL_OK)
|
||||
return -EFAULT;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (_events[cb->event].actions == NULL) {
|
||||
ret = no_os_list_init(&_events[cb->event].actions, NO_OS_LIST_PRIORITY_LIST,
|
||||
irq_action_cmp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* If an action with the same handle as the function parameter does not exists, insert a new one,
|
||||
* otherwise update
|
||||
*/
|
||||
ret = no_os_list_read_find(_events[cb->event].actions,
|
||||
(void**)&li,
|
||||
&action_key);
|
||||
if (ret) {
|
||||
li = no_os_calloc(1, sizeof(struct irq_action));
|
||||
if (!li)
|
||||
return -ENOMEM;
|
||||
|
||||
li->handle = cb->handle;
|
||||
li->callback = cb->callback;
|
||||
li->ctx = cb->ctx;
|
||||
ret = no_os_list_add_last(_events[cb->event].actions, li);
|
||||
if (ret < 0) {
|
||||
no_os_free(li);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
li->handle = cb->handle;
|
||||
li->callback = cb->callback;
|
||||
li->ctx = cb->ctx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister a callback.
|
||||
* @param desc - Interrupt controller descriptor.
|
||||
* @param irq_id - Id of the interrupt
|
||||
* @param cb - Descriptor of the callback.
|
||||
* @return 0 if successfull, negative error code otherwise.
|
||||
*/
|
||||
int stm32_irq_unregister_callback(struct no_os_irq_ctrl_desc *desc,
|
||||
uint32_t irq_id, struct no_os_callback_desc *cb)
|
||||
{
|
||||
int ret;
|
||||
void *discard = NULL;
|
||||
struct irq_action key;
|
||||
uint32_t hal_event = _events[cb->event].hal_event;
|
||||
|
||||
switch (cb->peripheral) {
|
||||
case NO_OS_UART_IRQ:
|
||||
key.handle = cb->handle;
|
||||
ret = no_os_list_get_find(_events[cb->event].actions, &discard, &key);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = HAL_UART_UnRegisterCallback(cb->handle, hal_event);
|
||||
if (ret != HAL_OK)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
case NO_OS_TIM_IRQ:
|
||||
key.handle = cb->handle;
|
||||
ret = no_os_list_get_find(_events[cb->event].actions, &discard, &key);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = HAL_TIM_UnRegisterCallback(cb->handle, hal_event);
|
||||
if (ret != HAL_OK)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
#endif
|
||||
#if defined(HAL_DMA_MODULE_ENABLED) && defined(HAL_SAI_MODULE_ENABLED)
|
||||
case NO_OS_TDM_DMA_IRQ:
|
||||
key.handle = cb->handle;
|
||||
ret = no_os_list_get_find(_events[cb->event].actions, &discard, &key);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = HAL_SAI_UnRegisterCallback(cb->handle, hal_event);
|
||||
if (ret != HAL_OK)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
#endif
|
||||
#if defined (HAL_TIM_MODULE_ENABLED) && defined(HAL_DMA_MODULE_ENABLED)
|
||||
case NO_OS_TIM_DMA_IRQ:
|
||||
case NO_OS_DMA_IRQ:
|
||||
key.handle = cb->handle;
|
||||
ret = no_os_list_get_find(_events[cb->event].actions, &discard, &key);
|
||||
if (ret < 0)
|
||||
break;
|
||||
ret = HAL_DMA_UnRegisterCallback(cb->handle, hal_event);
|
||||
if (ret != HAL_OK)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (discard)
|
||||
no_os_free(discard);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all interrupts
|
||||
* @param desc - Interrupt controller descriptor.
|
||||
* @return 0
|
||||
*/
|
||||
int stm32_irq_global_enable(struct no_os_irq_ctrl_desc *desc)
|
||||
{
|
||||
__enable_irq();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all interrupts
|
||||
* @param desc - Interrupt controller descriptor.
|
||||
* @return 0
|
||||
*/
|
||||
int stm32_irq_global_disable(struct no_os_irq_ctrl_desc *desc)
|
||||
{
|
||||
__disable_irq();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable a specific interrupt
|
||||
* @param desc - Interrupt controller descriptor.
|
||||
* @param irq_id - Interrupt identifier
|
||||
* @return 0 in case of success, errno error codes otherwise.
|
||||
*/
|
||||
int stm32_irq_enable(struct no_os_irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
NVIC_EnableIRQ(irq_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a specific interrupt
|
||||
* @param desc - Interrupt controller descriptor.
|
||||
* @param irq_id - Interrupt identifier
|
||||
* @return 0 in case of success, -EINVAL otherwise.
|
||||
*/
|
||||
int stm32_irq_disable(struct no_os_irq_ctrl_desc *desc, uint32_t irq_id)
|
||||
{
|
||||
NVIC_DisableIRQ(irq_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set a priority level for an interrupt
|
||||
* @param desc - Interrupt controller descriptor.
|
||||
* @param irq_id - The interrupt vector entry id of the peripheral.
|
||||
* @param priority_level - The interrupt priority level
|
||||
* @return 0
|
||||
*/
|
||||
static int stm32_irq_set_priority(struct no_os_irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
uint32_t priority_level)
|
||||
{
|
||||
HAL_NVIC_SetPriority(irq_id, priority_level, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a priority level for an interrupt
|
||||
* @param desc - Interrupt controller descriptor.
|
||||
* @param irq_id - The interrupt vector entry id of the peripheral.
|
||||
* @param priority_level - The interrupt priority level
|
||||
* @return 0
|
||||
*/
|
||||
static int stm32_irq_get_priority(struct no_os_irq_ctrl_desc *desc,
|
||||
uint32_t irq_id,
|
||||
uint32_t *priority_level)
|
||||
{
|
||||
uint32_t priority_group, sub_priority;
|
||||
priority_group = HAL_NVIC_GetPriorityGrouping();
|
||||
HAL_NVIC_GetPriority(irq_id, priority_group, priority_level, &sub_priority);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stm32 specific IRQ platform ops structure
|
||||
*/
|
||||
const struct no_os_irq_platform_ops stm32_irq_ops = {
|
||||
.init = &stm32_irq_ctrl_init,
|
||||
.trigger_level_set = &stm32_trigger_level_set,
|
||||
.register_callback = &stm32_irq_register_callback,
|
||||
.unregister_callback = &stm32_irq_unregister_callback,
|
||||
.global_enable = &stm32_irq_global_enable,
|
||||
.global_disable = &stm32_irq_global_disable,
|
||||
.enable = &stm32_irq_enable,
|
||||
.disable = &stm32_irq_disable,
|
||||
.set_priority = &stm32_irq_set_priority,
|
||||
.get_priority = &stm32_irq_get_priority,
|
||||
.remove = &stm32_irq_ctrl_remove
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_irq.h
|
||||
* @brief Header file for stm32 irq specifics.
|
||||
* @author Darius Berghe (darius.berghe@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2022(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef STM32_IRQ_H
|
||||
#define STM32_IRQ_H
|
||||
|
||||
#include "no_os_irq.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
/**
|
||||
* @brief stm32 platform specific irq platform ops structure
|
||||
*/
|
||||
extern const struct no_os_irq_platform_ops stm32_irq_ops;
|
||||
|
||||
#endif
|
||||
1114
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.c
Normal file
1114
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.c
Normal file
File diff suppressed because it is too large
Load Diff
151
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.h
Normal file
151
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/stm32_pwm.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_pwm.h
|
||||
* @brief Header file for stm32 pwm specifics.
|
||||
********************************************************************************
|
||||
* Copyright 2023(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef STM32_PWM_H_
|
||||
#define STM32_PWM_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "no_os_gpio.h"
|
||||
#include "no_os_irq.h"
|
||||
#include "stm32_gpio.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
enum stm32_pwm_timer {
|
||||
STM32_PWM_TIMER_TIM = 0,
|
||||
STM32_PWM_TIMER_LPTIM = 1,
|
||||
};
|
||||
|
||||
enum TimOCMode {
|
||||
TIM_OC_TOGGLE = 0,
|
||||
TIM_OC_PWM1 = 1,
|
||||
TIM_OC_PWM2 = 2,
|
||||
};
|
||||
|
||||
enum stm32_pwm_trigger {
|
||||
PWM_TS_ITR0,
|
||||
PWM_TS_ITR1,
|
||||
PWM_TS_ITR2,
|
||||
PWM_TS_ITR3,
|
||||
};
|
||||
|
||||
enum stm32_pwm_trigger_out {
|
||||
PWM_TRGO_RESET,
|
||||
PWM_TRGO_ENABLE,
|
||||
PWM_TRGO_UPDATE,
|
||||
PWM_TRGO_OC1,
|
||||
PWM_TRGO_OC1REF,
|
||||
PWM_TRGO_OC2REF,
|
||||
PWM_TRGO_OC3REF,
|
||||
PWM_TRGO_OC4REF,
|
||||
};
|
||||
/**
|
||||
* @struct stm32_pwm_init_param
|
||||
* @brief Structure holding the STM32 PWM parameters.
|
||||
*/
|
||||
struct stm32_pwm_init_param {
|
||||
/** PWM Timer Handle */
|
||||
void *htimer;
|
||||
/** Type of timer used for PWM */
|
||||
enum stm32_pwm_timer pwm_timer;
|
||||
/** Timer prescaler (0 to 0xFFFF) */
|
||||
uint32_t prescaler;
|
||||
/** Timer autoreload enable */
|
||||
bool timer_autoreload;
|
||||
/** Timer output compare Mode */
|
||||
enum TimOCMode mode;
|
||||
/** PWM timer channel */
|
||||
uint32_t timer_chn;
|
||||
/** Complementary channel */
|
||||
bool complementary_channel;
|
||||
/** Get timer source clock function */
|
||||
uint32_t (*get_timer_clock)(void);
|
||||
/** Get timer source clock divider */
|
||||
uint32_t clock_divider;
|
||||
/** Enable trigger source */
|
||||
bool trigger_enable;
|
||||
/** Trigger source selection */
|
||||
enum stm32_pwm_trigger trigger_source;
|
||||
/** Trigger out selection */
|
||||
enum stm32_pwm_trigger_out trigger_output;
|
||||
/* Enable one pulse */
|
||||
bool onepulse_enable;
|
||||
/* Number of pulse repetitions */
|
||||
uint32_t repetitions;
|
||||
/* Enable dma */
|
||||
bool dma_enable;
|
||||
/** Timer callback */
|
||||
struct no_os_callback_desc timer_callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct stm32_pwm_desc
|
||||
* @brief Structure holding the STM32 PWM descriptor.
|
||||
*/
|
||||
struct stm32_pwm_desc {
|
||||
/** PWM Timer Handle */
|
||||
void *htimer;
|
||||
/** Type of timer used for PWM */
|
||||
enum stm32_pwm_timer pwm_timer;
|
||||
/** Timer GPIO instance */
|
||||
struct no_os_gpio_desc *gpio;
|
||||
/** Timer prescaler */
|
||||
uint32_t prescaler;
|
||||
/** Timer autoreload enable */
|
||||
bool timer_autoreload;
|
||||
/** Timer output compare Mode */
|
||||
enum TimOCMode mode;
|
||||
/** PWM timer channel */
|
||||
uint32_t timer_chn;
|
||||
/** Complementary channel */
|
||||
bool complementary_channel;
|
||||
/** Get timer source clock function */
|
||||
uint32_t (*get_timer_clock)(void);
|
||||
/** Get timer source clock divider */
|
||||
uint32_t clock_divider;
|
||||
/** Interrupt controller descriptor */
|
||||
struct no_os_irq_ctrl_desc *nvic_tim;
|
||||
/** Timer callback */
|
||||
struct no_os_callback_desc timer_callback;
|
||||
/* Number of pulse repetitions */
|
||||
uint32_t repetitions;
|
||||
/* Enable dma */
|
||||
bool dma_enable;
|
||||
/* Enable one pulse */
|
||||
bool onepulse_enable;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief STM32 specific PWM platform ops structure
|
||||
*/
|
||||
extern const struct no_os_pwm_platform_ops stm32_pwm_ops;
|
||||
|
||||
#endif // STM32_PWM_H_
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "stm32_spi.h"
|
||||
#include "no_os_error.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int32_t stm32_spi_init(struct no_os_spi_desc **desc,
|
||||
const struct no_os_spi_init_param *param)
|
||||
{
|
||||
if (!desc || !param)
|
||||
return -EINVAL;
|
||||
|
||||
*desc = calloc(1, sizeof(**desc));
|
||||
if (!*desc)
|
||||
return -ENOMEM;
|
||||
|
||||
/* store platform handle (HAL SPI_HandleTypeDef*) in extra */
|
||||
(*desc)->extra = param->extra;
|
||||
(*desc)->max_speed_hz = param->max_speed_hz;
|
||||
(*desc)->mode = param->mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t stm32_spi_write_and_read(struct no_os_spi_desc *desc,
|
||||
uint8_t *data,
|
||||
uint32_t bytes_number)
|
||||
{
|
||||
if (!desc || !data || bytes_number == 0)
|
||||
return -EINVAL;
|
||||
|
||||
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)desc->extra;
|
||||
if (!hspi)
|
||||
return -EINVAL;
|
||||
|
||||
if (HAL_SPI_TransmitReceive(hspi, data, data, bytes_number, 200) != HAL_OK)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t stm32_spi_remove(struct no_os_spi_desc *desc)
|
||||
{
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
free(desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* platform ops struct */
|
||||
const struct no_os_spi_platform_ops stm32_spi_ops = {
|
||||
.init = &stm32_spi_init,
|
||||
.write_and_read = &stm32_spi_write_and_read,
|
||||
.remove = &stm32_spi_remove,
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _STM32_SPI_H_
|
||||
#define _STM32_SPI_H_
|
||||
|
||||
#include "no_os_spi.h"
|
||||
#include "stm32f7xx_hal.h"
|
||||
|
||||
extern const struct no_os_spi_platform_ops stm32_spi_ops;
|
||||
|
||||
#endif /* _STM32_SPI_H_ */
|
||||
@@ -0,0 +1,352 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_timer.c
|
||||
* @brief Implementation of stm32 timer driver.
|
||||
* @author RBolboac (ramona.bolboaca@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2022(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "no_os_util.h"
|
||||
#include "no_os_timer.h"
|
||||
#include "no_os_alloc.h"
|
||||
#include "stm32_timer.h"
|
||||
|
||||
|
||||
static int get_timer_base(uint32_t device_id, TIM_TypeDef **base,
|
||||
uint32_t *clk_freq)
|
||||
{
|
||||
uint32_t apb2_freq = HAL_RCC_GetPCLK2Freq();
|
||||
*clk_freq = HAL_RCC_GetPCLK1Freq();
|
||||
|
||||
switch (device_id) {
|
||||
#if defined(TIM1)
|
||||
case 1:
|
||||
*base = TIM1;
|
||||
*clk_freq = apb2_freq;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM2)
|
||||
case 2:
|
||||
*base = TIM2;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM3)
|
||||
case 3:
|
||||
*base = TIM3;
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
#if defined(TIM4)
|
||||
case 4:
|
||||
*base = TIM4;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM5)
|
||||
case 5:
|
||||
*base = TIM5;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM6)
|
||||
case 6:
|
||||
*base = TIM6;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM7)
|
||||
case 7:
|
||||
*base = TIM7;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM8)
|
||||
case 8:
|
||||
*base = TIM8;
|
||||
*clk_freq = apb2_freq;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM9)
|
||||
case 9:
|
||||
*base = TIM9;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM10)
|
||||
case 10:
|
||||
*base = TIM10;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM11)
|
||||
case 11:
|
||||
*base = TIM11;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM12)
|
||||
case 12:
|
||||
*base = TIM12;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM13)
|
||||
case 13:
|
||||
*base = TIM13;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIM14)
|
||||
case 14:
|
||||
*base = TIM14;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the timer peripheral.
|
||||
* @param desc - The timer descriptor.
|
||||
* @param param - The structure that contains the timer parameters.
|
||||
* @return ret - Result of the init procedure.
|
||||
*/
|
||||
int32_t stm32_timer_init(struct no_os_timer_desc **desc,
|
||||
const struct no_os_timer_init_param *param)
|
||||
{
|
||||
int32_t ret;
|
||||
struct no_os_timer_desc *no_os_desc;
|
||||
struct stm32_timer_desc *stm_desc;
|
||||
uint32_t src_freq;
|
||||
TIM_TypeDef *base = NULL;
|
||||
|
||||
if (!desc || !param)
|
||||
return -EINVAL;
|
||||
|
||||
no_os_desc = (struct no_os_timer_desc *)no_os_calloc(1, sizeof(*no_os_desc));
|
||||
if (!no_os_desc)
|
||||
return -ENOMEM;
|
||||
|
||||
stm_desc = param->extra;
|
||||
|
||||
ret = get_timer_base(param->id, &base, &src_freq);
|
||||
if (ret)
|
||||
goto error;
|
||||
/* Make sure the same id is used as the selected instance */
|
||||
if (base != stm_desc->htimer->Instance) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Make sure the selected frequency is in range */
|
||||
if (src_freq < param->freq_hz) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Overwrite generated values with given values */
|
||||
stm_desc->htimer->Init.Prescaler = src_freq / param->freq_hz;
|
||||
stm_desc->htimer->Init.Period = param->ticks_count;
|
||||
|
||||
ret = HAL_TIM_Base_Init(stm_desc->htimer);
|
||||
if (ret != HAL_OK) {
|
||||
ret = -EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Copy settings to device descriptor */
|
||||
no_os_desc->extra = stm_desc->htimer;
|
||||
no_os_desc->id = param->id;
|
||||
no_os_desc->freq_hz = param->freq_hz;
|
||||
no_os_desc->ticks_count = param->ticks_count;
|
||||
*desc = no_os_desc;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
no_os_free(no_os_desc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by no_os_timer_init().
|
||||
* @param desc - The timer descriptor.
|
||||
*
|
||||
* @return ret - Result of the remove procedure.
|
||||
*/
|
||||
int32_t stm32_timer_remove(struct no_os_timer_desc *desc)
|
||||
{
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
if (!HAL_TIM_Base_DeInit(desc->extra)) {
|
||||
no_os_free(desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a timer.
|
||||
* @param desc - Pointer to the device handler.
|
||||
*
|
||||
* @return ret - Result of the start procedure.
|
||||
*/
|
||||
int32_t stm32_timer_start(struct no_os_timer_desc *desc)
|
||||
{
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
if (!HAL_TIM_Base_Start_IT((TIM_HandleTypeDef*)desc->extra))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop a timer from counting.
|
||||
* @param desc - Pointer to the device handler.
|
||||
*
|
||||
* @return ret - Result of the stop procedure.
|
||||
*/
|
||||
int32_t stm32_timer_stop(struct no_os_timer_desc *desc)
|
||||
{
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
if (!HAL_TIM_Base_Stop_IT((TIM_HandleTypeDef*)desc->extra))
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the value of the counter register for the timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [out] counter - Pointer to the counter value.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t stm32_timer_counter_get(struct no_os_timer_desc *desc,
|
||||
uint32_t *counter)
|
||||
{
|
||||
if (!desc && !counter)
|
||||
return -EINVAL;
|
||||
|
||||
*counter = __HAL_TIM_GetCounter((TIM_HandleTypeDef*)desc->extra);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the timer counter register value.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] new_val - The new value of the counter register.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t stm32_timer_counter_set(struct no_os_timer_desc *desc, uint32_t new_val)
|
||||
{
|
||||
if (!desc || (new_val > desc->ticks_count))
|
||||
return -EINVAL;
|
||||
|
||||
__HAL_TIM_SetCounter((TIM_HandleTypeDef*)desc->extra, new_val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the timer clock frequency.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [out] freq_hz - The value in Hz of the timer clock.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t stm32_timer_count_clk_get(struct no_os_timer_desc *desc,
|
||||
uint32_t *freq_hz)
|
||||
{
|
||||
if (!desc || !freq_hz)
|
||||
return -EINVAL;
|
||||
|
||||
*freq_hz = desc->freq_hz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the timer clock frequency.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] freq_hz - The value in Hz of the new timer clock.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t stm32_timer_count_clk_set(struct no_os_timer_desc *desc,
|
||||
uint32_t freq_hz)
|
||||
{
|
||||
int ret;
|
||||
uint32_t src_freq;
|
||||
TIM_TypeDef *base = NULL;
|
||||
TIM_HandleTypeDef* tim_desc;
|
||||
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
ret = get_timer_base(desc->id, &base, &src_freq);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
if (src_freq < freq_hz)
|
||||
return -EINVAL;
|
||||
|
||||
tim_desc = desc->extra;
|
||||
|
||||
__HAL_TIM_SET_PRESCALER(tim_desc, src_freq / freq_hz);
|
||||
tim_desc->Init.Prescaler = src_freq / freq_hz;
|
||||
|
||||
desc->freq_hz = freq_hz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the elapsed time in nsec for the timer.
|
||||
* @param [in] desc - Pointer to the device handler.
|
||||
* @param [in] elapsed_time - The elapsed time in nsec.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
int32_t stm32_timer_get_elapsed_time_nsec(struct no_os_timer_desc *desc,
|
||||
uint64_t *elapsed_time)
|
||||
{
|
||||
/* Function not implemented because it is not needed at the moment */
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief stm32 platform specific timer platform ops structure
|
||||
*/
|
||||
const struct no_os_timer_platform_ops stm32_timer_ops = {
|
||||
.init = &stm32_timer_init,
|
||||
.start = &stm32_timer_start,
|
||||
.stop = &stm32_timer_stop,
|
||||
.counter_get = &stm32_timer_counter_get,
|
||||
.counter_set = &stm32_timer_counter_set,
|
||||
.count_clk_get = &stm32_timer_count_clk_get,
|
||||
.count_clk_set = &stm32_timer_count_clk_set,
|
||||
.get_elapsed_time_nsec = &stm32_timer_get_elapsed_time_nsec,
|
||||
.remove = &stm32_timer_remove
|
||||
};
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_timer.h
|
||||
* @brief Header file for the stm32 timer driver.
|
||||
* @author RBolboac (ramona.bolboaca@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2022(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef STM32_TIMER_H_
|
||||
#define STM32_TIMER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "no_os_timer.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
/**
|
||||
* @struct stm32_timer_init_param
|
||||
* @brief Structure holding the initialization parameters for stm32 platform
|
||||
* specific timer parameters.
|
||||
*/
|
||||
struct stm32_timer_init_param {
|
||||
TIM_HandleTypeDef *htimer;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct stm32_timer_desc
|
||||
* @brief stm32 platform specific timer descriptor
|
||||
*/
|
||||
struct stm32_timer_desc {
|
||||
/** timer instance */
|
||||
TIM_HandleTypeDef *htimer;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief stm32 specific timer platform ops structure
|
||||
*/
|
||||
extern const struct no_os_timer_platform_ops stm32_timer_ops;
|
||||
|
||||
#endif // STM32_TIMER_H_
|
||||
@@ -0,0 +1,302 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_uart.c
|
||||
* @brief Source file of UART driver for STM32
|
||||
* @author Darius Berghe (darius.berghe@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include "no_os_uart.h"
|
||||
#include "no_os_irq.h"
|
||||
#include "no_os_lf256fifo.h"
|
||||
#include "no_os_alloc.h"
|
||||
#include "stm32_irq.h"
|
||||
#include "stm32_uart.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
static uint8_t c;
|
||||
|
||||
void uart_rx_callback(void *context)
|
||||
{
|
||||
struct no_os_uart_desc *d = context;
|
||||
lf256fifo_write(d->rx_fifo, c);
|
||||
HAL_UART_Receive_IT(((struct stm32_uart_desc *)d->extra)->huart, &c, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the UART communication peripheral.
|
||||
* @param desc - The UART descriptor.
|
||||
* @param param - The structure that contains the UART parameters.
|
||||
* @return 0 in case of success, error code otherwise.
|
||||
*/
|
||||
static int32_t stm32_uart_init(struct no_os_uart_desc **desc,
|
||||
struct no_os_uart_init_param *param)
|
||||
{
|
||||
struct stm32_uart_init_param *suip;
|
||||
struct stm32_uart_desc *sud;
|
||||
struct no_os_uart_desc *descriptor;
|
||||
int ret;
|
||||
|
||||
if (!desc || !param)
|
||||
return -EINVAL;
|
||||
|
||||
descriptor = (struct no_os_uart_desc *) no_os_calloc(1, sizeof(*descriptor));
|
||||
if (!descriptor)
|
||||
return -ENOMEM;
|
||||
|
||||
sud = (struct stm32_uart_desc *) no_os_calloc(1,
|
||||
sizeof(struct stm32_uart_desc));
|
||||
if (!sud) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
descriptor->irq_id = param->irq_id;
|
||||
descriptor->extra = sud;
|
||||
suip = param->extra;
|
||||
|
||||
sud->huart = suip->huart;
|
||||
sud->huart->Init.BaudRate = param->baud_rate;
|
||||
switch (param->size) {
|
||||
case NO_OS_UART_CS_8:
|
||||
sud->huart->Init.WordLength = UART_WORDLENGTH_8B;
|
||||
break;
|
||||
case NO_OS_UART_CS_9:
|
||||
sud->huart->Init.WordLength = UART_WORDLENGTH_9B;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
};
|
||||
switch (param->parity) {
|
||||
case NO_OS_UART_PAR_NO:
|
||||
sud->huart->Init.Parity = UART_PARITY_NONE;
|
||||
break;
|
||||
case NO_OS_UART_PAR_ODD:
|
||||
sud->huart->Init.Parity = UART_PARITY_ODD;
|
||||
break;
|
||||
case NO_OS_UART_PAR_EVEN:
|
||||
sud->huart->Init.Parity = UART_PARITY_EVEN;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
};
|
||||
sud->huart->Init.StopBits = param->stop == NO_OS_UART_STOP_1_BIT ?
|
||||
UART_STOPBITS_1 :
|
||||
UART_STOPBITS_2;
|
||||
sud->huart->Init.Mode = suip->huart->Init.Mode;
|
||||
sud->huart->Init.HwFlowCtl = suip->huart->Init.HwFlowCtl;
|
||||
sud->huart->Init.OverSampling = suip->huart->Init.OverSampling;
|
||||
ret = HAL_UART_Init(sud->huart);
|
||||
if (ret != HAL_OK) {
|
||||
ret = -EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
sud->timeout = suip->timeout ? suip->timeout : HAL_MAX_DELAY;
|
||||
|
||||
// nonblocking uart_read
|
||||
if (param->asynchronous_rx) {
|
||||
ret = lf256fifo_init(&descriptor->rx_fifo);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
struct no_os_irq_init_param nvic_ip = {
|
||||
.platform_ops = &stm32_irq_ops,
|
||||
.extra = sud->huart,
|
||||
};
|
||||
ret = no_os_irq_ctrl_init(&sud->nvic, &nvic_ip);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
sud->rx_callback.callback = uart_rx_callback;
|
||||
sud->rx_callback.ctx = descriptor;
|
||||
sud->rx_callback.event = NO_OS_EVT_UART_RX_COMPLETE;
|
||||
sud->rx_callback.peripheral = NO_OS_UART_IRQ;
|
||||
sud->rx_callback.handle = sud->huart;
|
||||
|
||||
ret = no_os_irq_register_callback(sud->nvic, descriptor->irq_id,
|
||||
&sud->rx_callback);
|
||||
if (ret < 0)
|
||||
goto error_nvic;
|
||||
|
||||
ret = no_os_irq_enable(sud->nvic, descriptor->irq_id);
|
||||
if (ret < 0)
|
||||
goto error_register;
|
||||
|
||||
HAL_UART_Receive_IT(sud->huart, (uint8_t *)&c, 1);
|
||||
if (ret != HAL_OK) {
|
||||
ret = -EIO;
|
||||
goto error_enable;
|
||||
}
|
||||
}
|
||||
|
||||
descriptor->device_id = param->device_id;
|
||||
descriptor->baud_rate = param->baud_rate;
|
||||
|
||||
*desc = descriptor;
|
||||
|
||||
return 0;
|
||||
error_enable:
|
||||
no_os_irq_disable(sud->nvic, descriptor->irq_id);
|
||||
error_register:
|
||||
no_os_irq_unregister_callback(sud->nvic, descriptor->irq_id, &sud->rx_callback);
|
||||
error_nvic:
|
||||
no_os_irq_ctrl_remove(sud->nvic);
|
||||
error:
|
||||
no_os_free(descriptor);
|
||||
no_os_free(sud);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the resources allocated by stm32_uart_init().
|
||||
* @param desc - The UART descriptor.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
static int32_t stm32_uart_remove(struct no_os_uart_desc *desc)
|
||||
{
|
||||
struct stm32_uart_desc *sud;
|
||||
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
sud = desc->extra;
|
||||
HAL_UART_DeInit(sud->huart);
|
||||
if (desc->rx_fifo) {
|
||||
no_os_irq_disable(sud->nvic, desc->irq_id);
|
||||
lf256fifo_remove(desc->rx_fifo);
|
||||
desc->rx_fifo = NULL;
|
||||
no_os_irq_unregister_callback(sud->nvic, desc->irq_id, &sud->rx_callback);
|
||||
no_os_irq_ctrl_remove(sud->nvic);
|
||||
}
|
||||
no_os_free(desc->extra);
|
||||
no_os_free(desc);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Write data to UART device.
|
||||
* @param desc - Instance of UART.
|
||||
* @param data - Pointer to buffer containing data.
|
||||
* @param bytes_number - Number of bytes to read.
|
||||
* @return 0 in case of success, -1 otherwise.
|
||||
*/
|
||||
static int32_t stm32_uart_write(struct no_os_uart_desc *desc,
|
||||
const uint8_t *data,
|
||||
uint32_t bytes_number)
|
||||
{
|
||||
struct stm32_uart_desc *sud;
|
||||
int32_t ret;
|
||||
|
||||
if (!desc || !desc->extra || !data)
|
||||
return -EINVAL;
|
||||
|
||||
if (!bytes_number)
|
||||
return 0;
|
||||
|
||||
sud = desc->extra;
|
||||
ret = HAL_UART_Transmit(sud->huart, (uint8_t *)data, bytes_number,
|
||||
sud->timeout);
|
||||
|
||||
switch (ret) {
|
||||
case HAL_OK:
|
||||
break;
|
||||
case HAL_BUSY:
|
||||
return -EBUSY;
|
||||
case HAL_TIMEOUT:
|
||||
return -ETIMEDOUT;
|
||||
default:
|
||||
return -EIO;
|
||||
};
|
||||
|
||||
return bytes_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read data from UART device.
|
||||
* @param desc - Instance of UART.
|
||||
* @param data - Pointer to buffer containing data.
|
||||
* @param bytes_number - Number of bytes to read.
|
||||
* @return positive number of received bytes in case of success, negative error code otherwise.
|
||||
*/
|
||||
static int32_t stm32_uart_read(struct no_os_uart_desc *desc, uint8_t *data,
|
||||
uint32_t bytes_number)
|
||||
{
|
||||
struct stm32_uart_desc *sud;
|
||||
uint32_t i = 0;
|
||||
int32_t ret;
|
||||
|
||||
if (!desc || !desc->extra || !data)
|
||||
return -EINVAL;
|
||||
|
||||
if (!bytes_number)
|
||||
return 0;
|
||||
|
||||
sud = desc->extra;
|
||||
|
||||
if (desc->rx_fifo) {
|
||||
while (i < bytes_number) {
|
||||
ret = lf256fifo_read(desc->rx_fifo, &data[i]);
|
||||
if (ret < 0)
|
||||
return i ? i : -EAGAIN;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
} else {
|
||||
ret = HAL_UART_Receive(sud->huart, (uint8_t *)data, bytes_number,
|
||||
sud->timeout);
|
||||
|
||||
switch (ret) {
|
||||
case HAL_OK:
|
||||
break;
|
||||
case HAL_BUSY:
|
||||
return -EBUSY;
|
||||
case HAL_TIMEOUT:
|
||||
return -ETIMEDOUT;
|
||||
default:
|
||||
return -EIO;
|
||||
};
|
||||
}
|
||||
|
||||
return bytes_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief STM32 platform specific UART platform ops structure
|
||||
*/
|
||||
const struct no_os_uart_platform_ops stm32_uart_ops = {
|
||||
.init = &stm32_uart_init,
|
||||
.read = &stm32_uart_read,
|
||||
.write = &stm32_uart_write,
|
||||
.remove = &stm32_uart_remove
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
/***************************************************************************//**
|
||||
* @file stm32/stm32_uart.h
|
||||
* @brief Header file of UART driver for STM32
|
||||
* @author Darius Berghe (darius.berghe@analog.com)
|
||||
********************************************************************************
|
||||
* Copyright 2020(c) Analog Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
#ifndef _STM32_UART_H_
|
||||
#define _STM32_UART_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "no_os_uart.h"
|
||||
#include "no_os_irq.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
/**
|
||||
* @struct stm32_uart_init_param
|
||||
* @brief Specific initialization parameters for stm32 UART.
|
||||
*/
|
||||
struct stm32_uart_init_param {
|
||||
/** UART instance */
|
||||
UART_HandleTypeDef *huart;
|
||||
/** UART transaction timeout (HAL_IncTick() units) */
|
||||
uint32_t timeout;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct stm32_uart_desc
|
||||
* @brief stm32 platform specific UART descriptor
|
||||
*/
|
||||
struct stm32_uart_desc {
|
||||
/** UART instance */
|
||||
UART_HandleTypeDef *huart;
|
||||
/** UART transaction timeout (HAL_IncTick() units) */
|
||||
uint32_t timeout;
|
||||
/** Interrupt controller descriptor */
|
||||
struct no_os_irq_ctrl_desc *nvic;
|
||||
/** RX complete callback */
|
||||
struct no_os_callback_desc rx_callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief STM32 specific UART platform ops structure
|
||||
*/
|
||||
extern const struct no_os_uart_platform_ops stm32_uart_ops;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,484 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f7xx_hal_conf_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief HAL configuration template file.
|
||||
* This file should be copied to the application folder and renamed
|
||||
* to stm32f7xx_hal_conf.h.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F7xx_HAL_CONF_H
|
||||
#define __STM32F7xx_HAL_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
|
||||
/* #define HAL_CRYP_MODULE_ENABLED */
|
||||
/* #define HAL_ADC_MODULE_ENABLED */
|
||||
/* #define HAL_CAN_MODULE_ENABLED */
|
||||
/* #define HAL_CEC_MODULE_ENABLED */
|
||||
/* #define HAL_CRC_MODULE_ENABLED */
|
||||
/* #define HAL_DAC_MODULE_ENABLED */
|
||||
/* #define HAL_DCMI_MODULE_ENABLED */
|
||||
/* #define HAL_DMA2D_MODULE_ENABLED */
|
||||
/* #define HAL_ETH_MODULE_ENABLED */
|
||||
/* #define HAL_ETH_LEGACY_MODULE_ENABLED */
|
||||
/* #define HAL_NAND_MODULE_ENABLED */
|
||||
/* #define HAL_NOR_MODULE_ENABLED */
|
||||
/* #define HAL_SRAM_MODULE_ENABLED */
|
||||
/* #define HAL_SDRAM_MODULE_ENABLED */
|
||||
/* #define HAL_HASH_MODULE_ENABLED */
|
||||
/* #define HAL_I2S_MODULE_ENABLED */
|
||||
/* #define HAL_IWDG_MODULE_ENABLED */
|
||||
/* #define HAL_LPTIM_MODULE_ENABLED */
|
||||
/* #define HAL_LTDC_MODULE_ENABLED */
|
||||
/* #define HAL_QSPI_MODULE_ENABLED */
|
||||
/* #define HAL_RNG_MODULE_ENABLED */
|
||||
/* #define HAL_RTC_MODULE_ENABLED */
|
||||
/* #define HAL_SAI_MODULE_ENABLED */
|
||||
/* #define HAL_SD_MODULE_ENABLED */
|
||||
/* #define HAL_MMC_MODULE_ENABLED */
|
||||
/* #define HAL_SPDIFRX_MODULE_ENABLED */
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/* #define HAL_USART_MODULE_ENABLED */
|
||||
/* #define HAL_IRDA_MODULE_ENABLED */
|
||||
/* #define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
/* #define HAL_WWDG_MODULE_ENABLED */
|
||||
#define HAL_PCD_MODULE_ENABLED
|
||||
/* #define HAL_HCD_MODULE_ENABLED */
|
||||
/* #define HAL_DFSDM_MODULE_ENABLED */
|
||||
/* #define HAL_DSI_MODULE_ENABLED */
|
||||
/* #define HAL_JPEG_MODULE_ENABLED */
|
||||
/* #define HAL_MDIOS_MODULE_ENABLED */
|
||||
/* #define HAL_SMBUS_MODULE_ENABLED */
|
||||
/* #define HAL_EXTI_MODULE_ENABLED */
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief External clock source for I2S peripheral
|
||||
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#define TICK_INT_PRIORITY ((uint32_t)15U) /*!< tick interrupt priority */
|
||||
#define USE_RTOS 0U
|
||||
#define PREFETCH_ENABLE 0U
|
||||
#define ART_ACCELERATOR_ENABLE 0U /* To enable instruction cache and prefetch */
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
|
||||
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
|
||||
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U /* JPEG register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
|
||||
#define USE_HAL_MDIOS_REGISTER_CALLBACKS 0U /* MDIOS register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
|
||||
/* DP83848_PHY_ADDRESS Address*/
|
||||
#define DP83848_PHY_ADDRESS
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
|
||||
|
||||
#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
|
||||
#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
#define PHY_SR ((uint16_t)) /*!< PHY status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)) /*!< PHY Duplex mask */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
|
||||
#define USE_SPI_CRC 0U
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_LEGACY_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_eth_legacy.h"
|
||||
#endif /* HAL_ETH_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QSPI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_qspi.h"
|
||||
#endif /* HAL_QSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPDIFRX_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_spdifrx.h"
|
||||
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DFSDM_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dfsdm.h"
|
||||
#endif /* HAL_DFSDM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DSI_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_dsi.h"
|
||||
#endif /* HAL_DSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_JPEG_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_jpeg.h"
|
||||
#endif /* HAL_JPEG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MDIOS_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_mdios.h"
|
||||
#endif /* HAL_MDIOS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32f7xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr: If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t* file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F7xx_HAL_CONF_H */
|
||||
|
||||
@@ -0,0 +1,567 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f7xx_hal_msp.c
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Define */
|
||||
|
||||
/* USER CODE END Define */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Macro */
|
||||
|
||||
/* USER CODE END Macro */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* External functions --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ExternalFunctions */
|
||||
|
||||
/* USER CODE END ExternalFunctions */
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
/**
|
||||
* Initializes the Global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN MspInit 0 */
|
||||
|
||||
/* USER CODE END MspInit 0 */
|
||||
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
|
||||
/* System interrupt init*/
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hi2c: I2C handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
if(hi2c->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
|
||||
PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**I2C1 GPIO Configuration
|
||||
PB6 ------> I2C1_SCL
|
||||
PB7 ------> I2C1_SDA
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||
/* USER CODE BEGIN I2C1_MspInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 1 */
|
||||
}
|
||||
else if(hi2c->Instance==I2C2)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_MspInit 0 */
|
||||
|
||||
/* USER CODE END I2C2_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C2;
|
||||
PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
/**I2C2 GPIO Configuration
|
||||
PF0 ------> I2C2_SDA
|
||||
PF1 ------> I2C2_SCL
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
|
||||
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_I2C2_CLK_ENABLE();
|
||||
/* USER CODE BEGIN I2C2_MspInit 1 */
|
||||
|
||||
/* USER CODE END I2C2_MspInit 1 */
|
||||
}
|
||||
else if(hi2c->Instance==I2C3)
|
||||
{
|
||||
/* USER CODE BEGIN I2C3_MspInit 0 */
|
||||
|
||||
/* USER CODE END I2C3_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C3;
|
||||
PeriphClkInitStruct.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**I2C3 GPIO Configuration
|
||||
PC9 ------> I2C3_SDA
|
||||
PA8 ------> I2C3_SCL
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_I2C3_CLK_ENABLE();
|
||||
/* USER CODE BEGIN I2C3_MspInit 1 */
|
||||
|
||||
/* USER CODE END I2C3_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hi2c: I2C handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
|
||||
{
|
||||
if(hi2c->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
|
||||
/**I2C1 GPIO Configuration
|
||||
PB6 ------> I2C1_SCL
|
||||
PB7 ------> I2C1_SDA
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
|
||||
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 1 */
|
||||
}
|
||||
else if(hi2c->Instance==I2C2)
|
||||
{
|
||||
/* USER CODE BEGIN I2C2_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END I2C2_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C2_CLK_DISABLE();
|
||||
|
||||
/**I2C2 GPIO Configuration
|
||||
PF0 ------> I2C2_SDA
|
||||
PF1 ------> I2C2_SCL
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_1);
|
||||
|
||||
/* USER CODE BEGIN I2C2_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END I2C2_MspDeInit 1 */
|
||||
}
|
||||
else if(hi2c->Instance==I2C3)
|
||||
{
|
||||
/* USER CODE BEGIN I2C3_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END I2C3_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C3_CLK_DISABLE();
|
||||
|
||||
/**I2C3 GPIO Configuration
|
||||
PC9 ------> I2C3_SDA
|
||||
PA8 ------> I2C3_SCL
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_9);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8);
|
||||
|
||||
/* USER CODE BEGIN I2C3_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END I2C3_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(hspi->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 1 */
|
||||
}
|
||||
else if(hspi->Instance==SPI4)
|
||||
{
|
||||
/* USER CODE BEGIN SPI4_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI4_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_SPI4_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
/**SPI4 GPIO Configuration
|
||||
PE2 ------> SPI4_SCK
|
||||
PE5 ------> SPI4_MISO
|
||||
PE6 ------> SPI4_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_5|GPIO_PIN_6;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_SPI4;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN SPI4_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI4_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
|
||||
{
|
||||
if(hspi->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI1_CLK_DISABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 1 */
|
||||
}
|
||||
else if(hspi->Instance==SPI4)
|
||||
{
|
||||
/* USER CODE BEGIN SPI4_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI4_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI4_CLK_DISABLE();
|
||||
|
||||
/**SPI4 GPIO Configuration
|
||||
PE2 ------> SPI4_SCK
|
||||
PE5 ------> SPI4_MISO
|
||||
PE6 ------> SPI4_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2|GPIO_PIN_5|GPIO_PIN_6);
|
||||
|
||||
/* USER CODE BEGIN SPI4_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI4_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM_Base MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param htim_base: TIM_Base handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
|
||||
{
|
||||
if(htim_base->Instance==TIM1)
|
||||
{
|
||||
/* USER CODE BEGIN TIM1_MspInit 0 */
|
||||
|
||||
/* USER CODE END TIM1_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_TIM1_CLK_ENABLE();
|
||||
/* USER CODE BEGIN TIM1_MspInit 1 */
|
||||
|
||||
/* USER CODE END TIM1_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM_Base MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param htim_base: TIM_Base handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
|
||||
{
|
||||
if(htim_base->Instance==TIM1)
|
||||
{
|
||||
/* USER CODE BEGIN TIM1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END TIM1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_TIM1_CLK_DISABLE();
|
||||
/* USER CODE BEGIN TIM1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END TIM1_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param huart: UART handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
if(huart->Instance==UART5)
|
||||
{
|
||||
/* USER CODE BEGIN UART5_MspInit 0 */
|
||||
|
||||
/* USER CODE END UART5_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_UART5;
|
||||
PeriphClkInitStruct.Uart5ClockSelection = RCC_UART5CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_UART5_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
/**UART5 GPIO Configuration
|
||||
PC12 ------> UART5_TX
|
||||
PD2 ------> UART5_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN UART5_MspInit 1 */
|
||||
|
||||
/* USER CODE END UART5_MspInit 1 */
|
||||
}
|
||||
else if(huart->Instance==USART3)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART3_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3;
|
||||
PeriphClkInitStruct.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_USART3_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**USART3 GPIO Configuration
|
||||
PB10 ------> USART3_TX
|
||||
PB11 ------> USART3_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN USART3_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART3_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param huart: UART handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
|
||||
{
|
||||
if(huart->Instance==UART5)
|
||||
{
|
||||
/* USER CODE BEGIN UART5_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END UART5_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_UART5_CLK_DISABLE();
|
||||
|
||||
/**UART5 GPIO Configuration
|
||||
PC12 ------> UART5_TX
|
||||
PD2 ------> UART5_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
|
||||
|
||||
/* USER CODE BEGIN UART5_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END UART5_MspDeInit 1 */
|
||||
}
|
||||
else if(huart->Instance==USART3)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART3_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART3_CLK_DISABLE();
|
||||
|
||||
/**USART3 GPIO Configuration
|
||||
PB10 ------> USART3_TX
|
||||
PB11 ------> USART3_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
|
||||
|
||||
/* USER CODE BEGIN USART3_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART3_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
@@ -0,0 +1,217 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f7xx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "stm32f7xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M7 Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||
|
||||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Memory management fault.
|
||||
*/
|
||||
void MemManage_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
||||
|
||||
/* USER CODE END MemoryManagement_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pre-fetch fault, memory access fault.
|
||||
*/
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN BusFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END BusFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||||
/* USER CODE END W1_BusFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Undefined instruction or illegal state.
|
||||
*/
|
||||
void UsageFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END UsageFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||||
/* USER CODE END W1_UsageFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SVCall_IRQn 0 */
|
||||
|
||||
/* USER CODE END SVCall_IRQn 0 */
|
||||
/* USER CODE BEGIN SVCall_IRQn 1 */
|
||||
|
||||
/* USER CODE END SVCall_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Debug monitor.
|
||||
*/
|
||||
void DebugMon_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 0 */
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN PendSV_IRQn 0 */
|
||||
|
||||
/* USER CODE END PendSV_IRQn 0 */
|
||||
/* USER CODE BEGIN PendSV_IRQn 1 */
|
||||
|
||||
/* USER CODE END PendSV_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 0 */
|
||||
HAL_IncTick();
|
||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 1 */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F7xx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file (startup_stm32f7xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles USB On The Go FS global interrupt.
|
||||
*/
|
||||
void OTG_FS_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN OTG_FS_IRQn 0 */
|
||||
|
||||
/* USER CODE END OTG_FS_IRQn 0 */
|
||||
HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
|
||||
/* USER CODE BEGIN OTG_FS_IRQn 1 */
|
||||
|
||||
/* USER CODE END OTG_FS_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
@@ -0,0 +1,67 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f7xx_it.h
|
||||
* @brief This file contains the headers of the interrupt handlers.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F7xx_IT_H
|
||||
#define __STM32F7xx_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void MemManage_Handler(void);
|
||||
void BusFault_Handler(void);
|
||||
void UsageFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void OTG_FS_IRQHandler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F7xx_IT_H */
|
||||
176
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/syscalls.c
Normal file
176
9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/syscalls.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file syscalls.c
|
||||
* @author Auto-generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE Minimal System calls file
|
||||
*
|
||||
* For more information about which c-functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the Newlib libc-manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2020-2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
|
||||
/* Variables */
|
||||
extern int __io_putchar(int ch) __attribute__((weak));
|
||||
extern int __io_getchar(void) __attribute__((weak));
|
||||
|
||||
|
||||
char *__env[1] = { 0 };
|
||||
char **environ = __env;
|
||||
|
||||
|
||||
/* Functions */
|
||||
void initialise_monitor_handles()
|
||||
{
|
||||
}
|
||||
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
(void)pid;
|
||||
(void)sig;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _exit (int status)
|
||||
{
|
||||
_kill(status, -1);
|
||||
while (1) {} /* Make sure we hang here */
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _read(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
*ptr++ = __io_getchar();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _write(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
(void)file;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _open(char *path, int flags, ...)
|
||||
{
|
||||
(void)path;
|
||||
(void)flags;
|
||||
/* Pretend like we always fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _wait(int *status)
|
||||
{
|
||||
(void)status;
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _unlink(char *name)
|
||||
{
|
||||
(void)name;
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _times(struct tms *buf)
|
||||
{
|
||||
(void)buf;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _stat(char *file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _link(char *old, char *new)
|
||||
{
|
||||
(void)old;
|
||||
(void)new;
|
||||
errno = EMLINK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fork(void)
|
||||
{
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _execve(char *name, char **argv, char **env)
|
||||
{
|
||||
(void)name;
|
||||
(void)argv;
|
||||
(void)env;
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file sysmem.c
|
||||
* @author Generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE System Memory calls file
|
||||
*
|
||||
* For more information about which C functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the newlib libc manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Pointer to the current high watermark of the heap usage
|
||||
*/
|
||||
static uint8_t *__sbrk_heap_end = NULL;
|
||||
|
||||
/**
|
||||
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
|
||||
* and others from the C library
|
||||
*
|
||||
* @verbatim
|
||||
* ############################################################################
|
||||
* # .data # .bss # newlib heap # MSP stack #
|
||||
* # # # # Reserved by _Min_Stack_Size #
|
||||
* ############################################################################
|
||||
* ^-- RAM start ^-- _end _estack, RAM end --^
|
||||
* @endverbatim
|
||||
*
|
||||
* This implementation starts allocating at the '_end' linker symbol
|
||||
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
|
||||
* The implementation considers '_estack' linker symbol to be RAM end
|
||||
* NOTE: If the MSP stack, at any point during execution, grows larger than the
|
||||
* reserved size, please increase the '_Min_Stack_Size'.
|
||||
*
|
||||
* @param incr Memory size
|
||||
* @return Pointer to allocated memory
|
||||
*/
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
extern uint8_t _end; /* Symbol defined in the linker script */
|
||||
extern uint8_t _estack; /* Symbol defined in the linker script */
|
||||
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
|
||||
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
|
||||
const uint8_t *max_heap = (uint8_t *)stack_limit;
|
||||
uint8_t *prev_heap_end;
|
||||
|
||||
/* Initialize heap end at first call */
|
||||
if (NULL == __sbrk_heap_end)
|
||||
{
|
||||
__sbrk_heap_end = &_end;
|
||||
}
|
||||
|
||||
/* Protect heap from growing into the reserved MSP stack */
|
||||
if (__sbrk_heap_end + incr > max_heap)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
prev_heap_end = __sbrk_heap_end;
|
||||
__sbrk_heap_end += incr;
|
||||
|
||||
return (void *)prev_heap_end;
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f7xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M7 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32f7xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f7xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F7xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32f7xx.h"
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F7xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F7xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/************************* Miscellaneous Configuration ************************/
|
||||
|
||||
/* Note: Following vector table addresses must be defined in line with linker
|
||||
configuration. */
|
||||
/*!< Uncomment the following line if you need to relocate the vector table
|
||||
anywhere in Flash or Sram, else the vector table is kept at the automatic
|
||||
remap of boot address selected */
|
||||
/* #define USER_VECT_TAB_ADDRESS */
|
||||
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table
|
||||
in Sram else user remap will be done in Flash. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#if defined(VECT_TAB_SRAM)
|
||||
#define VECT_TAB_BASE_ADDRESS RAMDTCM_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#else
|
||||
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
#if !defined(VECT_TAB_OFFSET)
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif /* VECT_TAB_OFFSET */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F7xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F7xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 16000000;
|
||||
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F7xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F7xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system
|
||||
* Initialize the Embedded Flash Interface, the PLL and update the
|
||||
* SystemFrequency variable.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* FPU settings ------------------------------------------------------------*/
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
|
||||
#endif
|
||||
|
||||
/* Configure the Vector Table location -------------------------------------*/
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32f7xx_hal_conf.h file (default value
|
||||
* 16 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32f7xx_hal_conf.h file (default value
|
||||
* 25 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
uint32_t tmp, pllvco, pllp, pllsource, pllm;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00: /* HSI used as system clock source */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04: /* HSE used as system clock source */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08: /* PLL used as system clock source */
|
||||
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
|
||||
SYSCLK = PLL_VCO / PLL_P
|
||||
*/
|
||||
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
|
||||
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
|
||||
|
||||
if (pllsource != 0)
|
||||
{
|
||||
/* HSE used as PLL clock source */
|
||||
pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HSI used as PLL clock source */
|
||||
pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
|
||||
}
|
||||
|
||||
pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
|
||||
SystemCoreClock = pllvco/pllp;
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
/* Compute HCLK frequency --------------------------------------------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
|
||||
/* HCLK frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
2411
9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp
Normal file
2411
9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
175
9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.h
Normal file
175
9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.h
|
||||
* @brief : Header for main.c file.
|
||||
* This file contains the common defines of the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MAIN_H
|
||||
#define __MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f7xx_hal.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
extern uint8_t GUI_start_flag_received;
|
||||
extern uint8_t USB_Buffer[64];
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define AD9523_PD_Pin GPIO_PIN_3
|
||||
#define AD9523_PD_GPIO_Port GPIOF
|
||||
#define AD9523_REF_SEL_Pin GPIO_PIN_4
|
||||
#define AD9523_REF_SEL_GPIO_Port GPIOF
|
||||
#define AD9523_SYNC_Pin GPIO_PIN_5
|
||||
#define AD9523_SYNC_GPIO_Port GPIOF
|
||||
#define AD9523_RESET_Pin GPIO_PIN_6
|
||||
#define AD9523_RESET_GPIO_Port GPIOF
|
||||
#define AD9523_CS_Pin GPIO_PIN_7
|
||||
#define AD9523_CS_GPIO_Port GPIOF
|
||||
#define AD9523_STATUS0_Pin GPIO_PIN_8
|
||||
#define AD9523_STATUS0_GPIO_Port GPIOF
|
||||
#define AD9523_STATUS1_Pin GPIO_PIN_9
|
||||
#define AD9523_STATUS1_GPIO_Port GPIOF
|
||||
#define AD9523_EEPROM_SEL_Pin GPIO_PIN_10
|
||||
#define AD9523_EEPROM_SEL_GPIO_Port GPIOF
|
||||
#define ADAR_1_CS_3V3_Pin GPIO_PIN_0
|
||||
#define ADAR_1_CS_3V3_GPIO_Port GPIOA
|
||||
#define ADAR_2_CS_3V3_Pin GPIO_PIN_1
|
||||
#define ADAR_2_CS_3V3_GPIO_Port GPIOA
|
||||
#define ADAR_3_CS_3V3_Pin GPIO_PIN_2
|
||||
#define ADAR_3_CS_3V3_GPIO_Port GPIOA
|
||||
#define ADAR_4_CS_3V3_Pin GPIO_PIN_3
|
||||
#define ADAR_4_CS_3V3_GPIO_Port GPIOA
|
||||
#define LED_1_Pin GPIO_PIN_12
|
||||
#define LED_1_GPIO_Port GPIOF
|
||||
#define LED_2_Pin GPIO_PIN_13
|
||||
#define LED_2_GPIO_Port GPIOF
|
||||
#define LED_3_Pin GPIO_PIN_14
|
||||
#define LED_3_GPIO_Port GPIOF
|
||||
#define LED_4_Pin GPIO_PIN_15
|
||||
#define LED_4_GPIO_Port GPIOF
|
||||
#define EN_P_5V0_PA1_Pin GPIO_PIN_0
|
||||
#define EN_P_5V0_PA1_GPIO_Port GPIOG
|
||||
#define EN_P_5V0_PA2_Pin GPIO_PIN_1
|
||||
#define EN_P_5V0_PA2_GPIO_Port GPIOG
|
||||
#define EN_P_1V0_FPGA_Pin GPIO_PIN_7
|
||||
#define EN_P_1V0_FPGA_GPIO_Port GPIOE
|
||||
#define EN_P_1V8_FPGA_Pin GPIO_PIN_8
|
||||
#define EN_P_1V8_FPGA_GPIO_Port GPIOE
|
||||
#define EN_P_3V3_FPGA_Pin GPIO_PIN_9
|
||||
#define EN_P_3V3_FPGA_GPIO_Port GPIOE
|
||||
#define EN_P_5V0_ADAR_Pin GPIO_PIN_10
|
||||
#define EN_P_5V0_ADAR_GPIO_Port GPIOE
|
||||
#define EN_P_3V3_ADAR12_Pin GPIO_PIN_11
|
||||
#define EN_P_3V3_ADAR12_GPIO_Port GPIOE
|
||||
#define EN_P_3V3_ADAR34_Pin GPIO_PIN_12
|
||||
#define EN_P_3V3_ADAR34_GPIO_Port GPIOE
|
||||
#define EN_P_3V3_ADTR_Pin GPIO_PIN_13
|
||||
#define EN_P_3V3_ADTR_GPIO_Port GPIOE
|
||||
#define EN_P_3V3_SW_Pin GPIO_PIN_14
|
||||
#define EN_P_3V3_SW_GPIO_Port GPIOE
|
||||
#define EN_P_3V3_VDD_SW_Pin GPIO_PIN_15
|
||||
#define EN_P_3V3_VDD_SW_GPIO_Port GPIOE
|
||||
#define EN_P_5V0_PA3_Pin GPIO_PIN_2
|
||||
#define EN_P_5V0_PA3_GPIO_Port GPIOG
|
||||
#define EN_P_5V5_PA_Pin GPIO_PIN_3
|
||||
#define EN_P_5V5_PA_GPIO_Port GPIOG
|
||||
#define EN_P_1V8_CLOCK_Pin GPIO_PIN_4
|
||||
#define EN_P_1V8_CLOCK_GPIO_Port GPIOG
|
||||
#define EN_P_3V3_CLOCK_Pin GPIO_PIN_5
|
||||
#define EN_P_3V3_CLOCK_GPIO_Port GPIOG
|
||||
#define ADF4382_RX_LKDET_Pin GPIO_PIN_6
|
||||
#define ADF4382_RX_LKDET_GPIO_Port GPIOG
|
||||
#define ADF4382_RX_DELADJ_Pin GPIO_PIN_7
|
||||
#define ADF4382_RX_DELADJ_GPIO_Port GPIOG
|
||||
#define ADF4382_RX_DELSTR_Pin GPIO_PIN_8
|
||||
#define ADF4382_RX_DELSTR_GPIO_Port GPIOG
|
||||
#define MAG_DRDY_Pin GPIO_PIN_6
|
||||
#define MAG_DRDY_GPIO_Port GPIOC
|
||||
#define ACC_INT_Pin GPIO_PIN_7
|
||||
#define ACC_INT_GPIO_Port GPIOC
|
||||
#define GYR_INT_Pin GPIO_PIN_8
|
||||
#define GYR_INT_GPIO_Port GPIOC
|
||||
#define STEPPER_CW_P_Pin GPIO_PIN_4
|
||||
#define STEPPER_CW_P_GPIO_Port GPIOD
|
||||
#define STEPPER_CLK_P_Pin GPIO_PIN_5
|
||||
#define STEPPER_CLK_P_GPIO_Port GPIOD
|
||||
#define EN_DIS_RFPA_VDD_Pin GPIO_PIN_6
|
||||
#define EN_DIS_RFPA_VDD_GPIO_Port GPIOD
|
||||
#define EN_DIS_COOLING_Pin GPIO_PIN_7
|
||||
#define EN_DIS_COOLING_GPIO_Port GPIOD
|
||||
#define ADF4382_RX_CE_Pin GPIO_PIN_9
|
||||
#define ADF4382_RX_CE_GPIO_Port GPIOG
|
||||
#define ADF4382_RX_CS_Pin GPIO_PIN_10
|
||||
#define ADF4382_RX_CS_GPIO_Port GPIOG
|
||||
#define ADF4382_TX_LKDET_Pin GPIO_PIN_11
|
||||
#define ADF4382_TX_LKDET_GPIO_Port GPIOG
|
||||
#define ADF4382_TX_DELSTR_Pin GPIO_PIN_12
|
||||
#define ADF4382_TX_DELSTR_GPIO_Port GPIOG
|
||||
#define ADF4382_TX_DELADJ_Pin GPIO_PIN_13
|
||||
#define ADF4382_TX_DELADJ_GPIO_Port GPIOG
|
||||
#define ADF4382_TX_CS_Pin GPIO_PIN_14
|
||||
#define ADF4382_TX_CS_GPIO_Port GPIOG
|
||||
#define ADF4382_TX_CE_Pin GPIO_PIN_15
|
||||
#define ADF4382_TX_CE_GPIO_Port GPIOG
|
||||
#define DAC_1_VG_CLR_Pin GPIO_PIN_4
|
||||
#define DAC_1_VG_CLR_GPIO_Port GPIOB
|
||||
#define DAC_1_VG_LDAC_Pin GPIO_PIN_5
|
||||
#define DAC_1_VG_LDAC_GPIO_Port GPIOB
|
||||
#define DAC_2_VG_CLR_Pin GPIO_PIN_8
|
||||
#define DAC_2_VG_CLR_GPIO_Port GPIOB
|
||||
#define DAC_2_VG_LDAC_Pin GPIO_PIN_9
|
||||
#define DAC_2_VG_LDAC_GPIO_Port GPIOB
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
||||
98
9_Firmware/9_2_FPGA/ad9484_interface_400m.v
Normal file
98
9_Firmware/9_2_FPGA/ad9484_interface_400m.v
Normal file
@@ -0,0 +1,98 @@
|
||||
module ad9484_interface_400m (
|
||||
// ADC Physical Interface (LVDS)
|
||||
input wire [7:0] adc_d_p, // ADC Data P
|
||||
input wire [7:0] adc_d_n, // ADC Data N
|
||||
input wire adc_dco_p, // Data Clock Output P (400MHz)
|
||||
input wire adc_dco_n, // Data Clock Output N (400MHz)
|
||||
|
||||
// System Interface
|
||||
input wire sys_clk, // 100MHz system clock (for control only)
|
||||
input wire reset_n,
|
||||
|
||||
// Output at 400MHz domain
|
||||
output wire [7:0] adc_data_400m, // ADC data at 400MHz
|
||||
output wire adc_data_valid_400m // Valid at 400MHz
|
||||
);
|
||||
|
||||
// LVDS to single-ended conversion
|
||||
wire [7:0] adc_data;
|
||||
wire adc_dco;
|
||||
|
||||
// IBUFDS for each data bit
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < 8; i = i + 1) begin : data_buffers
|
||||
IBUFDS #(
|
||||
.DIFF_TERM("TRUE"),
|
||||
.IOSTANDARD("LVDS_25")
|
||||
) ibufds_data (
|
||||
.O(adc_data[i]),
|
||||
.I(adc_d_p[i]),
|
||||
.IB(adc_d_n[i])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// IBUFDS for DCO
|
||||
IBUFDS #(
|
||||
.DIFF_TERM("TRUE"),
|
||||
.IOSTANDARD("LVDS_25")
|
||||
) ibufds_dco (
|
||||
.O(adc_dco),
|
||||
.I(adc_dco_p),
|
||||
.IB(adc_dco_n)
|
||||
);
|
||||
|
||||
// IDDR for capturing DDR data
|
||||
wire [7:0] adc_data_rise; // Data on rising edge
|
||||
wire [7:0] adc_data_fall; // Data on falling edge
|
||||
|
||||
genvar j;
|
||||
generate
|
||||
for (j = 0; j < 8; j = j + 1) begin : iddr_gen
|
||||
IDDR #(
|
||||
.DDR_CLK_EDGE("SAME_EDGE_PIPELINED"),
|
||||
.INIT_Q1(1'b0),
|
||||
.INIT_Q2(1'b0),
|
||||
.SRTYPE("SYNC")
|
||||
) iddr_inst (
|
||||
.Q1(adc_data_rise[j]), // Rising edge data
|
||||
.Q2(adc_data_fall[j]), // Falling edge data
|
||||
.C(adc_dco), // 400MHz DCO
|
||||
.CE(1'b1),
|
||||
.D(adc_data[j]),
|
||||
.R(1'b0),
|
||||
.S(1'b0)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Combine rising and falling edge data to get 400MSPS stream
|
||||
reg [7:0] adc_data_400m_reg;
|
||||
reg adc_data_valid_400m_reg;
|
||||
reg dco_phase;
|
||||
|
||||
always @(posedge adc_dco or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
adc_data_400m_reg <= 8'b0;
|
||||
adc_data_valid_400m_reg <= 1'b0;
|
||||
dco_phase <= 1'b0;
|
||||
end else begin
|
||||
dco_phase <= ~dco_phase;
|
||||
|
||||
if (dco_phase) begin
|
||||
// Output falling edge data (completes the 400MSPS stream)
|
||||
adc_data_400m_reg <= adc_data_fall;
|
||||
end else begin
|
||||
// Output rising edge data
|
||||
adc_data_400m_reg <= adc_data_rise;
|
||||
end
|
||||
|
||||
adc_data_valid_400m_reg <= 1'b1; // Always valid when ADC is running
|
||||
end
|
||||
end
|
||||
|
||||
assign adc_data_400m = adc_data_400m_reg;
|
||||
assign adc_data_valid_400m = adc_data_valid_400m_reg;
|
||||
|
||||
endmodule
|
||||
237
9_Firmware/9_2_FPGA/cdc_modules.v
Normal file
237
9_Firmware/9_2_FPGA/cdc_modules.v
Normal file
@@ -0,0 +1,237 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
// ============================================================================
|
||||
// CDC FOR MULTI-BIT DATA (ADVANCED)
|
||||
// ============================================================================
|
||||
module cdc_adc_to_processing #(
|
||||
parameter WIDTH = 8,
|
||||
parameter STAGES = 3
|
||||
)(
|
||||
input wire src_clk,
|
||||
input wire dst_clk,
|
||||
input wire reset_n,
|
||||
input wire [WIDTH-1:0] src_data,
|
||||
input wire src_valid,
|
||||
output wire [WIDTH-1:0] dst_data,
|
||||
output wire dst_valid
|
||||
);
|
||||
|
||||
// Gray encoding for safe CDC
|
||||
function [WIDTH-1:0] binary_to_gray;
|
||||
input [WIDTH-1:0] binary;
|
||||
binary_to_gray = binary ^ (binary >> 1);
|
||||
endfunction
|
||||
|
||||
function [WIDTH-1:0] gray_to_binary;
|
||||
input [WIDTH-1:0] gray;
|
||||
reg [WIDTH-1:0] binary;
|
||||
integer i;
|
||||
begin
|
||||
binary[WIDTH-1] = gray[WIDTH-1];
|
||||
for (i = WIDTH-2; i >= 0; i = i - 1) begin
|
||||
binary[i] = binary[i+1] ^ gray[i];
|
||||
end
|
||||
gray_to_binary = binary;
|
||||
end
|
||||
endfunction
|
||||
|
||||
// Source domain registers
|
||||
reg [WIDTH-1:0] src_data_reg;
|
||||
reg [1:0] src_toggle = 2'b00;
|
||||
reg src_toggle_sync = 0;
|
||||
|
||||
// Destination domain registers
|
||||
reg [WIDTH-1:0] dst_data_gray [0:STAGES-1];
|
||||
reg [1:0] dst_toggle_sync [0:STAGES-1];
|
||||
reg [WIDTH-1:0] dst_data_reg;
|
||||
reg dst_valid_reg = 0;
|
||||
reg [1:0] prev_dst_toggle = 2'b00;
|
||||
|
||||
always @(posedge src_clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
src_data_reg <= 0;
|
||||
src_toggle <= 2'b00;
|
||||
end else if (src_valid) begin
|
||||
src_data_reg <= src_data;
|
||||
src_toggle <= src_toggle + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// CDC synchronization chain for data
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < STAGES; i = i + 1) begin : data_sync_chain
|
||||
always @(posedge dst_clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
if (i == 0) begin
|
||||
dst_data_gray[i] <= 0;
|
||||
end else begin
|
||||
dst_data_gray[i] <= dst_data_gray[i-1];
|
||||
end
|
||||
end else begin
|
||||
if (i == 0) begin
|
||||
// Convert to gray code at domain crossing
|
||||
dst_data_gray[i] <= binary_to_gray(src_data_reg);
|
||||
end else begin
|
||||
dst_data_gray[i] <= dst_data_gray[i-1];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for (i = 0; i < STAGES; i = i + 1) begin : toggle_sync_chain
|
||||
always @(posedge dst_clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
if (i == 0) begin
|
||||
dst_toggle_sync[i] <= 2'b00;
|
||||
end else begin
|
||||
dst_toggle_sync[i] <= dst_toggle_sync[i-1];
|
||||
end
|
||||
end else begin
|
||||
if (i == 0) begin
|
||||
dst_toggle_sync[i] <= src_toggle;
|
||||
end else begin
|
||||
dst_toggle_sync[i] <= dst_toggle_sync[i-1];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Detect new data
|
||||
always @(posedge dst_clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
dst_data_reg <= 0;
|
||||
dst_valid_reg <= 0;
|
||||
prev_dst_toggle <= 2'b00;
|
||||
end else begin
|
||||
// Convert from gray code
|
||||
dst_data_reg <= gray_to_binary(dst_data_gray[STAGES-1]);
|
||||
|
||||
// Check if toggle changed (new data)
|
||||
if (dst_toggle_sync[STAGES-1] != prev_dst_toggle) begin
|
||||
dst_valid_reg <= 1'b1;
|
||||
prev_dst_toggle <= dst_toggle_sync[STAGES-1];
|
||||
end else begin
|
||||
dst_valid_reg <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign dst_data = dst_data_reg;
|
||||
assign dst_valid = dst_valid_reg;
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================================
|
||||
// CDC FOR SINGLE BIT SIGNALS
|
||||
// ============================================================================
|
||||
module cdc_single_bit #(
|
||||
parameter STAGES = 3
|
||||
)(
|
||||
input wire src_clk,
|
||||
input wire dst_clk,
|
||||
input wire reset_n,
|
||||
input wire src_signal,
|
||||
output wire dst_signal
|
||||
);
|
||||
|
||||
reg [STAGES-1:0] sync_chain;
|
||||
|
||||
always @(posedge dst_clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
sync_chain <= 0;
|
||||
end else begin
|
||||
sync_chain <= {sync_chain[STAGES-2:0], src_signal};
|
||||
end
|
||||
end
|
||||
|
||||
assign dst_signal = sync_chain[STAGES-1];
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================================
|
||||
// CDC FOR MULTI-BIT WITH HANDSHAKE
|
||||
// ============================================================================
|
||||
module cdc_handshake #(
|
||||
parameter WIDTH = 32
|
||||
)(
|
||||
input wire src_clk,
|
||||
input wire dst_clk,
|
||||
input wire reset_n,
|
||||
input wire [WIDTH-1:0] src_data,
|
||||
input wire src_valid,
|
||||
output wire src_ready,
|
||||
output wire [WIDTH-1:0] dst_data,
|
||||
output wire dst_valid,
|
||||
input wire dst_ready
|
||||
);
|
||||
|
||||
// Source domain
|
||||
reg [WIDTH-1:0] src_data_reg;
|
||||
reg src_busy = 0;
|
||||
reg src_ack_sync = 0;
|
||||
reg [1:0] src_ack_sync_chain = 2'b00;
|
||||
|
||||
// Destination domain
|
||||
reg [WIDTH-1:0] dst_data_reg;
|
||||
reg dst_valid_reg = 0;
|
||||
reg dst_req_sync = 0;
|
||||
reg [1:0] dst_req_sync_chain = 2'b00;
|
||||
reg dst_ack = 0;
|
||||
|
||||
// Source clock domain
|
||||
always @(posedge src_clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
src_data_reg <= 0;
|
||||
src_busy <= 0;
|
||||
src_ack_sync <= 0;
|
||||
src_ack_sync_chain <= 2'b00;
|
||||
end else begin
|
||||
// Sync acknowledge from destination
|
||||
src_ack_sync_chain <= {src_ack_sync_chain[0], dst_ack};
|
||||
src_ack_sync <= src_ack_sync_chain[1];
|
||||
|
||||
if (!src_busy && src_valid) begin
|
||||
src_data_reg <= src_data;
|
||||
src_busy <= 1'b1;
|
||||
end else if (src_busy && src_ack_sync) begin
|
||||
src_busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Destination clock domain
|
||||
always @(posedge dst_clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
dst_data_reg <= 0;
|
||||
dst_valid_reg <= 0;
|
||||
dst_req_sync <= 0;
|
||||
dst_req_sync_chain <= 2'b00;
|
||||
dst_ack <= 0;
|
||||
end else begin
|
||||
// Sync request from source
|
||||
dst_req_sync_chain <= {dst_req_sync_chain[0], src_busy};
|
||||
dst_req_sync <= dst_req_sync_chain[1];
|
||||
|
||||
// Capture data when request arrives
|
||||
if (dst_req_sync && !dst_valid_reg) begin
|
||||
dst_data_reg <= src_data_reg;
|
||||
dst_valid_reg <= 1'b1;
|
||||
dst_ack <= 1'b1;
|
||||
end else if (dst_valid_reg && dst_ready) begin
|
||||
dst_valid_reg <= 1'b0;
|
||||
end
|
||||
|
||||
// Clear acknowledge after source sees it
|
||||
if (dst_ack && !dst_req_sync) begin
|
||||
dst_ack <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign src_ready = !src_busy;
|
||||
assign dst_data = dst_data_reg;
|
||||
assign dst_valid = dst_valid_reg;
|
||||
|
||||
endmodule
|
||||
244
9_Firmware/9_2_FPGA/chirp_lut_init.v
Normal file
244
9_Firmware/9_2_FPGA/chirp_lut_init.v
Normal file
@@ -0,0 +1,244 @@
|
||||
// Auto-generated LUT initialization for PLFM chirp controller
|
||||
// Long chirp: 30us from 30MHz to 10MHz
|
||||
// Short chirp: 0.5us from 30MHz to 10MHz
|
||||
|
||||
// Long PLFM chirp LUT (30us, 30MHz to 10MHz)
|
||||
initial begin
|
||||
long_chirp_lut[ 0] = 8'd255; long_chirp_lut[ 1] = 8'd128; long_chirp_lut[ 2] = 8'd 1; long_chirp_lut[ 3] = 8'd127; long_chirp_lut[ 4] = 8'd254; long_chirp_lut[ 5] = 8'd128; long_chirp_lut[ 6] = 8'd 1; long_chirp_lut[ 7] = 8'd127; long_chirp_lut[ 8] = 8'd254; long_chirp_lut[ 9] = 8'd129; long_chirp_lut[ 10] = 8'd 1; long_chirp_lut[ 11] = 8'd125; long_chirp_lut[ 12] = 8'd254; long_chirp_lut[ 13] = 8'd131; long_chirp_lut[ 14] = 8'd 1; long_chirp_lut[ 15] = 8'd123;
|
||||
long_chirp_lut[ 16] = 8'd254; long_chirp_lut[ 17] = 8'd133; long_chirp_lut[ 18] = 8'd 1; long_chirp_lut[ 19] = 8'd121; long_chirp_lut[ 20] = 8'd254; long_chirp_lut[ 21] = 8'd136; long_chirp_lut[ 22] = 8'd 1; long_chirp_lut[ 23] = 8'd118; long_chirp_lut[ 24] = 8'd254; long_chirp_lut[ 25] = 8'd139; long_chirp_lut[ 26] = 8'd 1; long_chirp_lut[ 27] = 8'd114; long_chirp_lut[ 28] = 8'd254; long_chirp_lut[ 29] = 8'd143; long_chirp_lut[ 30] = 8'd 2; long_chirp_lut[ 31] = 8'd110;
|
||||
long_chirp_lut[ 32] = 8'd253; long_chirp_lut[ 33] = 8'd148; long_chirp_lut[ 34] = 8'd 2; long_chirp_lut[ 35] = 8'd105; long_chirp_lut[ 36] = 8'd252; long_chirp_lut[ 37] = 8'd153; long_chirp_lut[ 38] = 8'd 3; long_chirp_lut[ 39] = 8'd100; long_chirp_lut[ 40] = 8'd251; long_chirp_lut[ 41] = 8'd158; long_chirp_lut[ 42] = 8'd 5; long_chirp_lut[ 43] = 8'd 94; long_chirp_lut[ 44] = 8'd249; long_chirp_lut[ 45] = 8'd164; long_chirp_lut[ 46] = 8'd 6; long_chirp_lut[ 47] = 8'd 87;
|
||||
long_chirp_lut[ 48] = 8'd247; long_chirp_lut[ 49] = 8'd171; long_chirp_lut[ 50] = 8'd 9; long_chirp_lut[ 51] = 8'd 81; long_chirp_lut[ 52] = 8'd245; long_chirp_lut[ 53] = 8'd178; long_chirp_lut[ 54] = 8'd 12; long_chirp_lut[ 55] = 8'd 73; long_chirp_lut[ 56] = 8'd242; long_chirp_lut[ 57] = 8'd185; long_chirp_lut[ 58] = 8'd 15; long_chirp_lut[ 59] = 8'd 66; long_chirp_lut[ 60] = 8'd237; long_chirp_lut[ 61] = 8'd193; long_chirp_lut[ 62] = 8'd 20; long_chirp_lut[ 63] = 8'd 58;
|
||||
long_chirp_lut[ 64] = 8'd233; long_chirp_lut[ 65] = 8'd201; long_chirp_lut[ 66] = 8'd 25; long_chirp_lut[ 67] = 8'd 50; long_chirp_lut[ 68] = 8'd227; long_chirp_lut[ 69] = 8'd209; long_chirp_lut[ 70] = 8'd 31; long_chirp_lut[ 71] = 8'd 43; long_chirp_lut[ 72] = 8'd220; long_chirp_lut[ 73] = 8'd216; long_chirp_lut[ 74] = 8'd 39; long_chirp_lut[ 75] = 8'd 35; long_chirp_lut[ 76] = 8'd212; long_chirp_lut[ 77] = 8'd224; long_chirp_lut[ 78] = 8'd 47; long_chirp_lut[ 79] = 8'd 27;
|
||||
long_chirp_lut[ 80] = 8'd203; long_chirp_lut[ 81] = 8'd231; long_chirp_lut[ 82] = 8'd 57; long_chirp_lut[ 83] = 8'd 20; long_chirp_lut[ 84] = 8'd193; long_chirp_lut[ 85] = 8'd238; long_chirp_lut[ 86] = 8'd 67; long_chirp_lut[ 87] = 8'd 14; long_chirp_lut[ 88] = 8'd182; long_chirp_lut[ 89] = 8'd244; long_chirp_lut[ 90] = 8'd 79; long_chirp_lut[ 91] = 8'd 9; long_chirp_lut[ 92] = 8'd170; long_chirp_lut[ 93] = 8'd248; long_chirp_lut[ 94] = 8'd 92; long_chirp_lut[ 95] = 8'd 5;
|
||||
long_chirp_lut[ 96] = 8'd157; long_chirp_lut[ 97] = 8'd252; long_chirp_lut[ 98] = 8'd106; long_chirp_lut[ 99] = 8'd 2; long_chirp_lut[100] = 8'd142; long_chirp_lut[101] = 8'd254; long_chirp_lut[102] = 8'd120; long_chirp_lut[103] = 8'd 1; long_chirp_lut[104] = 8'd127; long_chirp_lut[105] = 8'd254; long_chirp_lut[106] = 8'd136; long_chirp_lut[107] = 8'd 1; long_chirp_lut[108] = 8'd112; long_chirp_lut[109] = 8'd253; long_chirp_lut[110] = 8'd151; long_chirp_lut[111] = 8'd 4;
|
||||
long_chirp_lut[112] = 8'd 96; long_chirp_lut[113] = 8'd249; long_chirp_lut[114] = 8'd167; long_chirp_lut[115] = 8'd 8; long_chirp_lut[116] = 8'd 80; long_chirp_lut[117] = 8'd243; long_chirp_lut[118] = 8'd183; long_chirp_lut[119] = 8'd 15; long_chirp_lut[120] = 8'd 64; long_chirp_lut[121] = 8'd235; long_chirp_lut[122] = 8'd199; long_chirp_lut[123] = 8'd 25; long_chirp_lut[124] = 8'd 49; long_chirp_lut[125] = 8'd224; long_chirp_lut[126] = 8'd213; long_chirp_lut[127] = 8'd 37;
|
||||
long_chirp_lut[128] = 8'd 35; long_chirp_lut[129] = 8'd211; long_chirp_lut[130] = 8'd226; long_chirp_lut[131] = 8'd 51; long_chirp_lut[132] = 8'd 23; long_chirp_lut[133] = 8'd196; long_chirp_lut[134] = 8'd237; long_chirp_lut[135] = 8'd 68; long_chirp_lut[136] = 8'd 13; long_chirp_lut[137] = 8'd178; long_chirp_lut[138] = 8'd246; long_chirp_lut[139] = 8'd 86; long_chirp_lut[140] = 8'd 6; long_chirp_lut[141] = 8'd159; long_chirp_lut[142] = 8'd252; long_chirp_lut[143] = 8'd106;
|
||||
long_chirp_lut[144] = 8'd 2; long_chirp_lut[145] = 8'd138; long_chirp_lut[146] = 8'd254; long_chirp_lut[147] = 8'd128; long_chirp_lut[148] = 8'd 1; long_chirp_lut[149] = 8'd116; long_chirp_lut[150] = 8'd253; long_chirp_lut[151] = 8'd150; long_chirp_lut[152] = 8'd 4; long_chirp_lut[153] = 8'd 94; long_chirp_lut[154] = 8'd249; long_chirp_lut[155] = 8'd171; long_chirp_lut[156] = 8'd 10; long_chirp_lut[157] = 8'd 73; long_chirp_lut[158] = 8'd240; long_chirp_lut[159] = 8'd192;
|
||||
long_chirp_lut[160] = 8'd 21; long_chirp_lut[161] = 8'd 53; long_chirp_lut[162] = 8'd227; long_chirp_lut[163] = 8'd212; long_chirp_lut[164] = 8'd 36; long_chirp_lut[165] = 8'd 35; long_chirp_lut[166] = 8'd210; long_chirp_lut[167] = 8'd228; long_chirp_lut[168] = 8'd 55; long_chirp_lut[169] = 8'd 20; long_chirp_lut[170] = 8'd189; long_chirp_lut[171] = 8'd241; long_chirp_lut[172] = 8'd 77; long_chirp_lut[173] = 8'd 9; long_chirp_lut[174] = 8'd166; long_chirp_lut[175] = 8'd250;
|
||||
long_chirp_lut[176] = 8'd101; long_chirp_lut[177] = 8'd 2; long_chirp_lut[178] = 8'd141; long_chirp_lut[179] = 8'd254; long_chirp_lut[180] = 8'd127; long_chirp_lut[181] = 8'd 1; long_chirp_lut[182] = 8'd114; long_chirp_lut[183] = 8'd253; long_chirp_lut[184] = 8'd154; long_chirp_lut[185] = 8'd 5; long_chirp_lut[186] = 8'd 88; long_chirp_lut[187] = 8'd246; long_chirp_lut[188] = 8'd180; long_chirp_lut[189] = 8'd 15; long_chirp_lut[190] = 8'd 62; long_chirp_lut[191] = 8'd233;
|
||||
long_chirp_lut[192] = 8'd204; long_chirp_lut[193] = 8'd 31; long_chirp_lut[194] = 8'd 40; long_chirp_lut[195] = 8'd214; long_chirp_lut[196] = 8'd225; long_chirp_lut[197] = 8'd 52; long_chirp_lut[198] = 8'd 21; long_chirp_lut[199] = 8'd191; long_chirp_lut[200] = 8'd241; long_chirp_lut[201] = 8'd 77; long_chirp_lut[202] = 8'd 8; long_chirp_lut[203] = 8'd164; long_chirp_lut[204] = 8'd251; long_chirp_lut[205] = 8'd106; long_chirp_lut[206] = 8'd 1; long_chirp_lut[207] = 8'd134;
|
||||
long_chirp_lut[208] = 8'd254; long_chirp_lut[209] = 8'd136; long_chirp_lut[210] = 8'd 2; long_chirp_lut[211] = 8'd103; long_chirp_lut[212] = 8'd250; long_chirp_lut[213] = 8'd167; long_chirp_lut[214] = 8'd 9; long_chirp_lut[215] = 8'd 73; long_chirp_lut[216] = 8'd239; long_chirp_lut[217] = 8'd196; long_chirp_lut[218] = 8'd 25; long_chirp_lut[219] = 8'd 46; long_chirp_lut[220] = 8'd220; long_chirp_lut[221] = 8'd220; long_chirp_lut[222] = 8'd 47; long_chirp_lut[223] = 8'd 24;
|
||||
long_chirp_lut[224] = 8'd195; long_chirp_lut[225] = 8'd240; long_chirp_lut[226] = 8'd 75; long_chirp_lut[227] = 8'd 9; long_chirp_lut[228] = 8'd164; long_chirp_lut[229] = 8'd251; long_chirp_lut[230] = 8'd107; long_chirp_lut[231] = 8'd 1; long_chirp_lut[232] = 8'd131; long_chirp_lut[233] = 8'd254; long_chirp_lut[234] = 8'd141; long_chirp_lut[235] = 8'd 3; long_chirp_lut[236] = 8'd 96; long_chirp_lut[237] = 8'd248; long_chirp_lut[238] = 8'd175; long_chirp_lut[239] = 8'd 13;
|
||||
long_chirp_lut[240] = 8'd 64; long_chirp_lut[241] = 8'd233; long_chirp_lut[242] = 8'd206; long_chirp_lut[243] = 8'd 33; long_chirp_lut[244] = 8'd 36; long_chirp_lut[245] = 8'd209; long_chirp_lut[246] = 8'd231; long_chirp_lut[247] = 8'd 61; long_chirp_lut[248] = 8'd 15; long_chirp_lut[249] = 8'd178; long_chirp_lut[250] = 8'd247; long_chirp_lut[251] = 8'd 95; long_chirp_lut[252] = 8'd 3; long_chirp_lut[253] = 8'd142; long_chirp_lut[254] = 8'd254; long_chirp_lut[255] = 8'd132;
|
||||
long_chirp_lut[256] = 8'd 1; long_chirp_lut[257] = 8'd105; long_chirp_lut[258] = 8'd250; long_chirp_lut[259] = 8'd169; long_chirp_lut[260] = 8'd 11; long_chirp_lut[261] = 8'd 69; long_chirp_lut[262] = 8'd235; long_chirp_lut[263] = 8'd203; long_chirp_lut[264] = 8'd 31; long_chirp_lut[265] = 8'd 37; long_chirp_lut[266] = 8'd210; long_chirp_lut[267] = 8'd230; long_chirp_lut[268] = 8'd 61; long_chirp_lut[269] = 8'd 14; long_chirp_lut[270] = 8'd176; long_chirp_lut[271] = 8'd248;
|
||||
long_chirp_lut[272] = 8'd 98; long_chirp_lut[273] = 8'd 2; long_chirp_lut[274] = 8'd137; long_chirp_lut[275] = 8'd254; long_chirp_lut[276] = 8'd138; long_chirp_lut[277] = 8'd 2; long_chirp_lut[278] = 8'd 97; long_chirp_lut[279] = 8'd248; long_chirp_lut[280] = 8'd178; long_chirp_lut[281] = 8'd 15; long_chirp_lut[282] = 8'd 59; long_chirp_lut[283] = 8'd228; long_chirp_lut[284] = 8'd213; long_chirp_lut[285] = 8'd 41; long_chirp_lut[286] = 8'd 28; long_chirp_lut[287] = 8'd198;
|
||||
long_chirp_lut[288] = 8'd239; long_chirp_lut[289] = 8'd 76; long_chirp_lut[290] = 8'd 8; long_chirp_lut[291] = 8'd159; long_chirp_lut[292] = 8'd253; long_chirp_lut[293] = 8'd117; long_chirp_lut[294] = 8'd 1; long_chirp_lut[295] = 8'd116; long_chirp_lut[296] = 8'd253; long_chirp_lut[297] = 8'd161; long_chirp_lut[298] = 8'd 8; long_chirp_lut[299] = 8'd 74; long_chirp_lut[300] = 8'd237; long_chirp_lut[301] = 8'd200; long_chirp_lut[302] = 8'd 30; long_chirp_lut[303] = 8'd 38;
|
||||
long_chirp_lut[304] = 8'd209; long_chirp_lut[305] = 8'd232; long_chirp_lut[306] = 8'd 65; long_chirp_lut[307] = 8'd 12; long_chirp_lut[308] = 8'd170; long_chirp_lut[309] = 8'd251; long_chirp_lut[310] = 8'd107; long_chirp_lut[311] = 8'd 1; long_chirp_lut[312] = 8'd125; long_chirp_lut[313] = 8'd254; long_chirp_lut[314] = 8'd153; long_chirp_lut[315] = 8'd 6; long_chirp_lut[316] = 8'd 80; long_chirp_lut[317] = 8'd240; long_chirp_lut[318] = 8'd196; long_chirp_lut[319] = 8'd 27;
|
||||
long_chirp_lut[320] = 8'd 40; long_chirp_lut[321] = 8'd211; long_chirp_lut[322] = 8'd230; long_chirp_lut[323] = 8'd 63; long_chirp_lut[324] = 8'd 13; long_chirp_lut[325] = 8'd171; long_chirp_lut[326] = 8'd251; long_chirp_lut[327] = 8'd108; long_chirp_lut[328] = 8'd 1; long_chirp_lut[329] = 8'd123; long_chirp_lut[330] = 8'd253; long_chirp_lut[331] = 8'd156; long_chirp_lut[332] = 8'd 7; long_chirp_lut[333] = 8'd 76; long_chirp_lut[334] = 8'd238; long_chirp_lut[335] = 8'd201;
|
||||
long_chirp_lut[336] = 8'd 31; long_chirp_lut[337] = 8'd 36; long_chirp_lut[338] = 8'd206; long_chirp_lut[339] = 8'd235; long_chirp_lut[340] = 8'd 71; long_chirp_lut[341] = 8'd 9; long_chirp_lut[342] = 8'd161; long_chirp_lut[343] = 8'd253; long_chirp_lut[344] = 8'd119; long_chirp_lut[345] = 8'd 1; long_chirp_lut[346] = 8'd111; long_chirp_lut[347] = 8'd251; long_chirp_lut[348] = 8'd169; long_chirp_lut[349] = 8'd 12; long_chirp_lut[350] = 8'd 62; long_chirp_lut[351] = 8'd229;
|
||||
long_chirp_lut[352] = 8'd213; long_chirp_lut[353] = 8'd 43; long_chirp_lut[354] = 8'd 24; long_chirp_lut[355] = 8'd191; long_chirp_lut[356] = 8'd244; long_chirp_lut[357] = 8'd 88; long_chirp_lut[358] = 8'd 3; long_chirp_lut[359] = 8'd141; long_chirp_lut[360] = 8'd255; long_chirp_lut[361] = 8'd141; long_chirp_lut[362] = 8'd 3; long_chirp_lut[363] = 8'd 88; long_chirp_lut[364] = 8'd243; long_chirp_lut[365] = 8'd191; long_chirp_lut[366] = 8'd 25; long_chirp_lut[367] = 8'd 42;
|
||||
long_chirp_lut[368] = 8'd212; long_chirp_lut[369] = 8'd231; long_chirp_lut[370] = 8'd 66; long_chirp_lut[371] = 8'd 11; long_chirp_lut[372] = 8'd164; long_chirp_lut[373] = 8'd252; long_chirp_lut[374] = 8'd118; long_chirp_lut[375] = 8'd 1; long_chirp_lut[376] = 8'd110; long_chirp_lut[377] = 8'd251; long_chirp_lut[378] = 8'd172; long_chirp_lut[379] = 8'd 14; long_chirp_lut[380] = 8'd 58; long_chirp_lut[381] = 8'd225; long_chirp_lut[382] = 8'd219; long_chirp_lut[383] = 8'd 50;
|
||||
long_chirp_lut[384] = 8'd 19; long_chirp_lut[385] = 8'd181; long_chirp_lut[386] = 8'd248; long_chirp_lut[387] = 8'd101; long_chirp_lut[388] = 8'd 1; long_chirp_lut[389] = 8'd125; long_chirp_lut[390] = 8'd253; long_chirp_lut[391] = 8'd158; long_chirp_lut[392] = 8'd 9; long_chirp_lut[393] = 8'd 70; long_chirp_lut[394] = 8'd233; long_chirp_lut[395] = 8'd209; long_chirp_lut[396] = 8'd 41; long_chirp_lut[397] = 8'd 26; long_chirp_lut[398] = 8'd191; long_chirp_lut[399] = 8'd244;
|
||||
long_chirp_lut[400] = 8'd 91; long_chirp_lut[401] = 8'd 2; long_chirp_lut[402] = 8'd135; long_chirp_lut[403] = 8'd254; long_chirp_lut[404] = 8'd150; long_chirp_lut[405] = 8'd 6; long_chirp_lut[406] = 8'd 77; long_chirp_lut[407] = 8'd237; long_chirp_lut[408] = 8'd204; long_chirp_lut[409] = 8'd 36; long_chirp_lut[410] = 8'd 29; long_chirp_lut[411] = 8'd195; long_chirp_lut[412] = 8'd242; long_chirp_lut[413] = 8'd 87; long_chirp_lut[414] = 8'd 3; long_chirp_lut[415] = 8'd138;
|
||||
long_chirp_lut[416] = 8'd254; long_chirp_lut[417] = 8'd148; long_chirp_lut[418] = 8'd 5; long_chirp_lut[419] = 8'd 78; long_chirp_lut[420] = 8'd237; long_chirp_lut[421] = 8'd204; long_chirp_lut[422] = 8'd 36; long_chirp_lut[423] = 8'd 29; long_chirp_lut[424] = 8'd195; long_chirp_lut[425] = 8'd243; long_chirp_lut[426] = 8'd 89; long_chirp_lut[427] = 8'd 3; long_chirp_lut[428] = 8'd135; long_chirp_lut[429] = 8'd254; long_chirp_lut[430] = 8'd151; long_chirp_lut[431] = 8'd 7;
|
||||
long_chirp_lut[432] = 8'd 73; long_chirp_lut[433] = 8'd235; long_chirp_lut[434] = 8'd209; long_chirp_lut[435] = 8'd 41; long_chirp_lut[436] = 8'd 25; long_chirp_lut[437] = 8'd188; long_chirp_lut[438] = 8'd246; long_chirp_lut[439] = 8'd 97; long_chirp_lut[440] = 8'd 1; long_chirp_lut[441] = 8'd126; long_chirp_lut[442] = 8'd253; long_chirp_lut[443] = 8'd161; long_chirp_lut[444] = 8'd 10; long_chirp_lut[445] = 8'd 64; long_chirp_lut[446] = 8'd228; long_chirp_lut[447] = 8'd217;
|
||||
long_chirp_lut[448] = 8'd 50; long_chirp_lut[449] = 8'd 18; long_chirp_lut[450] = 8'd176; long_chirp_lut[451] = 8'd250; long_chirp_lut[452] = 8'd111; long_chirp_lut[453] = 8'd 1; long_chirp_lut[454] = 8'd111; long_chirp_lut[455] = 8'd250; long_chirp_lut[456] = 8'd177; long_chirp_lut[457] = 8'd 18; long_chirp_lut[458] = 8'd 49; long_chirp_lut[459] = 8'd216; long_chirp_lut[460] = 8'd229; long_chirp_lut[461] = 8'd 66; long_chirp_lut[462] = 8'd 9; long_chirp_lut[463] = 8'd157;
|
||||
long_chirp_lut[464] = 8'd254; long_chirp_lut[465] = 8'd132; long_chirp_lut[466] = 8'd 2; long_chirp_lut[467] = 8'd 90; long_chirp_lut[468] = 8'd242; long_chirp_lut[469] = 8'd197; long_chirp_lut[470] = 8'd 31; long_chirp_lut[471] = 8'd 32; long_chirp_lut[472] = 8'd198; long_chirp_lut[473] = 8'd242; long_chirp_lut[474] = 8'd 89; long_chirp_lut[475] = 8'd 2; long_chirp_lut[476] = 8'd132; long_chirp_lut[477] = 8'd254; long_chirp_lut[478] = 8'd158; long_chirp_lut[479] = 8'd 10;
|
||||
long_chirp_lut[480] = 8'd 64; long_chirp_lut[481] = 8'd228; long_chirp_lut[482] = 8'd219; long_chirp_lut[483] = 8'd 53; long_chirp_lut[484] = 8'd 15; long_chirp_lut[485] = 8'd171; long_chirp_lut[486] = 8'd252; long_chirp_lut[487] = 8'd120; long_chirp_lut[488] = 8'd 1; long_chirp_lut[489] = 8'd100; long_chirp_lut[490] = 8'd246; long_chirp_lut[491] = 8'd189; long_chirp_lut[492] = 8'd 26; long_chirp_lut[493] = 8'd 37; long_chirp_lut[494] = 8'd203; long_chirp_lut[495] = 8'd240;
|
||||
long_chirp_lut[496] = 8'd 84; long_chirp_lut[497] = 8'd 3; long_chirp_lut[498] = 8'd135; long_chirp_lut[499] = 8'd254; long_chirp_lut[500] = 8'd157; long_chirp_lut[501] = 8'd 9; long_chirp_lut[502] = 8'd 64; long_chirp_lut[503] = 8'd227; long_chirp_lut[504] = 8'd220; long_chirp_lut[505] = 8'd 55; long_chirp_lut[506] = 8'd 14; long_chirp_lut[507] = 8'd167; long_chirp_lut[508] = 8'd253; long_chirp_lut[509] = 8'd125; long_chirp_lut[510] = 8'd 2; long_chirp_lut[511] = 8'd 92;
|
||||
long_chirp_lut[512] = 8'd243; long_chirp_lut[513] = 8'd197; long_chirp_lut[514] = 8'd 33; long_chirp_lut[515] = 8'd 30; long_chirp_lut[516] = 8'd193; long_chirp_lut[517] = 8'd245; long_chirp_lut[518] = 8'd 97; long_chirp_lut[519] = 8'd 1; long_chirp_lut[520] = 8'd120; long_chirp_lut[521] = 8'd252; long_chirp_lut[522] = 8'd172; long_chirp_lut[523] = 8'd 17; long_chirp_lut[524] = 8'd 49; long_chirp_lut[525] = 8'd214; long_chirp_lut[526] = 8'd232; long_chirp_lut[527] = 8'd 73;
|
||||
long_chirp_lut[528] = 8'd 6; long_chirp_lut[529] = 8'd145; long_chirp_lut[530] = 8'd254; long_chirp_lut[531] = 8'd149; long_chirp_lut[532] = 8'd 7; long_chirp_lut[533] = 8'd 69; long_chirp_lut[534] = 8'd230; long_chirp_lut[535] = 8'd218; long_chirp_lut[536] = 8'd 53; long_chirp_lut[537] = 8'd 14; long_chirp_lut[538] = 8'd167; long_chirp_lut[539] = 8'd253; long_chirp_lut[540] = 8'd127; long_chirp_lut[541] = 8'd 2; long_chirp_lut[542] = 8'd 88; long_chirp_lut[543] = 8'd241;
|
||||
long_chirp_lut[544] = 8'd202; long_chirp_lut[545] = 8'd 38; long_chirp_lut[546] = 8'd 24; long_chirp_lut[547] = 8'd184; long_chirp_lut[548] = 8'd249; long_chirp_lut[549] = 8'd109; long_chirp_lut[550] = 8'd 1; long_chirp_lut[551] = 8'd105; long_chirp_lut[552] = 8'd247; long_chirp_lut[553] = 8'd188; long_chirp_lut[554] = 8'd 27; long_chirp_lut[555] = 8'd 35; long_chirp_lut[556] = 8'd198; long_chirp_lut[557] = 8'd243; long_chirp_lut[558] = 8'd 94; long_chirp_lut[559] = 8'd 1;
|
||||
long_chirp_lut[560] = 8'd120; long_chirp_lut[561] = 8'd251; long_chirp_lut[562] = 8'd175; long_chirp_lut[563] = 8'd 19; long_chirp_lut[564] = 8'd 45; long_chirp_lut[565] = 8'd209; long_chirp_lut[566] = 8'd237; long_chirp_lut[567] = 8'd 82; long_chirp_lut[568] = 8'd 3; long_chirp_lut[569] = 8'd132; long_chirp_lut[570] = 8'd253; long_chirp_lut[571] = 8'd165; long_chirp_lut[572] = 8'd 14; long_chirp_lut[573] = 8'd 53; long_chirp_lut[574] = 8'd216; long_chirp_lut[575] = 8'd232;
|
||||
long_chirp_lut[576] = 8'd 73; long_chirp_lut[577] = 8'd 5; long_chirp_lut[578] = 8'd141; long_chirp_lut[579] = 8'd254; long_chirp_lut[580] = 8'd157; long_chirp_lut[581] = 8'd 11; long_chirp_lut[582] = 8'd 59; long_chirp_lut[583] = 8'd221; long_chirp_lut[584] = 8'd228; long_chirp_lut[585] = 8'd 68; long_chirp_lut[586] = 8'd 7; long_chirp_lut[587] = 8'd146; long_chirp_lut[588] = 8'd254; long_chirp_lut[589] = 8'd152; long_chirp_lut[590] = 8'd 9; long_chirp_lut[591] = 8'd 63;
|
||||
long_chirp_lut[592] = 8'd224; long_chirp_lut[593] = 8'd225; long_chirp_lut[594] = 8'd 65; long_chirp_lut[595] = 8'd 8; long_chirp_lut[596] = 8'd149; long_chirp_lut[597] = 8'd254; long_chirp_lut[598] = 8'd150; long_chirp_lut[599] = 8'd 8; long_chirp_lut[600] = 8'd 64; long_chirp_lut[601] = 8'd225; long_chirp_lut[602] = 8'd225; long_chirp_lut[603] = 8'd 64; long_chirp_lut[604] = 8'd 8; long_chirp_lut[605] = 8'd149; long_chirp_lut[606] = 8'd254; long_chirp_lut[607] = 8'd150;
|
||||
long_chirp_lut[608] = 8'd 9; long_chirp_lut[609] = 8'd 63; long_chirp_lut[610] = 8'd224; long_chirp_lut[611] = 8'd226; long_chirp_lut[612] = 8'd 66; long_chirp_lut[613] = 8'd 7; long_chirp_lut[614] = 8'd146; long_chirp_lut[615] = 8'd254; long_chirp_lut[616] = 8'd154; long_chirp_lut[617] = 8'd 10; long_chirp_lut[618] = 8'd 59; long_chirp_lut[619] = 8'd220; long_chirp_lut[620] = 8'd229; long_chirp_lut[621] = 8'd 71; long_chirp_lut[622] = 8'd 5; long_chirp_lut[623] = 8'd140;
|
||||
long_chirp_lut[624] = 8'd254; long_chirp_lut[625] = 8'd161; long_chirp_lut[626] = 8'd 13; long_chirp_lut[627] = 8'd 53; long_chirp_lut[628] = 8'd215; long_chirp_lut[629] = 8'd234; long_chirp_lut[630] = 8'd 79; long_chirp_lut[631] = 8'd 3; long_chirp_lut[632] = 8'd131; long_chirp_lut[633] = 8'd253; long_chirp_lut[634] = 8'd170; long_chirp_lut[635] = 8'd 18; long_chirp_lut[636] = 8'd 45; long_chirp_lut[637] = 8'd207; long_chirp_lut[638] = 8'd240; long_chirp_lut[639] = 8'd 90;
|
||||
long_chirp_lut[640] = 8'd 1; long_chirp_lut[641] = 8'd119; long_chirp_lut[642] = 8'd250; long_chirp_lut[643] = 8'd182; long_chirp_lut[644] = 8'd 25; long_chirp_lut[645] = 8'd 35; long_chirp_lut[646] = 8'd195; long_chirp_lut[647] = 8'd246; long_chirp_lut[648] = 8'd104; long_chirp_lut[649] = 8'd 1; long_chirp_lut[650] = 8'd104; long_chirp_lut[651] = 8'd246; long_chirp_lut[652] = 8'd196; long_chirp_lut[653] = 8'd 35; long_chirp_lut[654] = 8'd 24; long_chirp_lut[655] = 8'd181;
|
||||
long_chirp_lut[656] = 8'd251; long_chirp_lut[657] = 8'd121; long_chirp_lut[658] = 8'd 2; long_chirp_lut[659] = 8'd 86; long_chirp_lut[660] = 8'd237; long_chirp_lut[661] = 8'd211; long_chirp_lut[662] = 8'd 49; long_chirp_lut[663] = 8'd 14; long_chirp_lut[664] = 8'd162; long_chirp_lut[665] = 8'd254; long_chirp_lut[666] = 8'd141; long_chirp_lut[667] = 8'd 6; long_chirp_lut[668] = 8'd 67; long_chirp_lut[669] = 8'd225; long_chirp_lut[670] = 8'd226; long_chirp_lut[671] = 8'd 68;
|
||||
long_chirp_lut[672] = 8'd 6; long_chirp_lut[673] = 8'd140; long_chirp_lut[674] = 8'd254; long_chirp_lut[675] = 8'd164; long_chirp_lut[676] = 8'd 16; long_chirp_lut[677] = 8'd 47; long_chirp_lut[678] = 8'd208; long_chirp_lut[679] = 8'd240; long_chirp_lut[680] = 8'd 91; long_chirp_lut[681] = 8'd 1; long_chirp_lut[682] = 8'd114; long_chirp_lut[683] = 8'd249; long_chirp_lut[684] = 8'd189; long_chirp_lut[685] = 8'd 31; long_chirp_lut[686] = 8'd 28; long_chirp_lut[687] = 8'd185;
|
||||
long_chirp_lut[688] = 8'd250; long_chirp_lut[689] = 8'd119; long_chirp_lut[690] = 8'd 2; long_chirp_lut[691] = 8'd 86; long_chirp_lut[692] = 8'd237; long_chirp_lut[693] = 8'd213; long_chirp_lut[694] = 8'd 52; long_chirp_lut[695] = 8'd 12; long_chirp_lut[696] = 8'd157; long_chirp_lut[697] = 8'd254; long_chirp_lut[698] = 8'd150; long_chirp_lut[699] = 8'd 9; long_chirp_lut[700] = 8'd 58; long_chirp_lut[701] = 8'd217; long_chirp_lut[702] = 8'd234; long_chirp_lut[703] = 8'd 81;
|
||||
long_chirp_lut[704] = 8'd 2; long_chirp_lut[705] = 8'd123; long_chirp_lut[706] = 8'd251; long_chirp_lut[707] = 8'd182; long_chirp_lut[708] = 8'd 26; long_chirp_lut[709] = 8'd 32; long_chirp_lut[710] = 8'd189; long_chirp_lut[711] = 8'd249; long_chirp_lut[712] = 8'd115; long_chirp_lut[713] = 8'd 1; long_chirp_lut[714] = 8'd 88; long_chirp_lut[715] = 8'd237; long_chirp_lut[716] = 8'd213; long_chirp_lut[717] = 8'd 53; long_chirp_lut[718] = 8'd 11; long_chirp_lut[719] = 8'd154;
|
||||
long_chirp_lut[720] = 8'd255; long_chirp_lut[721] = 8'd154; long_chirp_lut[722] = 8'd 12; long_chirp_lut[723] = 8'd 53; long_chirp_lut[724] = 8'd212; long_chirp_lut[725] = 8'd238; long_chirp_lut[726] = 8'd 89; long_chirp_lut[727] = 8'd 1; long_chirp_lut[728] = 8'd113; long_chirp_lut[729] = 8'd248; long_chirp_lut[730] = 8'd193; long_chirp_lut[731] = 8'd 35; long_chirp_lut[732] = 8'd 23; long_chirp_lut[733] = 8'd176; long_chirp_lut[734] = 8'd252; long_chirp_lut[735] = 8'd132;
|
||||
long_chirp_lut[736] = 8'd 4; long_chirp_lut[737] = 8'd 71; long_chirp_lut[738] = 8'd227; long_chirp_lut[739] = 8'd226; long_chirp_lut[740] = 8'd 71; long_chirp_lut[741] = 8'd 4; long_chirp_lut[742] = 8'd132; long_chirp_lut[743] = 8'd252; long_chirp_lut[744] = 8'd177; long_chirp_lut[745] = 8'd 24; long_chirp_lut[746] = 8'd 34; long_chirp_lut[747] = 8'd191; long_chirp_lut[748] = 8'd249; long_chirp_lut[749] = 8'd116; long_chirp_lut[750] = 8'd 2; long_chirp_lut[751] = 8'd 84;
|
||||
long_chirp_lut[752] = 8'd235; long_chirp_lut[753] = 8'd217; long_chirp_lut[754] = 8'd 60; long_chirp_lut[755] = 8'd 8; long_chirp_lut[756] = 8'd143; long_chirp_lut[757] = 8'd254; long_chirp_lut[758] = 8'd167; long_chirp_lut[759] = 8'd 18; long_chirp_lut[760] = 8'd 40; long_chirp_lut[761] = 8'd199; long_chirp_lut[762] = 8'd246; long_chirp_lut[763] = 8'd109; long_chirp_lut[764] = 8'd 1; long_chirp_lut[765] = 8'd 91; long_chirp_lut[766] = 8'd238; long_chirp_lut[767] = 8'd213;
|
||||
long_chirp_lut[768] = 8'd 55; long_chirp_lut[769] = 8'd 10; long_chirp_lut[770] = 8'd148; long_chirp_lut[771] = 8'd254; long_chirp_lut[772] = 8'd164; long_chirp_lut[773] = 8'd 17; long_chirp_lut[774] = 8'd 42; long_chirp_lut[775] = 8'd200; long_chirp_lut[776] = 8'd245; long_chirp_lut[777] = 8'd108; long_chirp_lut[778] = 8'd 1; long_chirp_lut[779] = 8'd 90; long_chirp_lut[780] = 8'd237; long_chirp_lut[781] = 8'd214; long_chirp_lut[782] = 8'd 57; long_chirp_lut[783] = 8'd 9;
|
||||
long_chirp_lut[784] = 8'd145; long_chirp_lut[785] = 8'd254; long_chirp_lut[786] = 8'd167; long_chirp_lut[787] = 8'd 19; long_chirp_lut[788] = 8'd 38; long_chirp_lut[789] = 8'd195; long_chirp_lut[790] = 8'd247; long_chirp_lut[791] = 8'd114; long_chirp_lut[792] = 8'd 2; long_chirp_lut[793] = 8'd 83; long_chirp_lut[794] = 8'd233; long_chirp_lut[795] = 8'd220; long_chirp_lut[796] = 8'd 64; long_chirp_lut[797] = 8'd 6; long_chirp_lut[798] = 8'd135; long_chirp_lut[799] = 8'd253;
|
||||
long_chirp_lut[800] = 8'd178; long_chirp_lut[801] = 8'd 26; long_chirp_lut[802] = 8'd 30; long_chirp_lut[803] = 8'd184; long_chirp_lut[804] = 8'd251; long_chirp_lut[805] = 8'd128; long_chirp_lut[806] = 8'd 4; long_chirp_lut[807] = 8'd 70; long_chirp_lut[808] = 8'd224; long_chirp_lut[809] = 8'd230; long_chirp_lut[810] = 8'd 79; long_chirp_lut[811] = 8'd 2; long_chirp_lut[812] = 8'd117; long_chirp_lut[813] = 8'd248; long_chirp_lut[814] = 8'd194; long_chirp_lut[815] = 8'd 38;
|
||||
long_chirp_lut[816] = 8'd 19; long_chirp_lut[817] = 8'd166; long_chirp_lut[818] = 8'd254; long_chirp_lut[819] = 8'd149; long_chirp_lut[820] = 8'd 11; long_chirp_lut[821] = 8'd 51; long_chirp_lut[822] = 8'd208; long_chirp_lut[823] = 8'd242; long_chirp_lut[824] = 8'd101; long_chirp_lut[825] = 8'd 1; long_chirp_lut[826] = 8'd 93; long_chirp_lut[827] = 8'd238; long_chirp_lut[828] = 8'd214; long_chirp_lut[829] = 8'd 58; long_chirp_lut[830] = 8'd 8; long_chirp_lut[831] = 8'd139;
|
||||
long_chirp_lut[832] = 8'd253; long_chirp_lut[833] = 8'd176; long_chirp_lut[834] = 8'd 25; long_chirp_lut[835] = 8'd 30; long_chirp_lut[836] = 8'd183; long_chirp_lut[837] = 8'd252; long_chirp_lut[838] = 8'd132; long_chirp_lut[839] = 8'd 5; long_chirp_lut[840] = 8'd 64; long_chirp_lut[841] = 8'd219; long_chirp_lut[842] = 8'd235; long_chirp_lut[843] = 8'd 88; long_chirp_lut[844] = 8'd 1; long_chirp_lut[845] = 8'd105; long_chirp_lut[846] = 8'd243; long_chirp_lut[847] = 8'd206;
|
||||
long_chirp_lut[848] = 8'd 50; long_chirp_lut[849] = 8'd 11; long_chirp_lut[850] = 8'd148; long_chirp_lut[851] = 8'd254; long_chirp_lut[852] = 8'd169; long_chirp_lut[853] = 8'd 21; long_chirp_lut[854] = 8'd 34; long_chirp_lut[855] = 8'd187; long_chirp_lut[856] = 8'd251; long_chirp_lut[857] = 8'd128; long_chirp_lut[858] = 8'd 5; long_chirp_lut[859] = 8'd 66; long_chirp_lut[860] = 8'd220; long_chirp_lut[861] = 8'd235; long_chirp_lut[862] = 8'd 88; long_chirp_lut[863] = 8'd 1;
|
||||
long_chirp_lut[864] = 8'd104; long_chirp_lut[865] = 8'd242; long_chirp_lut[866] = 8'd209; long_chirp_lut[867] = 8'd 53; long_chirp_lut[868] = 8'd 9; long_chirp_lut[869] = 8'd143; long_chirp_lut[870] = 8'd253; long_chirp_lut[871] = 8'd175; long_chirp_lut[872] = 8'd 25; long_chirp_lut[873] = 8'd 29; long_chirp_lut[874] = 8'd180; long_chirp_lut[875] = 8'd253; long_chirp_lut[876] = 8'd138; long_chirp_lut[877] = 8'd 8; long_chirp_lut[878] = 8'd 56; long_chirp_lut[879] = 8'd211;
|
||||
long_chirp_lut[880] = 8'd241; long_chirp_lut[881] = 8'd101; long_chirp_lut[882] = 8'd 1; long_chirp_lut[883] = 8'd 90; long_chirp_lut[884] = 8'd235; long_chirp_lut[885] = 8'd220; long_chirp_lut[886] = 8'd 67; long_chirp_lut[887] = 8'd 4; long_chirp_lut[888] = 8'd125; long_chirp_lut[889] = 8'd250; long_chirp_lut[890] = 8'd193; long_chirp_lut[891] = 8'd 39; long_chirp_lut[892] = 8'd 17; long_chirp_lut[893] = 8'd159; long_chirp_lut[894] = 8'd254; long_chirp_lut[895] = 8'd161;
|
||||
long_chirp_lut[896] = 8'd 18; long_chirp_lut[897] = 8'd 38; long_chirp_lut[898] = 8'd191; long_chirp_lut[899] = 8'd250; long_chirp_lut[900] = 8'd127; long_chirp_lut[901] = 8'd 5; long_chirp_lut[902] = 8'd 64; long_chirp_lut[903] = 8'd217; long_chirp_lut[904] = 8'd238; long_chirp_lut[905] = 8'd 95; long_chirp_lut[906] = 8'd 1; long_chirp_lut[907] = 8'd 94; long_chirp_lut[908] = 8'd237; long_chirp_lut[909] = 8'd218; long_chirp_lut[910] = 8'd 66; long_chirp_lut[911] = 8'd 4;
|
||||
long_chirp_lut[912] = 8'd125; long_chirp_lut[913] = 8'd249; long_chirp_lut[914] = 8'd194; long_chirp_lut[915] = 8'd 41; long_chirp_lut[916] = 8'd 15; long_chirp_lut[917] = 8'd155; long_chirp_lut[918] = 8'd254; long_chirp_lut[919] = 8'd167; long_chirp_lut[920] = 8'd 21; long_chirp_lut[921] = 8'd 32; long_chirp_lut[922] = 8'd183; long_chirp_lut[923] = 8'd252; long_chirp_lut[924] = 8'd138; long_chirp_lut[925] = 8'd 8; long_chirp_lut[926] = 8'd 54; long_chirp_lut[927] = 8'd207;
|
||||
long_chirp_lut[928] = 8'd244; long_chirp_lut[929] = 8'd110; long_chirp_lut[930] = 8'd 2; long_chirp_lut[931] = 8'd 78; long_chirp_lut[932] = 8'd227; long_chirp_lut[933] = 8'd230; long_chirp_lut[934] = 8'd 83; long_chirp_lut[935] = 8'd 1; long_chirp_lut[936] = 8'd104; long_chirp_lut[937] = 8'd241; long_chirp_lut[938] = 8'd213; long_chirp_lut[939] = 8'd 60; long_chirp_lut[940] = 8'd 6; long_chirp_lut[941] = 8'd130; long_chirp_lut[942] = 8'd250; long_chirp_lut[943] = 8'd192;
|
||||
long_chirp_lut[944] = 8'd 39; long_chirp_lut[945] = 8'd 15; long_chirp_lut[946] = 8'd155; long_chirp_lut[947] = 8'd254; long_chirp_lut[948] = 8'd169; long_chirp_lut[949] = 8'd 23; long_chirp_lut[950] = 8'd 29; long_chirp_lut[951] = 8'd178; long_chirp_lut[952] = 8'd253; long_chirp_lut[953] = 8'd146; long_chirp_lut[954] = 8'd 12; long_chirp_lut[955] = 8'd 46; long_chirp_lut[956] = 8'd198; long_chirp_lut[957] = 8'd248; long_chirp_lut[958] = 8'd123; long_chirp_lut[959] = 8'd 4;
|
||||
long_chirp_lut[960] = 8'd 64; long_chirp_lut[961] = 8'd216; long_chirp_lut[962] = 8'd240; long_chirp_lut[963] = 8'd101; long_chirp_lut[964] = 8'd 1; long_chirp_lut[965] = 8'd 84; long_chirp_lut[966] = 8'd230; long_chirp_lut[967] = 8'd228; long_chirp_lut[968] = 8'd 81; long_chirp_lut[969] = 8'd 1; long_chirp_lut[970] = 8'd104; long_chirp_lut[971] = 8'd241; long_chirp_lut[972] = 8'd214; long_chirp_lut[973] = 8'd 63; long_chirp_lut[974] = 8'd 4; long_chirp_lut[975] = 8'd123;
|
||||
long_chirp_lut[976] = 8'd248; long_chirp_lut[977] = 8'd199; long_chirp_lut[978] = 8'd 47; long_chirp_lut[979] = 8'd 11; long_chirp_lut[980] = 8'd142; long_chirp_lut[981] = 8'd253; long_chirp_lut[982] = 8'd183; long_chirp_lut[983] = 8'd 34; long_chirp_lut[984] = 8'd 19; long_chirp_lut[985] = 8'd160; long_chirp_lut[986] = 8'd254; long_chirp_lut[987] = 8'd167; long_chirp_lut[988] = 8'd 23; long_chirp_lut[989] = 8'd 29; long_chirp_lut[990] = 8'd176; long_chirp_lut[991] = 8'd254;
|
||||
long_chirp_lut[992] = 8'd151; long_chirp_lut[993] = 8'd 14; long_chirp_lut[994] = 8'd 40; long_chirp_lut[995] = 8'd191; long_chirp_lut[996] = 8'd251; long_chirp_lut[997] = 8'd135; long_chirp_lut[998] = 8'd 8; long_chirp_lut[999] = 8'd 52; long_chirp_lut[1000] = 8'd203; long_chirp_lut[1001] = 8'd247; long_chirp_lut[1002] = 8'd120; long_chirp_lut[1003] = 8'd 4; long_chirp_lut[1004] = 8'd 64; long_chirp_lut[1005] = 8'd214; long_chirp_lut[1006] = 8'd241; long_chirp_lut[1007] = 8'd106;
|
||||
long_chirp_lut[1008] = 8'd 2; long_chirp_lut[1009] = 8'd 76; long_chirp_lut[1010] = 8'd224; long_chirp_lut[1011] = 8'd235; long_chirp_lut[1012] = 8'd 94; long_chirp_lut[1013] = 8'd 1; long_chirp_lut[1014] = 8'd 88; long_chirp_lut[1015] = 8'd231; long_chirp_lut[1016] = 8'd228; long_chirp_lut[1017] = 8'd 82; long_chirp_lut[1018] = 8'd 1; long_chirp_lut[1019] = 8'd 99; long_chirp_lut[1020] = 8'd237; long_chirp_lut[1021] = 8'd220; long_chirp_lut[1022] = 8'd 72; long_chirp_lut[1023] = 8'd 2;
|
||||
long_chirp_lut[1024] = 8'd110; long_chirp_lut[1025] = 8'd242; long_chirp_lut[1026] = 8'd213; long_chirp_lut[1027] = 8'd 63; long_chirp_lut[1028] = 8'd 4; long_chirp_lut[1029] = 8'd119; long_chirp_lut[1030] = 8'd246; long_chirp_lut[1031] = 8'd206; long_chirp_lut[1032] = 8'd 55; long_chirp_lut[1033] = 8'd 6; long_chirp_lut[1034] = 8'd128; long_chirp_lut[1035] = 8'd249; long_chirp_lut[1036] = 8'd199; long_chirp_lut[1037] = 8'd 48; long_chirp_lut[1038] = 8'd 9; long_chirp_lut[1039] = 8'd136;
|
||||
long_chirp_lut[1040] = 8'd251; long_chirp_lut[1041] = 8'd192; long_chirp_lut[1042] = 8'd 43; long_chirp_lut[1043] = 8'd 12; long_chirp_lut[1044] = 8'd143; long_chirp_lut[1045] = 8'd252; long_chirp_lut[1046] = 8'd186; long_chirp_lut[1047] = 8'd 38; long_chirp_lut[1048] = 8'd 15; long_chirp_lut[1049] = 8'd150; long_chirp_lut[1050] = 8'd253; long_chirp_lut[1051] = 8'd181; long_chirp_lut[1052] = 8'd 34; long_chirp_lut[1053] = 8'd 17; long_chirp_lut[1054] = 8'd155; long_chirp_lut[1055] = 8'd254;
|
||||
long_chirp_lut[1056] = 8'd177; long_chirp_lut[1057] = 8'd 31; long_chirp_lut[1058] = 8'd 20; long_chirp_lut[1059] = 8'd159; long_chirp_lut[1060] = 8'd254; long_chirp_lut[1061] = 8'd173; long_chirp_lut[1062] = 8'd 28; long_chirp_lut[1063] = 8'd 22; long_chirp_lut[1064] = 8'd162; long_chirp_lut[1065] = 8'd254; long_chirp_lut[1066] = 8'd170; long_chirp_lut[1067] = 8'd 27; long_chirp_lut[1068] = 8'd 23; long_chirp_lut[1069] = 8'd165; long_chirp_lut[1070] = 8'd254; long_chirp_lut[1071] = 8'd168;
|
||||
long_chirp_lut[1072] = 8'd 25; long_chirp_lut[1073] = 8'd 24; long_chirp_lut[1074] = 8'd166; long_chirp_lut[1075] = 8'd254; long_chirp_lut[1076] = 8'd167; long_chirp_lut[1077] = 8'd 25; long_chirp_lut[1078] = 8'd 25; long_chirp_lut[1079] = 8'd167; long_chirp_lut[1080] = 8'd255; long_chirp_lut[1081] = 8'd167; long_chirp_lut[1082] = 8'd 25; long_chirp_lut[1083] = 8'd 25; long_chirp_lut[1084] = 8'd166; long_chirp_lut[1085] = 8'd254; long_chirp_lut[1086] = 8'd167; long_chirp_lut[1087] = 8'd 25;
|
||||
long_chirp_lut[1088] = 8'd 24; long_chirp_lut[1089] = 8'd165; long_chirp_lut[1090] = 8'd254; long_chirp_lut[1091] = 8'd169; long_chirp_lut[1092] = 8'd 26; long_chirp_lut[1093] = 8'd 23; long_chirp_lut[1094] = 8'd163; long_chirp_lut[1095] = 8'd254; long_chirp_lut[1096] = 8'd171; long_chirp_lut[1097] = 8'd 28; long_chirp_lut[1098] = 8'd 21; long_chirp_lut[1099] = 8'd160; long_chirp_lut[1100] = 8'd254; long_chirp_lut[1101] = 8'd174; long_chirp_lut[1102] = 8'd 30; long_chirp_lut[1103] = 8'd 19;
|
||||
long_chirp_lut[1104] = 8'd157; long_chirp_lut[1105] = 8'd254; long_chirp_lut[1106] = 8'd178; long_chirp_lut[1107] = 8'd 33; long_chirp_lut[1108] = 8'd 17; long_chirp_lut[1109] = 8'd152; long_chirp_lut[1110] = 8'd253; long_chirp_lut[1111] = 8'd183; long_chirp_lut[1112] = 8'd 37; long_chirp_lut[1113] = 8'd 14; long_chirp_lut[1114] = 8'd146; long_chirp_lut[1115] = 8'd252; long_chirp_lut[1116] = 8'd189; long_chirp_lut[1117] = 8'd 42; long_chirp_lut[1118] = 8'd 11; long_chirp_lut[1119] = 8'd139;
|
||||
long_chirp_lut[1120] = 8'd251; long_chirp_lut[1121] = 8'd195; long_chirp_lut[1122] = 8'd 47; long_chirp_lut[1123] = 8'd 9; long_chirp_lut[1124] = 8'd132; long_chirp_lut[1125] = 8'd249; long_chirp_lut[1126] = 8'd201; long_chirp_lut[1127] = 8'd 54; long_chirp_lut[1128] = 8'd 6; long_chirp_lut[1129] = 8'd123; long_chirp_lut[1130] = 8'd246; long_chirp_lut[1131] = 8'd209; long_chirp_lut[1132] = 8'd 61; long_chirp_lut[1133] = 8'd 4; long_chirp_lut[1134] = 8'd114; long_chirp_lut[1135] = 8'd242;
|
||||
long_chirp_lut[1136] = 8'd216; long_chirp_lut[1137] = 8'd 70; long_chirp_lut[1138] = 8'd 2; long_chirp_lut[1139] = 8'd103; long_chirp_lut[1140] = 8'd237; long_chirp_lut[1141] = 8'd223; long_chirp_lut[1142] = 8'd 80; long_chirp_lut[1143] = 8'd 1; long_chirp_lut[1144] = 8'd 92; long_chirp_lut[1145] = 8'd231; long_chirp_lut[1146] = 8'd231; long_chirp_lut[1147] = 8'd 91; long_chirp_lut[1148] = 8'd 1; long_chirp_lut[1149] = 8'd 81; long_chirp_lut[1150] = 8'd224; long_chirp_lut[1151] = 8'd237;
|
||||
long_chirp_lut[1152] = 8'd104; long_chirp_lut[1153] = 8'd 2; long_chirp_lut[1154] = 8'd 69; long_chirp_lut[1155] = 8'd214; long_chirp_lut[1156] = 8'd244; long_chirp_lut[1157] = 8'd117; long_chirp_lut[1158] = 8'd 5; long_chirp_lut[1159] = 8'd 56; long_chirp_lut[1160] = 8'd203; long_chirp_lut[1161] = 8'd249; long_chirp_lut[1162] = 8'd132; long_chirp_lut[1163] = 8'd 9; long_chirp_lut[1164] = 8'd 45; long_chirp_lut[1165] = 8'd191; long_chirp_lut[1166] = 8'd252; long_chirp_lut[1167] = 8'd148;
|
||||
long_chirp_lut[1168] = 8'd 16; long_chirp_lut[1169] = 8'd 33; long_chirp_lut[1170] = 8'd176; long_chirp_lut[1171] = 8'd254; long_chirp_lut[1172] = 8'd164; long_chirp_lut[1173] = 8'd 25; long_chirp_lut[1174] = 8'd 23; long_chirp_lut[1175] = 8'd160; long_chirp_lut[1176] = 8'd254; long_chirp_lut[1177] = 8'd180; long_chirp_lut[1178] = 8'd 36; long_chirp_lut[1179] = 8'd 14; long_chirp_lut[1180] = 8'd142; long_chirp_lut[1181] = 8'd251; long_chirp_lut[1182] = 8'd196; long_chirp_lut[1183] = 8'd 50;
|
||||
long_chirp_lut[1184] = 8'd 7; long_chirp_lut[1185] = 8'd123; long_chirp_lut[1186] = 8'd246; long_chirp_lut[1187] = 8'd212; long_chirp_lut[1188] = 8'd 66; long_chirp_lut[1189] = 8'd 2; long_chirp_lut[1190] = 8'd104; long_chirp_lut[1191] = 8'd237; long_chirp_lut[1192] = 8'd226; long_chirp_lut[1193] = 8'd 85; long_chirp_lut[1194] = 8'd 1; long_chirp_lut[1195] = 8'd 84; long_chirp_lut[1196] = 8'd225; long_chirp_lut[1197] = 8'd238; long_chirp_lut[1198] = 8'd106; long_chirp_lut[1199] = 8'd 2;
|
||||
long_chirp_lut[1200] = 8'd 64; long_chirp_lut[1201] = 8'd209; long_chirp_lut[1202] = 8'd247; long_chirp_lut[1203] = 8'd128; long_chirp_lut[1204] = 8'd 8; long_chirp_lut[1205] = 8'd 46; long_chirp_lut[1206] = 8'd190; long_chirp_lut[1207] = 8'd253; long_chirp_lut[1208] = 8'd151; long_chirp_lut[1209] = 8'd 18; long_chirp_lut[1210] = 8'd 29; long_chirp_lut[1211] = 8'd169; long_chirp_lut[1212] = 8'd254; long_chirp_lut[1213] = 8'd174; long_chirp_lut[1214] = 8'd 33; long_chirp_lut[1215] = 8'd 15;
|
||||
long_chirp_lut[1216] = 8'd145; long_chirp_lut[1217] = 8'd252; long_chirp_lut[1218] = 8'd196; long_chirp_lut[1219] = 8'd 51; long_chirp_lut[1220] = 8'd 6; long_chirp_lut[1221] = 8'd119; long_chirp_lut[1222] = 8'd243; long_chirp_lut[1223] = 8'd216; long_chirp_lut[1224] = 8'd 73; long_chirp_lut[1225] = 8'd 1; long_chirp_lut[1226] = 8'd 93; long_chirp_lut[1227] = 8'd230; long_chirp_lut[1228] = 8'd233; long_chirp_lut[1229] = 8'd 99; long_chirp_lut[1230] = 8'd 2; long_chirp_lut[1231] = 8'd 68;
|
||||
long_chirp_lut[1232] = 8'd212; long_chirp_lut[1233] = 8'd246; long_chirp_lut[1234] = 8'd127; long_chirp_lut[1235] = 8'd 8; long_chirp_lut[1236] = 8'd 45; long_chirp_lut[1237] = 8'd188; long_chirp_lut[1238] = 8'd253; long_chirp_lut[1239] = 8'd155; long_chirp_lut[1240] = 8'd 21; long_chirp_lut[1241] = 8'd 25; long_chirp_lut[1242] = 8'd161; long_chirp_lut[1243] = 8'd254; long_chirp_lut[1244] = 8'd183; long_chirp_lut[1245] = 8'd 41; long_chirp_lut[1246] = 8'd 10; long_chirp_lut[1247] = 8'd131;
|
||||
long_chirp_lut[1248] = 8'd247; long_chirp_lut[1249] = 8'd209; long_chirp_lut[1250] = 8'd 66; long_chirp_lut[1251] = 8'd 2; long_chirp_lut[1252] = 8'd100; long_chirp_lut[1253] = 8'd234; long_chirp_lut[1254] = 8'd231; long_chirp_lut[1255] = 8'd 95; long_chirp_lut[1256] = 8'd 1; long_chirp_lut[1257] = 8'd 70; long_chirp_lut[1258] = 8'd212; long_chirp_lut[1259] = 8'd246; long_chirp_lut[1260] = 8'd128; long_chirp_lut[1261] = 8'd 9; long_chirp_lut[1262] = 8'd 42; long_chirp_lut[1263] = 8'd185;
|
||||
long_chirp_lut[1264] = 8'd254; long_chirp_lut[1265] = 8'd161; long_chirp_lut[1266] = 8'd 25; long_chirp_lut[1267] = 8'd 20; long_chirp_lut[1268] = 8'd153; long_chirp_lut[1269] = 8'd253; long_chirp_lut[1270] = 8'd193; long_chirp_lut[1271] = 8'd 49; long_chirp_lut[1272] = 8'd 6; long_chirp_lut[1273] = 8'd118; long_chirp_lut[1274] = 8'd242; long_chirp_lut[1275] = 8'd220; long_chirp_lut[1276] = 8'd 80; long_chirp_lut[1277] = 8'd 1; long_chirp_lut[1278] = 8'd 83; long_chirp_lut[1279] = 8'd222;
|
||||
long_chirp_lut[1280] = 8'd241; long_chirp_lut[1281] = 8'd116; long_chirp_lut[1282] = 8'd 5; long_chirp_lut[1283] = 8'd 50; long_chirp_lut[1284] = 8'd193; long_chirp_lut[1285] = 8'd253; long_chirp_lut[1286] = 8'd153; long_chirp_lut[1287] = 8'd 21; long_chirp_lut[1288] = 8'd 24; long_chirp_lut[1289] = 8'd158; long_chirp_lut[1290] = 8'd253; long_chirp_lut[1291] = 8'd189; long_chirp_lut[1292] = 8'd 47; long_chirp_lut[1293] = 8'd 7; long_chirp_lut[1294] = 8'd119; long_chirp_lut[1295] = 8'd242;
|
||||
long_chirp_lut[1296] = 8'd220; long_chirp_lut[1297] = 8'd 81; long_chirp_lut[1298] = 8'd 1; long_chirp_lut[1299] = 8'd 81; long_chirp_lut[1300] = 8'd220; long_chirp_lut[1301] = 8'd243; long_chirp_lut[1302] = 8'd120; long_chirp_lut[1303] = 8'd 7; long_chirp_lut[1304] = 8'd 46; long_chirp_lut[1305] = 8'd187; long_chirp_lut[1306] = 8'd254; long_chirp_lut[1307] = 8'd161; long_chirp_lut[1308] = 8'd 26; long_chirp_lut[1309] = 8'd 19; long_chirp_lut[1310] = 8'd148; long_chirp_lut[1311] = 8'd251;
|
||||
long_chirp_lut[1312] = 8'd199; long_chirp_lut[1313] = 8'd 57; long_chirp_lut[1314] = 8'd 3; long_chirp_lut[1315] = 8'd105; long_chirp_lut[1316] = 8'd235; long_chirp_lut[1317] = 8'd230; long_chirp_lut[1318] = 8'd 97; long_chirp_lut[1319] = 8'd 2; long_chirp_lut[1320] = 8'd 64; long_chirp_lut[1321] = 8'd206; long_chirp_lut[1322] = 8'd250; long_chirp_lut[1323] = 8'd141; long_chirp_lut[1324] = 8'd 16; long_chirp_lut[1325] = 8'd 30; long_chirp_lut[1326] = 8'd166; long_chirp_lut[1327] = 8'd254;
|
||||
long_chirp_lut[1328] = 8'd184; long_chirp_lut[1329] = 8'd 44; long_chirp_lut[1330] = 8'd 8; long_chirp_lut[1331] = 8'd121; long_chirp_lut[1332] = 8'd242; long_chirp_lut[1333] = 8'd221; long_chirp_lut[1334] = 8'd 83; long_chirp_lut[1335] = 8'd 1; long_chirp_lut[1336] = 8'd 76; long_chirp_lut[1337] = 8'd215; long_chirp_lut[1338] = 8'd246; long_chirp_lut[1339] = 8'd130; long_chirp_lut[1340] = 8'd 11; long_chirp_lut[1341] = 8'd 37; long_chirp_lut[1342] = 8'd175; long_chirp_lut[1343] = 8'd254;
|
||||
long_chirp_lut[1344] = 8'd177; long_chirp_lut[1345] = 8'd 38; long_chirp_lut[1346] = 8'd 10; long_chirp_lut[1347] = 8'd127; long_chirp_lut[1348] = 8'd245; long_chirp_lut[1349] = 8'd217; long_chirp_lut[1350] = 8'd 79; long_chirp_lut[1351] = 8'd 1; long_chirp_lut[1352] = 8'd 79; long_chirp_lut[1353] = 8'd217; long_chirp_lut[1354] = 8'd245; long_chirp_lut[1355] = 8'd128; long_chirp_lut[1356] = 8'd 10; long_chirp_lut[1357] = 8'd 37; long_chirp_lut[1358] = 8'd175; long_chirp_lut[1359] = 8'd254;
|
||||
long_chirp_lut[1360] = 8'd178; long_chirp_lut[1361] = 8'd 39; long_chirp_lut[1362] = 8'd 9; long_chirp_lut[1363] = 8'd124; long_chirp_lut[1364] = 8'd243; long_chirp_lut[1365] = 8'd220; long_chirp_lut[1366] = 8'd 83; long_chirp_lut[1367] = 8'd 1; long_chirp_lut[1368] = 8'd 73; long_chirp_lut[1369] = 8'd212; long_chirp_lut[1370] = 8'd247; long_chirp_lut[1371] = 8'd136; long_chirp_lut[1372] = 8'd 14; long_chirp_lut[1373] = 8'd 31; long_chirp_lut[1374] = 8'd166; long_chirp_lut[1375] = 8'd254;
|
||||
long_chirp_lut[1376] = 8'd187; long_chirp_lut[1377] = 8'd 48; long_chirp_lut[1378] = 8'd 5; long_chirp_lut[1379] = 8'd112; long_chirp_lut[1380] = 8'd237; long_chirp_lut[1381] = 8'd229; long_chirp_lut[1382] = 8'd 97; long_chirp_lut[1383] = 8'd 2; long_chirp_lut[1384] = 8'd 60; long_chirp_lut[1385] = 8'd200; long_chirp_lut[1386] = 8'd252; long_chirp_lut[1387] = 8'd153; long_chirp_lut[1388] = 8'd 23; long_chirp_lut[1389] = 8'd 20; long_chirp_lut[1390] = 8'd148; long_chirp_lut[1391] = 8'd251;
|
||||
long_chirp_lut[1392] = 8'd204; long_chirp_lut[1393] = 8'd 65; long_chirp_lut[1394] = 8'd 1; long_chirp_lut[1395] = 8'd 91; long_chirp_lut[1396] = 8'd225; long_chirp_lut[1397] = 8'd241; long_chirp_lut[1398] = 8'd120; long_chirp_lut[1399] = 8'd 8; long_chirp_lut[1400] = 8'd 40; long_chirp_lut[1401] = 8'd178; long_chirp_lut[1402] = 8'd254; long_chirp_lut[1403] = 8'd178; long_chirp_lut[1404] = 8'd 41; long_chirp_lut[1405] = 8'd 8; long_chirp_lut[1406] = 8'd119; long_chirp_lut[1407] = 8'd241;
|
||||
long_chirp_lut[1408] = 8'd226; long_chirp_lut[1409] = 8'd 93; long_chirp_lut[1410] = 8'd 2; long_chirp_lut[1411] = 8'd 62; long_chirp_lut[1412] = 8'd201; long_chirp_lut[1413] = 8'd252; long_chirp_lut[1414] = 8'd153; long_chirp_lut[1415] = 8'd 24; long_chirp_lut[1416] = 8'd 19; long_chirp_lut[1417] = 8'd144; long_chirp_lut[1418] = 8'd250; long_chirp_lut[1419] = 8'd209; long_chirp_lut[1420] = 8'd 71; long_chirp_lut[1421] = 8'd 1; long_chirp_lut[1422] = 8'd 83; long_chirp_lut[1423] = 8'd218;
|
||||
long_chirp_lut[1424] = 8'd245; long_chirp_lut[1425] = 8'd132; long_chirp_lut[1426] = 8'd 13; long_chirp_lut[1427] = 8'd 31; long_chirp_lut[1428] = 8'd164; long_chirp_lut[1429] = 8'd254; long_chirp_lut[1430] = 8'd193; long_chirp_lut[1431] = 8'd 54; long_chirp_lut[1432] = 8'd 3; long_chirp_lut[1433] = 8'd100; long_chirp_lut[1434] = 8'd230; long_chirp_lut[1435] = 8'd238; long_chirp_lut[1436] = 8'd115; long_chirp_lut[1437] = 8'd 7; long_chirp_lut[1438] = 8'd 42; long_chirp_lut[1439] = 8'd179;
|
||||
long_chirp_lut[1440] = 8'd255; long_chirp_lut[1441] = 8'd179; long_chirp_lut[1442] = 8'd 43; long_chirp_lut[1443] = 8'd 7; long_chirp_lut[1444] = 8'd114; long_chirp_lut[1445] = 8'd237; long_chirp_lut[1446] = 8'd231; long_chirp_lut[1447] = 8'd102; long_chirp_lut[1448] = 8'd 4; long_chirp_lut[1449] = 8'd 52; long_chirp_lut[1450] = 8'd189; long_chirp_lut[1451] = 8'd254; long_chirp_lut[1452] = 8'd169; long_chirp_lut[1453] = 8'd 35; long_chirp_lut[1454] = 8'd 10; long_chirp_lut[1455] = 8'd123;
|
||||
long_chirp_lut[1456] = 8'd242; long_chirp_lut[1457] = 8'd225; long_chirp_lut[1458] = 8'd 94; long_chirp_lut[1459] = 8'd 2; long_chirp_lut[1460] = 8'd 58; long_chirp_lut[1461] = 8'd195; long_chirp_lut[1462] = 8'd253; long_chirp_lut[1463] = 8'd163; long_chirp_lut[1464] = 8'd 31; long_chirp_lut[1465] = 8'd 12; long_chirp_lut[1466] = 8'd128; long_chirp_lut[1467] = 8'd243; long_chirp_lut[1468] = 8'd223; long_chirp_lut[1469] = 8'd 90; long_chirp_lut[1470] = 8'd 2; long_chirp_lut[1471] = 8'd 60;
|
||||
long_chirp_lut[1472] = 8'd198; long_chirp_lut[1473] = 8'd253; long_chirp_lut[1474] = 8'd162; long_chirp_lut[1475] = 8'd 31; long_chirp_lut[1476] = 8'd 13; long_chirp_lut[1477] = 8'd129; long_chirp_lut[1478] = 8'd243; long_chirp_lut[1479] = 8'd223; long_chirp_lut[1480] = 8'd 91; long_chirp_lut[1481] = 8'd 2; long_chirp_lut[1482] = 8'd 59; long_chirp_lut[1483] = 8'd196; long_chirp_lut[1484] = 8'd253; long_chirp_lut[1485] = 8'd164; long_chirp_lut[1486] = 8'd 33; long_chirp_lut[1487] = 8'd 11;
|
||||
long_chirp_lut[1488] = 8'd125; long_chirp_lut[1489] = 8'd242; long_chirp_lut[1490] = 8'd226; long_chirp_lut[1491] = 8'd 96; long_chirp_lut[1492] = 8'd 3; long_chirp_lut[1493] = 8'd 54; long_chirp_lut[1494] = 8'd190; long_chirp_lut[1495] = 8'd254; long_chirp_lut[1496] = 8'd171; long_chirp_lut[1497] = 8'd 38; long_chirp_lut[1498] = 8'd 8; long_chirp_lut[1499] = 8'd116; long_chirp_lut[1500] = 8'd237; long_chirp_lut[1501] = 8'd232; long_chirp_lut[1502] = 8'd106; long_chirp_lut[1503] = 8'd 5;
|
||||
long_chirp_lut[1504] = 8'd 46; long_chirp_lut[1505] = 8'd181; long_chirp_lut[1506] = 8'd254; long_chirp_lut[1507] = 8'd182; long_chirp_lut[1508] = 8'd 47; long_chirp_lut[1509] = 8'd 4; long_chirp_lut[1510] = 8'd104; long_chirp_lut[1511] = 8'd230; long_chirp_lut[1512] = 8'd239; long_chirp_lut[1513] = 8'd120; long_chirp_lut[1514] = 8'd 9; long_chirp_lut[1515] = 8'd 35; long_chirp_lut[1516] = 8'd166; long_chirp_lut[1517] = 8'd253; long_chirp_lut[1518] = 8'd196; long_chirp_lut[1519] = 8'd 60;
|
||||
long_chirp_lut[1520] = 8'd 1; long_chirp_lut[1521] = 8'd 87; long_chirp_lut[1522] = 8'd219; long_chirp_lut[1523] = 8'd246; long_chirp_lut[1524] = 8'd138; long_chirp_lut[1525] = 8'd 18; long_chirp_lut[1526] = 8'd 23; long_chirp_lut[1527] = 8'd147; long_chirp_lut[1528] = 8'd249; long_chirp_lut[1529] = 8'd212; long_chirp_lut[1530] = 8'd 79; long_chirp_lut[1531] = 8'd 1; long_chirp_lut[1532] = 8'd 67; long_chirp_lut[1533] = 8'd202; long_chirp_lut[1534] = 8'd252; long_chirp_lut[1535] = 8'd161;
|
||||
long_chirp_lut[1536] = 8'd 31; long_chirp_lut[1537] = 8'd 11; long_chirp_lut[1538] = 8'd123; long_chirp_lut[1539] = 8'd240; long_chirp_lut[1540] = 8'd229; long_chirp_lut[1541] = 8'd103; long_chirp_lut[1542] = 8'd 5; long_chirp_lut[1543] = 8'd 45; long_chirp_lut[1544] = 8'd179; long_chirp_lut[1545] = 8'd254; long_chirp_lut[1546] = 8'd186; long_chirp_lut[1547] = 8'd 52; long_chirp_lut[1548] = 8'd 3; long_chirp_lut[1549] = 8'd 95; long_chirp_lut[1550] = 8'd224; long_chirp_lut[1551] = 8'd244;
|
||||
long_chirp_lut[1552] = 8'd133; long_chirp_lut[1553] = 8'd 16; long_chirp_lut[1554] = 8'd 24; long_chirp_lut[1555] = 8'd149; long_chirp_lut[1556] = 8'd249; long_chirp_lut[1557] = 8'd213; long_chirp_lut[1558] = 8'd 80; long_chirp_lut[1559] = 8'd 1; long_chirp_lut[1560] = 8'd 64; long_chirp_lut[1561] = 8'd199; long_chirp_lut[1562] = 8'd253; long_chirp_lut[1563] = 8'd167; long_chirp_lut[1564] = 8'd 36; long_chirp_lut[1565] = 8'd 8; long_chirp_lut[1566] = 8'd114; long_chirp_lut[1567] = 8'd235;
|
||||
long_chirp_lut[1568] = 8'd236; long_chirp_lut[1569] = 8'd116; long_chirp_lut[1570] = 8'd 9; long_chirp_lut[1571] = 8'd 35; long_chirp_lut[1572] = 8'd164; long_chirp_lut[1573] = 8'd253; long_chirp_lut[1574] = 8'd201; long_chirp_lut[1575] = 8'd 68; long_chirp_lut[1576] = 8'd 1; long_chirp_lut[1577] = 8'd 75; long_chirp_lut[1578] = 8'd208; long_chirp_lut[1579] = 8'd251; long_chirp_lut[1580] = 8'd157; long_chirp_lut[1581] = 8'd 30; long_chirp_lut[1582] = 8'd 11; long_chirp_lut[1583] = 8'd122;
|
||||
long_chirp_lut[1584] = 8'd239; long_chirp_lut[1585] = 8'd232; long_chirp_lut[1586] = 8'd109; long_chirp_lut[1587] = 8'd 7; long_chirp_lut[1588] = 8'd 38; long_chirp_lut[1589] = 8'd169; long_chirp_lut[1590] = 8'd253; long_chirp_lut[1591] = 8'd199; long_chirp_lut[1592] = 8'd 65; long_chirp_lut[1593] = 8'd 1; long_chirp_lut[1594] = 8'd 77; long_chirp_lut[1595] = 8'd209; long_chirp_lut[1596] = 8'd251; long_chirp_lut[1597] = 8'd157; long_chirp_lut[1598] = 8'd 30; long_chirp_lut[1599] = 8'd 11;
|
||||
long_chirp_lut[1600] = 8'd120; long_chirp_lut[1601] = 8'd237; long_chirp_lut[1602] = 8'd234; long_chirp_lut[1603] = 8'd113; long_chirp_lut[1604] = 8'd 8; long_chirp_lut[1605] = 8'd 35; long_chirp_lut[1606] = 8'd163; long_chirp_lut[1607] = 8'd252; long_chirp_lut[1608] = 8'd204; long_chirp_lut[1609] = 8'd 72; long_chirp_lut[1610] = 8'd 1; long_chirp_lut[1611] = 8'd 69; long_chirp_lut[1612] = 8'd201; long_chirp_lut[1613] = 8'd253; long_chirp_lut[1614] = 8'd167; long_chirp_lut[1615] = 8'd 38;
|
||||
long_chirp_lut[1616] = 8'd 7; long_chirp_lut[1617] = 8'd107; long_chirp_lut[1618] = 8'd230; long_chirp_lut[1619] = 8'd241; long_chirp_lut[1620] = 8'd127; long_chirp_lut[1621] = 8'd 14; long_chirp_lut[1622] = 8'd 25; long_chirp_lut[1623] = 8'd147; long_chirp_lut[1624] = 8'd248; long_chirp_lut[1625] = 8'd218; long_chirp_lut[1626] = 8'd 89; long_chirp_lut[1627] = 8'd 2; long_chirp_lut[1628] = 8'd 52; long_chirp_lut[1629] = 8'd184; long_chirp_lut[1630] = 8'd254; long_chirp_lut[1631] = 8'd187;
|
||||
long_chirp_lut[1632] = 8'd 55; long_chirp_lut[1633] = 8'd 2; long_chirp_lut[1634] = 8'd 85; long_chirp_lut[1635] = 8'd214; long_chirp_lut[1636] = 8'd250; long_chirp_lut[1637] = 8'd153; long_chirp_lut[1638] = 8'd 28; long_chirp_lut[1639] = 8'd 11; long_chirp_lut[1640] = 8'd120; long_chirp_lut[1641] = 8'd237; long_chirp_lut[1642] = 8'd235; long_chirp_lut[1643] = 8'd117; long_chirp_lut[1644] = 8'd 10; long_chirp_lut[1645] = 8'd 30; long_chirp_lut[1646] = 8'd155; long_chirp_lut[1647] = 8'd250;
|
||||
long_chirp_lut[1648] = 8'd213; long_chirp_lut[1649] = 8'd 84; long_chirp_lut[1650] = 8'd 2; long_chirp_lut[1651] = 8'd 55; long_chirp_lut[1652] = 8'd186; long_chirp_lut[1653] = 8'd254; long_chirp_lut[1654] = 8'd186; long_chirp_lut[1655] = 8'd 55; long_chirp_lut[1656] = 8'd 2; long_chirp_lut[1657] = 8'd 83; long_chirp_lut[1658] = 8'd212; long_chirp_lut[1659] = 8'd251; long_chirp_lut[1660] = 8'd157; long_chirp_lut[1661] = 8'd 32; long_chirp_lut[1662] = 8'd 9; long_chirp_lut[1663] = 8'd113;
|
||||
long_chirp_lut[1664] = 8'd233; long_chirp_lut[1665] = 8'd240; long_chirp_lut[1666] = 8'd127; long_chirp_lut[1667] = 8'd 15; long_chirp_lut[1668] = 8'd 23; long_chirp_lut[1669] = 8'd143; long_chirp_lut[1670] = 8'd246; long_chirp_lut[1671] = 8'd223; long_chirp_lut[1672] = 8'd 98; long_chirp_lut[1673] = 8'd 4; long_chirp_lut[1674] = 8'd 42; long_chirp_lut[1675] = 8'd171; long_chirp_lut[1676] = 8'd253; long_chirp_lut[1677] = 8'd202; long_chirp_lut[1678] = 8'd 72; long_chirp_lut[1679] = 8'd 1;
|
||||
long_chirp_lut[1680] = 8'd 64; long_chirp_lut[1681] = 8'd195; long_chirp_lut[1682] = 8'd254; long_chirp_lut[1683] = 8'd179; long_chirp_lut[1684] = 8'd 50; long_chirp_lut[1685] = 8'd 2; long_chirp_lut[1686] = 8'd 88; long_chirp_lut[1687] = 8'd215; long_chirp_lut[1688] = 8'd250; long_chirp_lut[1689] = 8'd155; long_chirp_lut[1690] = 8'd 31; long_chirp_lut[1691] = 8'd 9; long_chirp_lut[1692] = 8'd112; long_chirp_lut[1693] = 8'd231; long_chirp_lut[1694] = 8'd241; long_chirp_lut[1695] = 8'd132;
|
||||
long_chirp_lut[1696] = 8'd 18; long_chirp_lut[1697] = 8'd 19; long_chirp_lut[1698] = 8'd135; long_chirp_lut[1699] = 8'd243; long_chirp_lut[1700] = 8'd229; long_chirp_lut[1701] = 8'd109; long_chirp_lut[1702] = 8'd 8; long_chirp_lut[1703] = 8'd 33; long_chirp_lut[1704] = 8'd157; long_chirp_lut[1705] = 8'd250; long_chirp_lut[1706] = 8'd215; long_chirp_lut[1707] = 8'd 88; long_chirp_lut[1708] = 8'd 3; long_chirp_lut[1709] = 8'd 48; long_chirp_lut[1710] = 8'd176; long_chirp_lut[1711] = 8'd254;
|
||||
long_chirp_lut[1712] = 8'd199; long_chirp_lut[1713] = 8'd 70; long_chirp_lut[1714] = 8'd 1; long_chirp_lut[1715] = 8'd 64; long_chirp_lut[1716] = 8'd193; long_chirp_lut[1717] = 8'd254; long_chirp_lut[1718] = 8'd183; long_chirp_lut[1719] = 8'd 54; long_chirp_lut[1720] = 8'd 1; long_chirp_lut[1721] = 8'd 80; long_chirp_lut[1722] = 8'd208; long_chirp_lut[1723] = 8'd252; long_chirp_lut[1724] = 8'd167; long_chirp_lut[1725] = 8'd 41; long_chirp_lut[1726] = 8'd 4; long_chirp_lut[1727] = 8'd 96;
|
||||
long_chirp_lut[1728] = 8'd220; long_chirp_lut[1729] = 8'd248; long_chirp_lut[1730] = 8'd151; long_chirp_lut[1731] = 8'd 30; long_chirp_lut[1732] = 8'd 9; long_chirp_lut[1733] = 8'd111; long_chirp_lut[1734] = 8'd230; long_chirp_lut[1735] = 8'd243; long_chirp_lut[1736] = 8'd137; long_chirp_lut[1737] = 8'd 21; long_chirp_lut[1738] = 8'd 15; long_chirp_lut[1739] = 8'd125; long_chirp_lut[1740] = 8'd237; long_chirp_lut[1741] = 8'd236; long_chirp_lut[1742] = 8'd123; long_chirp_lut[1743] = 8'd 14;
|
||||
long_chirp_lut[1744] = 8'd 22; long_chirp_lut[1745] = 8'd138; long_chirp_lut[1746] = 8'd243; long_chirp_lut[1747] = 8'd229; long_chirp_lut[1748] = 8'd111; long_chirp_lut[1749] = 8'd 9; long_chirp_lut[1750] = 8'd 29; long_chirp_lut[1751] = 8'd150; long_chirp_lut[1752] = 8'd247; long_chirp_lut[1753] = 8'd222; long_chirp_lut[1754] = 8'd100; long_chirp_lut[1755] = 8'd 6; long_chirp_lut[1756] = 8'd 36; long_chirp_lut[1757] = 8'd159; long_chirp_lut[1758] = 8'd250; long_chirp_lut[1759] = 8'd216;
|
||||
long_chirp_lut[1760] = 8'd 91; long_chirp_lut[1761] = 8'd 4; long_chirp_lut[1762] = 8'd 42; long_chirp_lut[1763] = 8'd168; long_chirp_lut[1764] = 8'd252; long_chirp_lut[1765] = 8'd209; long_chirp_lut[1766] = 8'd 83; long_chirp_lut[1767] = 8'd 2; long_chirp_lut[1768] = 8'd 48; long_chirp_lut[1769] = 8'd175; long_chirp_lut[1770] = 8'd253; long_chirp_lut[1771] = 8'd204; long_chirp_lut[1772] = 8'd 77; long_chirp_lut[1773] = 8'd 1; long_chirp_lut[1774] = 8'd 54; long_chirp_lut[1775] = 8'd181;
|
||||
long_chirp_lut[1776] = 8'd254; long_chirp_lut[1777] = 8'd199; long_chirp_lut[1778] = 8'd 72; long_chirp_lut[1779] = 8'd 1; long_chirp_lut[1780] = 8'd 58; long_chirp_lut[1781] = 8'd185; long_chirp_lut[1782] = 8'd254; long_chirp_lut[1783] = 8'd196; long_chirp_lut[1784] = 8'd 68; long_chirp_lut[1785] = 8'd 1; long_chirp_lut[1786] = 8'd 61; long_chirp_lut[1787] = 8'd188; long_chirp_lut[1788] = 8'd254; long_chirp_lut[1789] = 8'd193; long_chirp_lut[1790] = 8'd 66; long_chirp_lut[1791] = 8'd 1;
|
||||
long_chirp_lut[1792] = 8'd 63; long_chirp_lut[1793] = 8'd190; long_chirp_lut[1794] = 8'd254; long_chirp_lut[1795] = 8'd191; long_chirp_lut[1796] = 8'd 64; long_chirp_lut[1797] = 8'd 1; long_chirp_lut[1798] = 8'd 64; long_chirp_lut[1799] = 8'd191; long_chirp_lut[1800] = 8'd255; long_chirp_lut[1801] = 8'd191; long_chirp_lut[1802] = 8'd 64; long_chirp_lut[1803] = 8'd 1; long_chirp_lut[1804] = 8'd 64; long_chirp_lut[1805] = 8'd191; long_chirp_lut[1806] = 8'd254; long_chirp_lut[1807] = 8'd192;
|
||||
long_chirp_lut[1808] = 8'd 65; long_chirp_lut[1809] = 8'd 1; long_chirp_lut[1810] = 8'd 62; long_chirp_lut[1811] = 8'd189; long_chirp_lut[1812] = 8'd254; long_chirp_lut[1813] = 8'd194; long_chirp_lut[1814] = 8'd 67; long_chirp_lut[1815] = 8'd 1; long_chirp_lut[1816] = 8'd 60; long_chirp_lut[1817] = 8'd186; long_chirp_lut[1818] = 8'd254; long_chirp_lut[1819] = 8'd197; long_chirp_lut[1820] = 8'd 71; long_chirp_lut[1821] = 8'd 1; long_chirp_lut[1822] = 8'd 56; long_chirp_lut[1823] = 8'd182;
|
||||
long_chirp_lut[1824] = 8'd254; long_chirp_lut[1825] = 8'd201; long_chirp_lut[1826] = 8'd 75; long_chirp_lut[1827] = 8'd 1; long_chirp_lut[1828] = 8'd 52; long_chirp_lut[1829] = 8'd177; long_chirp_lut[1830] = 8'd253; long_chirp_lut[1831] = 8'd206; long_chirp_lut[1832] = 8'd 81; long_chirp_lut[1833] = 8'd 2; long_chirp_lut[1834] = 8'd 46; long_chirp_lut[1835] = 8'd171; long_chirp_lut[1836] = 8'd252; long_chirp_lut[1837] = 8'd212; long_chirp_lut[1838] = 8'd 88; long_chirp_lut[1839] = 8'd 4;
|
||||
long_chirp_lut[1840] = 8'd 40; long_chirp_lut[1841] = 8'd162; long_chirp_lut[1842] = 8'd250; long_chirp_lut[1843] = 8'd218; long_chirp_lut[1844] = 8'd 97; long_chirp_lut[1845] = 8'd 6; long_chirp_lut[1846] = 8'd 34; long_chirp_lut[1847] = 8'd153; long_chirp_lut[1848] = 8'd247; long_chirp_lut[1849] = 8'd225; long_chirp_lut[1850] = 8'd107; long_chirp_lut[1851] = 8'd 9; long_chirp_lut[1852] = 8'd 27; long_chirp_lut[1853] = 8'd142; long_chirp_lut[1854] = 8'd243; long_chirp_lut[1855] = 8'd232;
|
||||
long_chirp_lut[1856] = 8'd119; long_chirp_lut[1857] = 8'd 14; long_chirp_lut[1858] = 8'd 20; long_chirp_lut[1859] = 8'd130; long_chirp_lut[1860] = 8'd237; long_chirp_lut[1861] = 8'd239; long_chirp_lut[1862] = 8'd132; long_chirp_lut[1863] = 8'd 21; long_chirp_lut[1864] = 8'd 13; long_chirp_lut[1865] = 8'd116; long_chirp_lut[1866] = 8'd230; long_chirp_lut[1867] = 8'd245; long_chirp_lut[1868] = 8'd146; long_chirp_lut[1869] = 8'd 30; long_chirp_lut[1870] = 8'd 8; long_chirp_lut[1871] = 8'd101;
|
||||
long_chirp_lut[1872] = 8'd220; long_chirp_lut[1873] = 8'd250; long_chirp_lut[1874] = 8'd162; long_chirp_lut[1875] = 8'd 41; long_chirp_lut[1876] = 8'd 3; long_chirp_lut[1877] = 8'd 85; long_chirp_lut[1878] = 8'd208; long_chirp_lut[1879] = 8'd253; long_chirp_lut[1880] = 8'd178; long_chirp_lut[1881] = 8'd 54; long_chirp_lut[1882] = 8'd 1; long_chirp_lut[1883] = 8'd 69; long_chirp_lut[1884] = 8'd193; long_chirp_lut[1885] = 8'd254; long_chirp_lut[1886] = 8'd194; long_chirp_lut[1887] = 8'd 70;
|
||||
long_chirp_lut[1888] = 8'd 1; long_chirp_lut[1889] = 8'd 53; long_chirp_lut[1890] = 8'd176; long_chirp_lut[1891] = 8'd253; long_chirp_lut[1892] = 8'd210; long_chirp_lut[1893] = 8'd 88; long_chirp_lut[1894] = 8'd 4; long_chirp_lut[1895] = 8'd 37; long_chirp_lut[1896] = 8'd157; long_chirp_lut[1897] = 8'd248; long_chirp_lut[1898] = 8'd225; long_chirp_lut[1899] = 8'd109; long_chirp_lut[1900] = 8'd 11; long_chirp_lut[1901] = 8'd 23; long_chirp_lut[1902] = 8'd135; long_chirp_lut[1903] = 8'd239;
|
||||
long_chirp_lut[1904] = 8'd238; long_chirp_lut[1905] = 8'd132; long_chirp_lut[1906] = 8'd 22; long_chirp_lut[1907] = 8'd 12; long_chirp_lut[1908] = 8'd112; long_chirp_lut[1909] = 8'd226; long_chirp_lut[1910] = 8'd247; long_chirp_lut[1911] = 8'd155; long_chirp_lut[1912] = 8'd 37; long_chirp_lut[1913] = 8'd 4; long_chirp_lut[1914] = 8'd 88; long_chirp_lut[1915] = 8'd209; long_chirp_lut[1916] = 8'd253; long_chirp_lut[1917] = 8'd179; long_chirp_lut[1918] = 8'd 57; long_chirp_lut[1919] = 8'd 1;
|
||||
long_chirp_lut[1920] = 8'd 64; long_chirp_lut[1921] = 8'd187; long_chirp_lut[1922] = 8'd254; long_chirp_lut[1923] = 8'd202; long_chirp_lut[1924] = 8'd 80; long_chirp_lut[1925] = 8'd 3; long_chirp_lut[1926] = 8'd 42; long_chirp_lut[1927] = 8'd162; long_chirp_lut[1928] = 8'd249; long_chirp_lut[1929] = 8'd223; long_chirp_lut[1930] = 8'd107; long_chirp_lut[1931] = 8'd 11; long_chirp_lut[1932] = 8'd 23; long_chirp_lut[1933] = 8'd133; long_chirp_lut[1934] = 8'd238; long_chirp_lut[1935] = 8'd240;
|
||||
long_chirp_lut[1936] = 8'd137; long_chirp_lut[1937] = 8'd 25; long_chirp_lut[1938] = 8'd 9; long_chirp_lut[1939] = 8'd103; long_chirp_lut[1940] = 8'd220; long_chirp_lut[1941] = 8'd251; long_chirp_lut[1942] = 8'd167; long_chirp_lut[1943] = 8'd 47; long_chirp_lut[1944] = 8'd 2; long_chirp_lut[1945] = 8'd 73; long_chirp_lut[1946] = 8'd195; long_chirp_lut[1947] = 8'd254; long_chirp_lut[1948] = 8'd196; long_chirp_lut[1949] = 8'd 74; long_chirp_lut[1950] = 8'd 2; long_chirp_lut[1951] = 8'd 46;
|
||||
long_chirp_lut[1952] = 8'd166; long_chirp_lut[1953] = 8'd250; long_chirp_lut[1954] = 8'd221; long_chirp_lut[1955] = 8'd106; long_chirp_lut[1956] = 8'd 10; long_chirp_lut[1957] = 8'd 23; long_chirp_lut[1958] = 8'd132; long_chirp_lut[1959] = 8'd237; long_chirp_lut[1960] = 8'd241; long_chirp_lut[1961] = 8'd141; long_chirp_lut[1962] = 8'd 28; long_chirp_lut[1963] = 8'd 7; long_chirp_lut[1964] = 8'd 96; long_chirp_lut[1965] = 8'd214; long_chirp_lut[1966] = 8'd252; long_chirp_lut[1967] = 8'd176;
|
||||
long_chirp_lut[1968] = 8'd 55; long_chirp_lut[1969] = 8'd 1; long_chirp_lut[1970] = 8'd 62; long_chirp_lut[1971] = 8'd184; long_chirp_lut[1972] = 8'd254; long_chirp_lut[1973] = 8'd208; long_chirp_lut[1974] = 8'd 89; long_chirp_lut[1975] = 8'd 5; long_chirp_lut[1976] = 8'd 33; long_chirp_lut[1977] = 8'd147; long_chirp_lut[1978] = 8'd243; long_chirp_lut[1979] = 8'd234; long_chirp_lut[1980] = 8'd127; long_chirp_lut[1981] = 8'd 21; long_chirp_lut[1982] = 8'd 11; long_chirp_lut[1983] = 8'd107;
|
||||
long_chirp_lut[1984] = 8'd222; long_chirp_lut[1985] = 8'd250; long_chirp_lut[1986] = 8'd167; long_chirp_lut[1987] = 8'd 48; long_chirp_lut[1988] = 8'd 1; long_chirp_lut[1989] = 8'd 69; long_chirp_lut[1990] = 8'd189; long_chirp_lut[1991] = 8'd254; long_chirp_lut[1992] = 8'd204; long_chirp_lut[1993] = 8'd 85; long_chirp_lut[1994] = 8'd 4; long_chirp_lut[1995] = 8'd 35; long_chirp_lut[1996] = 8'd149; long_chirp_lut[1997] = 8'd244; long_chirp_lut[1998] = 8'd234; long_chirp_lut[1999] = 8'd128;
|
||||
long_chirp_lut[2000] = 8'd 21; long_chirp_lut[2001] = 8'd 11; long_chirp_lut[2002] = 8'd105; long_chirp_lut[2003] = 8'd220; long_chirp_lut[2004] = 8'd251; long_chirp_lut[2005] = 8'd171; long_chirp_lut[2006] = 8'd 52; long_chirp_lut[2007] = 8'd 1; long_chirp_lut[2008] = 8'd 63; long_chirp_lut[2009] = 8'd183; long_chirp_lut[2010] = 8'd253; long_chirp_lut[2011] = 8'd211; long_chirp_lut[2012] = 8'd 94; long_chirp_lut[2013] = 8'd 7; long_chirp_lut[2014] = 8'd 28; long_chirp_lut[2015] = 8'd138;
|
||||
long_chirp_lut[2016] = 8'd239; long_chirp_lut[2017] = 8'd240; long_chirp_lut[2018] = 8'd141; long_chirp_lut[2019] = 8'd 30; long_chirp_lut[2020] = 8'd 6; long_chirp_lut[2021] = 8'd 90; long_chirp_lut[2022] = 8'd208; long_chirp_lut[2023] = 8'd254; long_chirp_lut[2024] = 8'd187; long_chirp_lut[2025] = 8'd 68; long_chirp_lut[2026] = 8'd 1; long_chirp_lut[2027] = 8'd 47; long_chirp_lut[2028] = 8'd164; long_chirp_lut[2029] = 8'd249; long_chirp_lut[2030] = 8'd226; long_chirp_lut[2031] = 8'd116;
|
||||
long_chirp_lut[2032] = 8'd 16; long_chirp_lut[2033] = 8'd 15; long_chirp_lut[2034] = 8'd114; long_chirp_lut[2035] = 8'd224; long_chirp_lut[2036] = 8'd250; long_chirp_lut[2037] = 8'd167; long_chirp_lut[2038] = 8'd 49; long_chirp_lut[2039] = 8'd 1; long_chirp_lut[2040] = 8'd 64; long_chirp_lut[2041] = 8'd183; long_chirp_lut[2042] = 8'd253; long_chirp_lut[2043] = 8'd213; long_chirp_lut[2044] = 8'd 97; long_chirp_lut[2045] = 8'd 8; long_chirp_lut[2046] = 8'd 24; long_chirp_lut[2047] = 8'd131;
|
||||
long_chirp_lut[2048] = 8'd235; long_chirp_lut[2049] = 8'd244; long_chirp_lut[2050] = 8'd151; long_chirp_lut[2051] = 8'd 38; long_chirp_lut[2052] = 8'd 3; long_chirp_lut[2053] = 8'd 77; long_chirp_lut[2054] = 8'd195; long_chirp_lut[2055] = 8'd254; long_chirp_lut[2056] = 8'd202; long_chirp_lut[2057] = 8'd 85; long_chirp_lut[2058] = 8'd 5; long_chirp_lut[2059] = 8'd 32; long_chirp_lut[2060] = 8'd142; long_chirp_lut[2061] = 8'd240; long_chirp_lut[2062] = 8'd240; long_chirp_lut[2063] = 8'd142;
|
||||
long_chirp_lut[2064] = 8'd 31; long_chirp_lut[2065] = 8'd 5; long_chirp_lut[2066] = 8'd 85; long_chirp_lut[2067] = 8'd202; long_chirp_lut[2068] = 8'd254; long_chirp_lut[2069] = 8'd197; long_chirp_lut[2070] = 8'd 79; long_chirp_lut[2071] = 8'd 3; long_chirp_lut[2072] = 8'd 35; long_chirp_lut[2073] = 8'd147; long_chirp_lut[2074] = 8'd242; long_chirp_lut[2075] = 8'd238; long_chirp_lut[2076] = 8'd138; long_chirp_lut[2077] = 8'd 29; long_chirp_lut[2078] = 8'd 5; long_chirp_lut[2079] = 8'd 87;
|
||||
long_chirp_lut[2080] = 8'd203; long_chirp_lut[2081] = 8'd254; long_chirp_lut[2082] = 8'd196; long_chirp_lut[2083] = 8'd 79; long_chirp_lut[2084] = 8'd 3; long_chirp_lut[2085] = 8'd 35; long_chirp_lut[2086] = 8'd146; long_chirp_lut[2087] = 8'd241; long_chirp_lut[2088] = 8'd239; long_chirp_lut[2089] = 8'd141; long_chirp_lut[2090] = 8'd 31; long_chirp_lut[2091] = 8'd 4; long_chirp_lut[2092] = 8'd 83; long_chirp_lut[2093] = 8'd200; long_chirp_lut[2094] = 8'd254; long_chirp_lut[2095] = 8'd201;
|
||||
long_chirp_lut[2096] = 8'd 84; long_chirp_lut[2097] = 8'd 5; long_chirp_lut[2098] = 8'd 30; long_chirp_lut[2099] = 8'd139; long_chirp_lut[2100] = 8'd237; long_chirp_lut[2101] = 8'd243; long_chirp_lut[2102] = 8'd150; long_chirp_lut[2103] = 8'd 38; long_chirp_lut[2104] = 8'd 2; long_chirp_lut[2105] = 8'd 73; long_chirp_lut[2106] = 8'd190; long_chirp_lut[2107] = 8'd254; long_chirp_lut[2108] = 8'd210; long_chirp_lut[2109] = 8'd 96; long_chirp_lut[2110] = 8'd 9; long_chirp_lut[2111] = 8'd 22;
|
||||
long_chirp_lut[2112] = 8'd125; long_chirp_lut[2113] = 8'd230; long_chirp_lut[2114] = 8'd248; long_chirp_lut[2115] = 8'd164; long_chirp_lut[2116] = 8'd 50; long_chirp_lut[2117] = 8'd 1; long_chirp_lut[2118] = 8'd 59; long_chirp_lut[2119] = 8'd175; long_chirp_lut[2120] = 8'd251; long_chirp_lut[2121] = 8'd223; long_chirp_lut[2122] = 8'd114; long_chirp_lut[2123] = 8'd 17; long_chirp_lut[2124] = 8'd 13; long_chirp_lut[2125] = 8'd105; long_chirp_lut[2126] = 8'd216; long_chirp_lut[2127] = 8'd253;
|
||||
long_chirp_lut[2128] = 8'd184; long_chirp_lut[2129] = 8'd 68; long_chirp_lut[2130] = 8'd 2; long_chirp_lut[2131] = 8'd 41; long_chirp_lut[2132] = 8'd153; long_chirp_lut[2133] = 8'd243; long_chirp_lut[2134] = 8'd237; long_chirp_lut[2135] = 8'd139; long_chirp_lut[2136] = 8'd 31; long_chirp_lut[2137] = 8'd 4; long_chirp_lut[2138] = 8'd 80; long_chirp_lut[2139] = 8'd195; long_chirp_lut[2140] = 8'd254; long_chirp_lut[2141] = 8'd207; long_chirp_lut[2142] = 8'd 94; long_chirp_lut[2143] = 8'd 8;
|
||||
long_chirp_lut[2144] = 8'd 22; long_chirp_lut[2145] = 8'd123; long_chirp_lut[2146] = 8'd228; long_chirp_lut[2147] = 8'd249; long_chirp_lut[2148] = 8'd169; long_chirp_lut[2149] = 8'd 55; long_chirp_lut[2150] = 8'd 1; long_chirp_lut[2151] = 8'd 52; long_chirp_lut[2152] = 8'd166; long_chirp_lut[2153] = 8'd248; long_chirp_lut[2154] = 8'd231; long_chirp_lut[2155] = 8'd128; long_chirp_lut[2156] = 8'd 25; long_chirp_lut[2157] = 8'd 7; long_chirp_lut[2158] = 8'd 88; long_chirp_lut[2159] = 8'd202;
|
||||
long_chirp_lut[2160] = 8'd255; long_chirp_lut[2161] = 8'd202; long_chirp_lut[2162] = 8'd 88; long_chirp_lut[2163] = 8'd 7; long_chirp_lut[2164] = 8'd 25; long_chirp_lut[2165] = 8'd127; long_chirp_lut[2166] = 8'd230; long_chirp_lut[2167] = 8'd249; long_chirp_lut[2168] = 8'd168; long_chirp_lut[2169] = 8'd 54; long_chirp_lut[2170] = 8'd 1; long_chirp_lut[2171] = 8'd 51; long_chirp_lut[2172] = 8'd164; long_chirp_lut[2173] = 8'd247; long_chirp_lut[2174] = 8'd232; long_chirp_lut[2175] = 8'd132;
|
||||
long_chirp_lut[2176] = 8'd 28; long_chirp_lut[2177] = 8'd 5; long_chirp_lut[2178] = 8'd 83; long_chirp_lut[2179] = 8'd197; long_chirp_lut[2180] = 8'd254; long_chirp_lut[2181] = 8'd209; long_chirp_lut[2182] = 8'd 97; long_chirp_lut[2183] = 8'd 10; long_chirp_lut[2184] = 8'd 19; long_chirp_lut[2185] = 8'd116; long_chirp_lut[2186] = 8'd222; long_chirp_lut[2187] = 8'd252; long_chirp_lut[2188] = 8'd180; long_chirp_lut[2189] = 8'd 66; long_chirp_lut[2190] = 8'd 2; long_chirp_lut[2191] = 8'd 39;
|
||||
long_chirp_lut[2192] = 8'd148; long_chirp_lut[2193] = 8'd241; long_chirp_lut[2194] = 8'd241; long_chirp_lut[2195] = 8'd150; long_chirp_lut[2196] = 8'd 41; long_chirp_lut[2197] = 8'd 1; long_chirp_lut[2198] = 8'd 64; long_chirp_lut[2199] = 8'd178; long_chirp_lut[2200] = 8'd251; long_chirp_lut[2201] = 8'd225; long_chirp_lut[2202] = 8'd120; long_chirp_lut[2203] = 8'd 21; long_chirp_lut[2204] = 8'd 8; long_chirp_lut[2205] = 8'd 91; long_chirp_lut[2206] = 8'd203; long_chirp_lut[2207] = 8'd254;
|
||||
long_chirp_lut[2208] = 8'd204; long_chirp_lut[2209] = 8'd 93; long_chirp_lut[2210] = 8'd 9; long_chirp_lut[2211] = 8'd 20; long_chirp_lut[2212] = 8'd117; long_chirp_lut[2213] = 8'd223; long_chirp_lut[2214] = 8'd252; long_chirp_lut[2215] = 8'd182; long_chirp_lut[2216] = 8'd 68; long_chirp_lut[2217] = 8'd 2; long_chirp_lut[2218] = 8'd 36; long_chirp_lut[2219] = 8'd143; long_chirp_lut[2220] = 8'd237; long_chirp_lut[2221] = 8'd244; long_chirp_lut[2222] = 8'd158; long_chirp_lut[2223] = 8'd 48;
|
||||
long_chirp_lut[2224] = 8'd 1; long_chirp_lut[2225] = 8'd 54; long_chirp_lut[2226] = 8'd166; long_chirp_lut[2227] = 8'd247; long_chirp_lut[2228] = 8'd233; long_chirp_lut[2229] = 8'd136; long_chirp_lut[2230] = 8'd 31; long_chirp_lut[2231] = 8'd 3; long_chirp_lut[2232] = 8'd 73; long_chirp_lut[2233] = 8'd186; long_chirp_lut[2234] = 8'd253; long_chirp_lut[2235] = 8'd220; long_chirp_lut[2236] = 8'd115; long_chirp_lut[2237] = 8'd 19; long_chirp_lut[2238] = 8'd 9; long_chirp_lut[2239] = 8'd 92;
|
||||
long_chirp_lut[2240] = 8'd203; long_chirp_lut[2241] = 8'd254; long_chirp_lut[2242] = 8'd206; long_chirp_lut[2243] = 8'd 96; long_chirp_lut[2244] = 8'd 10; long_chirp_lut[2245] = 8'd 17; long_chirp_lut[2246] = 8'd111; long_chirp_lut[2247] = 8'd217; long_chirp_lut[2248] = 8'd253; long_chirp_lut[2249] = 8'd191; long_chirp_lut[2250] = 8'd 79; long_chirp_lut[2251] = 8'd 5; long_chirp_lut[2252] = 8'd 27; long_chirp_lut[2253] = 8'd127; long_chirp_lut[2254] = 8'd228; long_chirp_lut[2255] = 8'd250;
|
||||
long_chirp_lut[2256] = 8'd177; long_chirp_lut[2257] = 8'd 65; long_chirp_lut[2258] = 8'd 2; long_chirp_lut[2259] = 8'd 37; long_chirp_lut[2260] = 8'd142; long_chirp_lut[2261] = 8'd236; long_chirp_lut[2262] = 8'd246; long_chirp_lut[2263] = 8'd163; long_chirp_lut[2264] = 8'd 53; long_chirp_lut[2265] = 8'd 1; long_chirp_lut[2266] = 8'd 46; long_chirp_lut[2267] = 8'd155; long_chirp_lut[2268] = 8'd242; long_chirp_lut[2269] = 8'd241; long_chirp_lut[2270] = 8'd151; long_chirp_lut[2271] = 8'd 44;
|
||||
long_chirp_lut[2272] = 8'd 1; long_chirp_lut[2273] = 8'd 56; long_chirp_lut[2274] = 8'd166; long_chirp_lut[2275] = 8'd247; long_chirp_lut[2276] = 8'd235; long_chirp_lut[2277] = 8'd141; long_chirp_lut[2278] = 8'd 36; long_chirp_lut[2279] = 8'd 2; long_chirp_lut[2280] = 8'd 64; long_chirp_lut[2281] = 8'd175; long_chirp_lut[2282] = 8'd250; long_chirp_lut[2283] = 8'd230; long_chirp_lut[2284] = 8'd132; long_chirp_lut[2285] = 8'd 31; long_chirp_lut[2286] = 8'd 3; long_chirp_lut[2287] = 8'd 71;
|
||||
long_chirp_lut[2288] = 8'd182; long_chirp_lut[2289] = 8'd251; long_chirp_lut[2290] = 8'd226; long_chirp_lut[2291] = 8'd125; long_chirp_lut[2292] = 8'd 26; long_chirp_lut[2293] = 8'd 5; long_chirp_lut[2294] = 8'd 77; long_chirp_lut[2295] = 8'd187; long_chirp_lut[2296] = 8'd253; long_chirp_lut[2297] = 8'd222; long_chirp_lut[2298] = 8'd120; long_chirp_lut[2299] = 8'd 23; long_chirp_lut[2300] = 8'd 6; long_chirp_lut[2301] = 8'd 81; long_chirp_lut[2302] = 8'd191; long_chirp_lut[2303] = 8'd253;
|
||||
long_chirp_lut[2304] = 8'd220; long_chirp_lut[2305] = 8'd117; long_chirp_lut[2306] = 8'd 22; long_chirp_lut[2307] = 8'd 7; long_chirp_lut[2308] = 8'd 83; long_chirp_lut[2309] = 8'd193; long_chirp_lut[2310] = 8'd253; long_chirp_lut[2311] = 8'd219; long_chirp_lut[2312] = 8'd115; long_chirp_lut[2313] = 8'd 21; long_chirp_lut[2314] = 8'd 7; long_chirp_lut[2315] = 8'd 84; long_chirp_lut[2316] = 8'd193; long_chirp_lut[2317] = 8'd253; long_chirp_lut[2318] = 8'd219; long_chirp_lut[2319] = 8'd116;
|
||||
long_chirp_lut[2320] = 8'd 21; long_chirp_lut[2321] = 8'd 7; long_chirp_lut[2322] = 8'd 83; long_chirp_lut[2323] = 8'd192; long_chirp_lut[2324] = 8'd253; long_chirp_lut[2325] = 8'd220; long_chirp_lut[2326] = 8'd118; long_chirp_lut[2327] = 8'd 23; long_chirp_lut[2328] = 8'd 6; long_chirp_lut[2329] = 8'd 80; long_chirp_lut[2330] = 8'd189; long_chirp_lut[2331] = 8'd253; long_chirp_lut[2332] = 8'd223; long_chirp_lut[2333] = 8'd122; long_chirp_lut[2334] = 8'd 25; long_chirp_lut[2335] = 8'd 5;
|
||||
long_chirp_lut[2336] = 8'd 76; long_chirp_lut[2337] = 8'd185; long_chirp_lut[2338] = 8'd252; long_chirp_lut[2339] = 8'd226; long_chirp_lut[2340] = 8'd128; long_chirp_lut[2341] = 8'd 29; long_chirp_lut[2342] = 8'd 3; long_chirp_lut[2343] = 8'd 70; long_chirp_lut[2344] = 8'd179; long_chirp_lut[2345] = 8'd250; long_chirp_lut[2346] = 8'd231; long_chirp_lut[2347] = 8'd135; long_chirp_lut[2348] = 8'd 34; long_chirp_lut[2349] = 8'd 2; long_chirp_lut[2350] = 8'd 62; long_chirp_lut[2351] = 8'd171;
|
||||
long_chirp_lut[2352] = 8'd247; long_chirp_lut[2353] = 8'd236; long_chirp_lut[2354] = 8'd144; long_chirp_lut[2355] = 8'd 41; long_chirp_lut[2356] = 8'd 1; long_chirp_lut[2357] = 8'd 54; long_chirp_lut[2358] = 8'd161; long_chirp_lut[2359] = 8'd244; long_chirp_lut[2360] = 8'd241; long_chirp_lut[2361] = 8'd155; long_chirp_lut[2362] = 8'd 49; long_chirp_lut[2363] = 8'd 1; long_chirp_lut[2364] = 8'd 45; long_chirp_lut[2365] = 8'd149; long_chirp_lut[2366] = 8'd238; long_chirp_lut[2367] = 8'd246;
|
||||
long_chirp_lut[2368] = 8'd168; long_chirp_lut[2369] = 8'd 60; long_chirp_lut[2370] = 8'd 2; long_chirp_lut[2371] = 8'd 35; long_chirp_lut[2372] = 8'd135; long_chirp_lut[2373] = 8'd230; long_chirp_lut[2374] = 8'd251; long_chirp_lut[2375] = 8'd182; long_chirp_lut[2376] = 8'd 73; long_chirp_lut[2377] = 8'd 4; long_chirp_lut[2378] = 8'd 25; long_chirp_lut[2379] = 8'd119; long_chirp_lut[2380] = 8'd220; long_chirp_lut[2381] = 8'd254; long_chirp_lut[2382] = 8'd196; long_chirp_lut[2383] = 8'd 89;
|
||||
long_chirp_lut[2384] = 8'd 10; long_chirp_lut[2385] = 8'd 15; long_chirp_lut[2386] = 8'd102; long_chirp_lut[2387] = 8'd207; long_chirp_lut[2388] = 8'd254; long_chirp_lut[2389] = 8'd211; long_chirp_lut[2390] = 8'd107; long_chirp_lut[2391] = 8'd 18; long_chirp_lut[2392] = 8'd 8; long_chirp_lut[2393] = 8'd 83; long_chirp_lut[2394] = 8'd190; long_chirp_lut[2395] = 8'd252; long_chirp_lut[2396] = 8'd225; long_chirp_lut[2397] = 8'd128; long_chirp_lut[2398] = 8'd 30; long_chirp_lut[2399] = 8'd 2;
|
||||
long_chirp_lut[2400] = 8'd 64; long_chirp_lut[2401] = 8'd171; long_chirp_lut[2402] = 8'd247; long_chirp_lut[2403] = 8'd238; long_chirp_lut[2404] = 8'd150; long_chirp_lut[2405] = 8'd 46; long_chirp_lut[2406] = 8'd 1; long_chirp_lut[2407] = 8'd 45; long_chirp_lut[2408] = 8'd148; long_chirp_lut[2409] = 8'd237; long_chirp_lut[2410] = 8'd247; long_chirp_lut[2411] = 8'd173; long_chirp_lut[2412] = 8'd 66; long_chirp_lut[2413] = 8'd 3; long_chirp_lut[2414] = 8'd 28; long_chirp_lut[2415] = 8'd123;
|
||||
long_chirp_lut[2416] = 8'd222; long_chirp_lut[2417] = 8'd253; long_chirp_lut[2418] = 8'd196; long_chirp_lut[2419] = 8'd 90; long_chirp_lut[2420] = 8'd 11; long_chirp_lut[2421] = 8'd 14; long_chirp_lut[2422] = 8'd 97; long_chirp_lut[2423] = 8'd201; long_chirp_lut[2424] = 8'd254; long_chirp_lut[2425] = 8'd218; long_chirp_lut[2426] = 8'd118; long_chirp_lut[2427] = 8'd 25; long_chirp_lut[2428] = 8'd 4; long_chirp_lut[2429] = 8'd 70; long_chirp_lut[2430] = 8'd176; long_chirp_lut[2431] = 8'd248;
|
||||
long_chirp_lut[2432] = 8'd236; long_chirp_lut[2433] = 8'd148; long_chirp_lut[2434] = 8'd 45; long_chirp_lut[2435] = 8'd 1; long_chirp_lut[2436] = 8'd 45; long_chirp_lut[2437] = 8'd146; long_chirp_lut[2438] = 8'd235; long_chirp_lut[2439] = 8'd249; long_chirp_lut[2440] = 8'd178; long_chirp_lut[2441] = 8'd 72; long_chirp_lut[2442] = 8'd 5; long_chirp_lut[2443] = 8'd 23; long_chirp_lut[2444] = 8'd114; long_chirp_lut[2445] = 8'd214; long_chirp_lut[2446] = 8'd254; long_chirp_lut[2447] = 8'd206;
|
||||
long_chirp_lut[2448] = 8'd104; long_chirp_lut[2449] = 8'd 18; long_chirp_lut[2450] = 8'd 8; long_chirp_lut[2451] = 8'd 81; long_chirp_lut[2452] = 8'd186; long_chirp_lut[2453] = 8'd251; long_chirp_lut[2454] = 8'd231; long_chirp_lut[2455] = 8'd139; long_chirp_lut[2456] = 8'd 39; long_chirp_lut[2457] = 8'd 1; long_chirp_lut[2458] = 8'd 49; long_chirp_lut[2459] = 8'd152; long_chirp_lut[2460] = 8'd237; long_chirp_lut[2461] = 8'd248; long_chirp_lut[2462] = 8'd175; long_chirp_lut[2463] = 8'd 70;
|
||||
long_chirp_lut[2464] = 8'd 4; long_chirp_lut[2465] = 8'd 23; long_chirp_lut[2466] = 8'd114; long_chirp_lut[2467] = 8'd213; long_chirp_lut[2468] = 8'd254; long_chirp_lut[2469] = 8'd209; long_chirp_lut[2470] = 8'd107; long_chirp_lut[2471] = 8'd 20; long_chirp_lut[2472] = 8'd 6; long_chirp_lut[2473] = 8'd 75; long_chirp_lut[2474] = 8'd180; long_chirp_lut[2475] = 8'd249; long_chirp_lut[2476] = 8'd235; long_chirp_lut[2477] = 8'd148; long_chirp_lut[2478] = 8'd 47; long_chirp_lut[2479] = 8'd 1;
|
||||
long_chirp_lut[2480] = 8'd 40; long_chirp_lut[2481] = 8'd139; long_chirp_lut[2482] = 8'd230; long_chirp_lut[2483] = 8'd251; long_chirp_lut[2484] = 8'd189; long_chirp_lut[2485] = 8'd 84; long_chirp_lut[2486] = 8'd 9; long_chirp_lut[2487] = 8'd 14; long_chirp_lut[2488] = 8'd 96; long_chirp_lut[2489] = 8'd199; long_chirp_lut[2490] = 8'd253; long_chirp_lut[2491] = 8'd223; long_chirp_lut[2492] = 8'd129; long_chirp_lut[2493] = 8'd 33; long_chirp_lut[2494] = 8'd 1; long_chirp_lut[2495] = 8'd 54;
|
||||
long_chirp_lut[2496] = 8'd157; long_chirp_lut[2497] = 8'd239; long_chirp_lut[2498] = 8'd247; long_chirp_lut[2499] = 8'd174; long_chirp_lut[2500] = 8'd 71; long_chirp_lut[2501] = 8'd 5; long_chirp_lut[2502] = 8'd 21; long_chirp_lut[2503] = 8'd109; long_chirp_lut[2504] = 8'd209; long_chirp_lut[2505] = 8'd254; long_chirp_lut[2506] = 8'd215; long_chirp_lut[2507] = 8'd117; long_chirp_lut[2508] = 8'd 26; long_chirp_lut[2509] = 8'd 3; long_chirp_lut[2510] = 8'd 62; long_chirp_lut[2511] = 8'd165;
|
||||
long_chirp_lut[2512] = 8'd243; long_chirp_lut[2513] = 8'd244; long_chirp_lut[2514] = 8'd167; long_chirp_lut[2515] = 8'd 64; long_chirp_lut[2516] = 8'd 3; long_chirp_lut[2517] = 8'd 25; long_chirp_lut[2518] = 8'd114; long_chirp_lut[2519] = 8'd212; long_chirp_lut[2520] = 8'd255; long_chirp_lut[2521] = 8'd212; long_chirp_lut[2522] = 8'd114; long_chirp_lut[2523] = 8'd 25; long_chirp_lut[2524] = 8'd 3; long_chirp_lut[2525] = 8'd 64; long_chirp_lut[2526] = 8'd166; long_chirp_lut[2527] = 8'd243;
|
||||
long_chirp_lut[2528] = 8'd244; long_chirp_lut[2529] = 8'd168; long_chirp_lut[2530] = 8'd 66; long_chirp_lut[2531] = 8'd 4; long_chirp_lut[2532] = 8'd 23; long_chirp_lut[2533] = 8'd111; long_chirp_lut[2534] = 8'd210; long_chirp_lut[2535] = 8'd254; long_chirp_lut[2536] = 8'd216; long_chirp_lut[2537] = 8'd120; long_chirp_lut[2538] = 8'd 28; long_chirp_lut[2539] = 8'd 2; long_chirp_lut[2540] = 8'd 58; long_chirp_lut[2541] = 8'd159; long_chirp_lut[2542] = 8'd240; long_chirp_lut[2543] = 8'd247;
|
||||
long_chirp_lut[2544] = 8'd177; long_chirp_lut[2545] = 8'd 74; long_chirp_lut[2546] = 8'd 6; long_chirp_lut[2547] = 8'd 17; long_chirp_lut[2548] = 8'd100; long_chirp_lut[2549] = 8'd200; long_chirp_lut[2550] = 8'd253; long_chirp_lut[2551] = 8'd225; long_chirp_lut[2552] = 8'd133; long_chirp_lut[2553] = 8'd 38; long_chirp_lut[2554] = 8'd 1; long_chirp_lut[2555] = 8'd 46; long_chirp_lut[2556] = 8'd143; long_chirp_lut[2557] = 8'd231; long_chirp_lut[2558] = 8'd252; long_chirp_lut[2559] = 8'd192;
|
||||
long_chirp_lut[2560] = 8'd 91; long_chirp_lut[2561] = 8'd 13; long_chirp_lut[2562] = 8'd 9; long_chirp_lut[2563] = 8'd 81; long_chirp_lut[2564] = 8'd183; long_chirp_lut[2565] = 8'd249; long_chirp_lut[2566] = 8'd237; long_chirp_lut[2567] = 8'd155; long_chirp_lut[2568] = 8'd 55; long_chirp_lut[2569] = 8'd 2; long_chirp_lut[2570] = 8'd 29; long_chirp_lut[2571] = 8'd119; long_chirp_lut[2572] = 8'd215; long_chirp_lut[2573] = 8'd254; long_chirp_lut[2574] = 8'd213; long_chirp_lut[2575] = 8'd117;
|
||||
long_chirp_lut[2576] = 8'd 28; long_chirp_lut[2577] = 8'd 2; long_chirp_lut[2578] = 8'd 56; long_chirp_lut[2579] = 8'd156; long_chirp_lut[2580] = 8'd237; long_chirp_lut[2581] = 8'd249; long_chirp_lut[2582] = 8'd183; long_chirp_lut[2583] = 8'd 82; long_chirp_lut[2584] = 8'd 10; long_chirp_lut[2585] = 8'd 12; long_chirp_lut[2586] = 8'd 88; long_chirp_lut[2587] = 8'd188; long_chirp_lut[2588] = 8'd250; long_chirp_lut[2589] = 8'd235; long_chirp_lut[2590] = 8'd151; long_chirp_lut[2591] = 8'd 53;
|
||||
long_chirp_lut[2592] = 8'd 2; long_chirp_lut[2593] = 8'd 30; long_chirp_lut[2594] = 8'd119; long_chirp_lut[2595] = 8'd214; long_chirp_lut[2596] = 8'd254; long_chirp_lut[2597] = 8'd215; long_chirp_lut[2598] = 8'd120; long_chirp_lut[2599] = 8'd 30; long_chirp_lut[2600] = 8'd 1; long_chirp_lut[2601] = 8'd 52; long_chirp_lut[2602] = 8'd149; long_chirp_lut[2603] = 8'd234; long_chirp_lut[2604] = 8'd251; long_chirp_lut[2605] = 8'd191; long_chirp_lut[2606] = 8'd 92; long_chirp_lut[2607] = 8'd 14;
|
||||
long_chirp_lut[2608] = 8'd 8; long_chirp_lut[2609] = 8'd 76; long_chirp_lut[2610] = 8'd176; long_chirp_lut[2611] = 8'd246; long_chirp_lut[2612] = 8'd242; long_chirp_lut[2613] = 8'd167; long_chirp_lut[2614] = 8'd 67; long_chirp_lut[2615] = 8'd 5; long_chirp_lut[2616] = 8'd 19; long_chirp_lut[2617] = 8'd100; long_chirp_lut[2618] = 8'd198; long_chirp_lut[2619] = 8'd253; long_chirp_lut[2620] = 8'd229; long_chirp_lut[2621] = 8'd143; long_chirp_lut[2622] = 8'd 47; long_chirp_lut[2623] = 8'd 1;
|
||||
long_chirp_lut[2624] = 8'd 33; long_chirp_lut[2625] = 8'd123; long_chirp_lut[2626] = 8'd216; long_chirp_lut[2627] = 8'd254; long_chirp_lut[2628] = 8'd214; long_chirp_lut[2629] = 8'd121; long_chirp_lut[2630] = 8'd 31; long_chirp_lut[2631] = 8'd 1; long_chirp_lut[2632] = 8'd 48; long_chirp_lut[2633] = 8'd144; long_chirp_lut[2634] = 8'd230; long_chirp_lut[2635] = 8'd253; long_chirp_lut[2636] = 8'd199; long_chirp_lut[2637] = 8'd101; long_chirp_lut[2638] = 8'd 20; long_chirp_lut[2639] = 8'd 4;
|
||||
long_chirp_lut[2640] = 8'd 64; long_chirp_lut[2641] = 8'd162; long_chirp_lut[2642] = 8'd240; long_chirp_lut[2643] = 8'd248; long_chirp_lut[2644] = 8'd183; long_chirp_lut[2645] = 8'd 84; long_chirp_lut[2646] = 8'd 12; long_chirp_lut[2647] = 8'd 9; long_chirp_lut[2648] = 8'd 79; long_chirp_lut[2649] = 8'd178; long_chirp_lut[2650] = 8'd246; long_chirp_lut[2651] = 8'd243; long_chirp_lut[2652] = 8'd169; long_chirp_lut[2653] = 8'd 71; long_chirp_lut[2654] = 8'd 6; long_chirp_lut[2655] = 8'd 15;
|
||||
long_chirp_lut[2656] = 8'd 92; long_chirp_lut[2657] = 8'd190; long_chirp_lut[2658] = 8'd250; long_chirp_lut[2659] = 8'd236; long_chirp_lut[2660] = 8'd157; long_chirp_lut[2661] = 8'd 60; long_chirp_lut[2662] = 8'd 3; long_chirp_lut[2663] = 8'd 22; long_chirp_lut[2664] = 8'd104; long_chirp_lut[2665] = 8'd200; long_chirp_lut[2666] = 8'd253; long_chirp_lut[2667] = 8'd230; long_chirp_lut[2668] = 8'd146; long_chirp_lut[2669] = 8'd 51; long_chirp_lut[2670] = 8'd 2; long_chirp_lut[2671] = 8'd 27;
|
||||
long_chirp_lut[2672] = 8'd113; long_chirp_lut[2673] = 8'd207; long_chirp_lut[2674] = 8'd254; long_chirp_lut[2675] = 8'd225; long_chirp_lut[2676] = 8'd138; long_chirp_lut[2677] = 8'd 45; long_chirp_lut[2678] = 8'd 1; long_chirp_lut[2679] = 8'd 32; long_chirp_lut[2680] = 8'd120; long_chirp_lut[2681] = 8'd212; long_chirp_lut[2682] = 8'd254; long_chirp_lut[2683] = 8'd221; long_chirp_lut[2684] = 8'd132; long_chirp_lut[2685] = 8'd 41; long_chirp_lut[2686] = 8'd 1; long_chirp_lut[2687] = 8'd 36;
|
||||
long_chirp_lut[2688] = 8'd125; long_chirp_lut[2689] = 8'd216; long_chirp_lut[2690] = 8'd254; long_chirp_lut[2691] = 8'd218; long_chirp_lut[2692] = 8'd129; long_chirp_lut[2693] = 8'd 38; long_chirp_lut[2694] = 8'd 1; long_chirp_lut[2695] = 8'd 37; long_chirp_lut[2696] = 8'd127; long_chirp_lut[2697] = 8'd217; long_chirp_lut[2698] = 8'd254; long_chirp_lut[2699] = 8'd217; long_chirp_lut[2700] = 8'd128; long_chirp_lut[2701] = 8'd 38; long_chirp_lut[2702] = 8'd 1; long_chirp_lut[2703] = 8'd 38;
|
||||
long_chirp_lut[2704] = 8'd127; long_chirp_lut[2705] = 8'd217; long_chirp_lut[2706] = 8'd254; long_chirp_lut[2707] = 8'd218; long_chirp_lut[2708] = 8'd129; long_chirp_lut[2709] = 8'd 39; long_chirp_lut[2710] = 8'd 1; long_chirp_lut[2711] = 8'd 36; long_chirp_lut[2712] = 8'd125; long_chirp_lut[2713] = 8'd215; long_chirp_lut[2714] = 8'd254; long_chirp_lut[2715] = 8'd220; long_chirp_lut[2716] = 8'd132; long_chirp_lut[2717] = 8'd 42; long_chirp_lut[2718] = 8'd 1; long_chirp_lut[2719] = 8'd 33;
|
||||
long_chirp_lut[2720] = 8'd120; long_chirp_lut[2721] = 8'd211; long_chirp_lut[2722] = 8'd254; long_chirp_lut[2723] = 8'd224; long_chirp_lut[2724] = 8'd138; long_chirp_lut[2725] = 8'd 46; long_chirp_lut[2726] = 8'd 1; long_chirp_lut[2727] = 8'd 29; long_chirp_lut[2728] = 8'd113; long_chirp_lut[2729] = 8'd206; long_chirp_lut[2730] = 8'd253; long_chirp_lut[2731] = 8'd229; long_chirp_lut[2732] = 8'd146; long_chirp_lut[2733] = 8'd 53; long_chirp_lut[2734] = 8'd 2; long_chirp_lut[2735] = 8'd 23;
|
||||
long_chirp_lut[2736] = 8'd104; long_chirp_lut[2737] = 8'd198; long_chirp_lut[2738] = 8'd252; long_chirp_lut[2739] = 8'd235; long_chirp_lut[2740] = 8'd157; long_chirp_lut[2741] = 8'd 62; long_chirp_lut[2742] = 8'd 5; long_chirp_lut[2743] = 8'd 17; long_chirp_lut[2744] = 8'd 92; long_chirp_lut[2745] = 8'd187; long_chirp_lut[2746] = 8'd249; long_chirp_lut[2747] = 8'd241; long_chirp_lut[2748] = 8'd169; long_chirp_lut[2749] = 8'd 74; long_chirp_lut[2750] = 8'd 9; long_chirp_lut[2751] = 8'd 11;
|
||||
long_chirp_lut[2752] = 8'd 79; long_chirp_lut[2753] = 8'd174; long_chirp_lut[2754] = 8'd243; long_chirp_lut[2755] = 8'd247; long_chirp_lut[2756] = 8'd183; long_chirp_lut[2757] = 8'd 88; long_chirp_lut[2758] = 8'd 15; long_chirp_lut[2759] = 8'd 5; long_chirp_lut[2760] = 8'd 64; long_chirp_lut[2761] = 8'd158; long_chirp_lut[2762] = 8'd235; long_chirp_lut[2763] = 8'd252; long_chirp_lut[2764] = 8'd199; long_chirp_lut[2765] = 8'd106; long_chirp_lut[2766] = 8'd 25; long_chirp_lut[2767] = 8'd 2;
|
||||
long_chirp_lut[2768] = 8'd 48; long_chirp_lut[2769] = 8'd139; long_chirp_lut[2770] = 8'd224; long_chirp_lut[2771] = 8'd254; long_chirp_lut[2772] = 8'd214; long_chirp_lut[2773] = 8'd126; long_chirp_lut[2774] = 8'd 39; long_chirp_lut[2775] = 8'd 1; long_chirp_lut[2776] = 8'd 33; long_chirp_lut[2777] = 8'd118; long_chirp_lut[2778] = 8'd208; long_chirp_lut[2779] = 8'd254; long_chirp_lut[2780] = 8'd229; long_chirp_lut[2781] = 8'd149; long_chirp_lut[2782] = 8'd 57; long_chirp_lut[2783] = 8'd 3;
|
||||
long_chirp_lut[2784] = 8'd 19; long_chirp_lut[2785] = 8'd 94; long_chirp_lut[2786] = 8'd188; long_chirp_lut[2787] = 8'd248; long_chirp_lut[2788] = 8'd242; long_chirp_lut[2789] = 8'd173; long_chirp_lut[2790] = 8'd 79; long_chirp_lut[2791] = 8'd 11; long_chirp_lut[2792] = 8'd 8; long_chirp_lut[2793] = 8'd 70; long_chirp_lut[2794] = 8'd163; long_chirp_lut[2795] = 8'd237; long_chirp_lut[2796] = 8'd251; long_chirp_lut[2797] = 8'd197; long_chirp_lut[2798] = 8'd106; long_chirp_lut[2799] = 8'd 26;
|
||||
long_chirp_lut[2800] = 8'd 1; long_chirp_lut[2801] = 8'd 46; long_chirp_lut[2802] = 8'd135; long_chirp_lut[2803] = 8'd220; long_chirp_lut[2804] = 8'd254; long_chirp_lut[2805] = 8'd220; long_chirp_lut[2806] = 8'd136; long_chirp_lut[2807] = 8'd 47; long_chirp_lut[2808] = 8'd 2; long_chirp_lut[2809] = 8'd 25; long_chirp_lut[2810] = 8'd104; long_chirp_lut[2811] = 8'd195; long_chirp_lut[2812] = 8'd250; long_chirp_lut[2813] = 8'd239; long_chirp_lut[2814] = 8'd167; long_chirp_lut[2815] = 8'd 74;
|
||||
long_chirp_lut[2816] = 8'd 10; long_chirp_lut[2817] = 8'd 9; long_chirp_lut[2818] = 8'd 72; long_chirp_lut[2819] = 8'd165; long_chirp_lut[2820] = 8'd237; long_chirp_lut[2821] = 8'd251; long_chirp_lut[2822] = 8'd199; long_chirp_lut[2823] = 8'd108; long_chirp_lut[2824] = 8'd 28; long_chirp_lut[2825] = 8'd 1; long_chirp_lut[2826] = 8'd 42; long_chirp_lut[2827] = 8'd129; long_chirp_lut[2828] = 8'd215; long_chirp_lut[2829] = 8'd254; long_chirp_lut[2830] = 8'd226; long_chirp_lut[2831] = 8'd145;
|
||||
long_chirp_lut[2832] = 8'd 55; long_chirp_lut[2833] = 8'd 3; long_chirp_lut[2834] = 8'd 18; long_chirp_lut[2835] = 8'd 91; long_chirp_lut[2836] = 8'd183; long_chirp_lut[2837] = 8'd246; long_chirp_lut[2838] = 8'd246; long_chirp_lut[2839] = 8'd183; long_chirp_lut[2840] = 8'd 91; long_chirp_lut[2841] = 8'd 18; long_chirp_lut[2842] = 8'd 3; long_chirp_lut[2843] = 8'd 54; long_chirp_lut[2844] = 8'd143; long_chirp_lut[2845] = 8'd224; long_chirp_lut[2846] = 8'd254; long_chirp_lut[2847] = 8'd217;
|
||||
long_chirp_lut[2848] = 8'd133; long_chirp_lut[2849] = 8'd 46; long_chirp_lut[2850] = 8'd 2; long_chirp_lut[2851] = 8'd 23; long_chirp_lut[2852] = 8'd100; long_chirp_lut[2853] = 8'd191; long_chirp_lut[2854] = 8'd249; long_chirp_lut[2855] = 8'd243; long_chirp_lut[2856] = 8'd177; long_chirp_lut[2857] = 8'd 85; long_chirp_lut[2858] = 8'd 15; long_chirp_lut[2859] = 8'd 4; long_chirp_lut[2860] = 8'd 58; long_chirp_lut[2861] = 8'd147; long_chirp_lut[2862] = 8'd227; long_chirp_lut[2863] = 8'd254;
|
||||
long_chirp_lut[2864] = 8'd216; long_chirp_lut[2865] = 8'd132; long_chirp_lut[2866] = 8'd 45; long_chirp_lut[2867] = 8'd 2; long_chirp_lut[2868] = 8'd 23; long_chirp_lut[2869] = 8'd 99; long_chirp_lut[2870] = 8'd189; long_chirp_lut[2871] = 8'd248; long_chirp_lut[2872] = 8'd244; long_chirp_lut[2873] = 8'd180; long_chirp_lut[2874] = 8'd 89; long_chirp_lut[2875] = 8'd 18; long_chirp_lut[2876] = 8'd 3; long_chirp_lut[2877] = 8'd 53; long_chirp_lut[2878] = 8'd141; long_chirp_lut[2879] = 8'd222;
|
||||
long_chirp_lut[2880] = 8'd255; long_chirp_lut[2881] = 8'd222; long_chirp_lut[2882] = 8'd141; long_chirp_lut[2883] = 8'd 53; long_chirp_lut[2884] = 8'd 3; long_chirp_lut[2885] = 8'd 17; long_chirp_lut[2886] = 8'd 88; long_chirp_lut[2887] = 8'd178; long_chirp_lut[2888] = 8'd243; long_chirp_lut[2889] = 8'd249; long_chirp_lut[2890] = 8'd193; long_chirp_lut[2891] = 8'd103; long_chirp_lut[2892] = 8'd 26; long_chirp_lut[2893] = 8'd 1; long_chirp_lut[2894] = 8'd 40; long_chirp_lut[2895] = 8'd123;
|
||||
long_chirp_lut[2896] = 8'd209; long_chirp_lut[2897] = 8'd253; long_chirp_lut[2898] = 8'd234; long_chirp_lut[2899] = 8'd160; long_chirp_lut[2900] = 8'd 71; long_chirp_lut[2901] = 8'd 9; long_chirp_lut[2902] = 8'd 8; long_chirp_lut[2903] = 8'd 67; long_chirp_lut[2904] = 8'd157; long_chirp_lut[2905] = 8'd231; long_chirp_lut[2906] = 8'd254; long_chirp_lut[2907] = 8'd213; long_chirp_lut[2908] = 8'd129; long_chirp_lut[2909] = 8'd 44; long_chirp_lut[2910] = 8'd 2; long_chirp_lut[2911] = 8'd 22;
|
||||
long_chirp_lut[2912] = 8'd 96; long_chirp_lut[2913] = 8'd185; long_chirp_lut[2914] = 8'd246; long_chirp_lut[2915] = 8'd247; long_chirp_lut[2916] = 8'd189; long_chirp_lut[2917] = 8'd100; long_chirp_lut[2918] = 8'd 25; long_chirp_lut[2919] = 8'd 1; long_chirp_lut[2920] = 8'd 40; long_chirp_lut[2921] = 8'd123; long_chirp_lut[2922] = 8'd208; long_chirp_lut[2923] = 8'd253; long_chirp_lut[2924] = 8'd235; long_chirp_lut[2925] = 8'd164; long_chirp_lut[2926] = 8'd 75; long_chirp_lut[2927] = 8'd 12;
|
||||
long_chirp_lut[2928] = 8'd 6; long_chirp_lut[2929] = 8'd 60; long_chirp_lut[2930] = 8'd148; long_chirp_lut[2931] = 8'd225; long_chirp_lut[2932] = 8'd254; long_chirp_lut[2933] = 8'd221; long_chirp_lut[2934] = 8'd141; long_chirp_lut[2935] = 8'd 55; long_chirp_lut[2936] = 8'd 4; long_chirp_lut[2937] = 8'd 14; long_chirp_lut[2938] = 8'd 80; long_chirp_lut[2939] = 8'd169; long_chirp_lut[2940] = 8'd237; long_chirp_lut[2941] = 8'd252; long_chirp_lut[2942] = 8'd206; long_chirp_lut[2943] = 8'd121;
|
||||
long_chirp_lut[2944] = 8'd 39; long_chirp_lut[2945] = 8'd 1; long_chirp_lut[2946] = 8'd 24; long_chirp_lut[2947] = 8'd 98; long_chirp_lut[2948] = 8'd186; long_chirp_lut[2949] = 8'd246; long_chirp_lut[2950] = 8'd247; long_chirp_lut[2951] = 8'd191; long_chirp_lut[2952] = 8'd104; long_chirp_lut[2953] = 8'd 28; long_chirp_lut[2954] = 8'd 1; long_chirp_lut[2955] = 8'd 35; long_chirp_lut[2956] = 8'd114; long_chirp_lut[2957] = 8'd200; long_chirp_lut[2958] = 8'd250; long_chirp_lut[2959] = 8'd242;
|
||||
long_chirp_lut[2960] = 8'd178; long_chirp_lut[2961] = 8'd 90; long_chirp_lut[2962] = 8'd 20; long_chirp_lut[2963] = 8'd 2; long_chirp_lut[2964] = 8'd 45; long_chirp_lut[2965] = 8'd127; long_chirp_lut[2966] = 8'd210; long_chirp_lut[2967] = 8'd253; long_chirp_lut[2968] = 8'd236; long_chirp_lut[2969] = 8'd167; long_chirp_lut[2970] = 8'd 79; long_chirp_lut[2971] = 8'd 14; long_chirp_lut[2972] = 8'd 4; long_chirp_lut[2973] = 8'd 53; long_chirp_lut[2974] = 8'd137; long_chirp_lut[2975] = 8'd217;
|
||||
long_chirp_lut[2976] = 8'd254; long_chirp_lut[2977] = 8'd231; long_chirp_lut[2978] = 8'd158; long_chirp_lut[2979] = 8'd 71; long_chirp_lut[2980] = 8'd 11; long_chirp_lut[2981] = 8'd 6; long_chirp_lut[2982] = 8'd 59; long_chirp_lut[2983] = 8'd144; long_chirp_lut[2984] = 8'd222; long_chirp_lut[2985] = 8'd254; long_chirp_lut[2986] = 8'd227; long_chirp_lut[2987] = 8'd153; long_chirp_lut[2988] = 8'd 66; long_chirp_lut[2989] = 8'd 9; long_chirp_lut[2990] = 8'd 8; long_chirp_lut[2991] = 8'd 63;
|
||||
long_chirp_lut[2992] = 8'd148; long_chirp_lut[2993] = 8'd224; long_chirp_lut[2994] = 8'd254; long_chirp_lut[2995] = 8'd225; long_chirp_lut[2996] = 8'd150; long_chirp_lut[2997] = 8'd 64; long_chirp_lut[2998] = 8'd 8; long_chirp_lut[2999] = 8'd 8; long_chirp_lut[3000] = 8'd 64; long_chirp_lut[3001] = 8'd150; long_chirp_lut[3002] = 8'd225; long_chirp_lut[3003] = 8'd254; long_chirp_lut[3004] = 8'd225; long_chirp_lut[3005] = 8'd150; long_chirp_lut[3006] = 8'd 65; long_chirp_lut[3007] = 8'd 8;
|
||||
long_chirp_lut[3008] = 8'd 8; long_chirp_lut[3009] = 8'd 63; long_chirp_lut[3010] = 8'd148; long_chirp_lut[3011] = 8'd223; long_chirp_lut[3012] = 8'd254; long_chirp_lut[3013] = 8'd227; long_chirp_lut[3014] = 8'd153; long_chirp_lut[3015] = 8'd 68; long_chirp_lut[3016] = 8'd 10; long_chirp_lut[3017] = 8'd 6; long_chirp_lut[3018] = 8'd 59; long_chirp_lut[3019] = 8'd143; long_chirp_lut[3020] = 8'd220; long_chirp_lut[3021] = 8'd254; long_chirp_lut[3022] = 8'd230; long_chirp_lut[3023] = 8'd159;
|
||||
long_chirp_lut[3024] = 8'd 73; long_chirp_lut[3025] = 8'd 13; long_chirp_lut[3026] = 8'd 4; long_chirp_lut[3027] = 8'd 53; long_chirp_lut[3028] = 8'd135; long_chirp_lut[3029] = 8'd214; long_chirp_lut[3030] = 8'd253; long_chirp_lut[3031] = 8'd235; long_chirp_lut[3032] = 8'd168; long_chirp_lut[3033] = 8'd 82; long_chirp_lut[3034] = 8'd 17; long_chirp_lut[3035] = 8'd 2; long_chirp_lut[3036] = 8'd 45; long_chirp_lut[3037] = 8'd124; long_chirp_lut[3038] = 8'd206; long_chirp_lut[3039] = 8'd251;
|
||||
long_chirp_lut[3040] = 8'd241; long_chirp_lut[3041] = 8'd179; long_chirp_lut[3042] = 8'd 94; long_chirp_lut[3043] = 8'd 24; long_chirp_lut[3044] = 8'd 1; long_chirp_lut[3045] = 8'd 35; long_chirp_lut[3046] = 8'd111; long_chirp_lut[3047] = 8'd194; long_chirp_lut[3048] = 8'd247; long_chirp_lut[3049] = 8'd247; long_chirp_lut[3050] = 8'd193; long_chirp_lut[3051] = 8'd109; long_chirp_lut[3052] = 8'd 34; long_chirp_lut[3053] = 8'd 1; long_chirp_lut[3054] = 8'd 24; long_chirp_lut[3055] = 8'd 94;
|
||||
long_chirp_lut[3056] = 8'd179; long_chirp_lut[3057] = 8'd241; long_chirp_lut[3058] = 8'd252; long_chirp_lut[3059] = 8'd207; long_chirp_lut[3060] = 8'd128; long_chirp_lut[3061] = 8'd 48; long_chirp_lut[3062] = 8'd 3; long_chirp_lut[3063] = 8'd 14; long_chirp_lut[3064] = 8'd 76; long_chirp_lut[3065] = 8'd160; long_chirp_lut[3066] = 8'd230; long_chirp_lut[3067] = 8'd254; long_chirp_lut[3068] = 8'd223; long_chirp_lut[3069] = 8'd149; long_chirp_lut[3070] = 8'd 66; long_chirp_lut[3071] = 8'd 10;
|
||||
long_chirp_lut[3072] = 8'd 6; long_chirp_lut[3073] = 8'd 56; long_chirp_lut[3074] = 8'd137; long_chirp_lut[3075] = 8'd214; long_chirp_lut[3076] = 8'd253; long_chirp_lut[3077] = 8'd237; long_chirp_lut[3078] = 8'd172; long_chirp_lut[3079] = 8'd 88; long_chirp_lut[3080] = 8'd 21; long_chirp_lut[3081] = 8'd 1; long_chirp_lut[3082] = 8'd 36; long_chirp_lut[3083] = 8'd111; long_chirp_lut[3084] = 8'd193; long_chirp_lut[3085] = 8'd247; long_chirp_lut[3086] = 8'd248; long_chirp_lut[3087] = 8'd197;
|
||||
long_chirp_lut[3088] = 8'd115; long_chirp_lut[3089] = 8'd 39; long_chirp_lut[3090] = 8'd 2; long_chirp_lut[3091] = 8'd 19; long_chirp_lut[3092] = 8'd 83; long_chirp_lut[3093] = 8'd167; long_chirp_lut[3094] = 8'd233; long_chirp_lut[3095] = 8'd254; long_chirp_lut[3096] = 8'd220; long_chirp_lut[3097] = 8'd146; long_chirp_lut[3098] = 8'd 64; long_chirp_lut[3099] = 8'd 9; long_chirp_lut[3100] = 8'd 6; long_chirp_lut[3101] = 8'd 55; long_chirp_lut[3102] = 8'd135; long_chirp_lut[3103] = 8'd212;
|
||||
long_chirp_lut[3104] = 8'd253; long_chirp_lut[3105] = 8'd240; long_chirp_lut[3106] = 8'd178; long_chirp_lut[3107] = 8'd 96; long_chirp_lut[3108] = 8'd 26; long_chirp_lut[3109] = 8'd 1; long_chirp_lut[3110] = 8'd 29; long_chirp_lut[3111] = 8'd100; long_chirp_lut[3112] = 8'd182; long_chirp_lut[3113] = 8'd241; long_chirp_lut[3114] = 8'd252; long_chirp_lut[3115] = 8'd209; long_chirp_lut[3116] = 8'd132; long_chirp_lut[3117] = 8'd 53; long_chirp_lut[3118] = 8'd 5; long_chirp_lut[3119] = 8'd 10;
|
||||
long_chirp_lut[3120] = 8'd 64; long_chirp_lut[3121] = 8'd145; long_chirp_lut[3122] = 8'd219; long_chirp_lut[3123] = 8'd254; long_chirp_lut[3124] = 8'd235; long_chirp_lut[3125] = 8'd171; long_chirp_lut[3126] = 8'd 89; long_chirp_lut[3127] = 8'd 23; long_chirp_lut[3128] = 8'd 1; long_chirp_lut[3129] = 8'd 32; long_chirp_lut[3130] = 8'd104; long_chirp_lut[3131] = 8'd185; long_chirp_lut[3132] = 8'd242; long_chirp_lut[3133] = 8'd251; long_chirp_lut[3134] = 8'd209; long_chirp_lut[3135] = 8'd132;
|
||||
long_chirp_lut[3136] = 8'd 53; long_chirp_lut[3137] = 8'd 6; long_chirp_lut[3138] = 8'd 9; long_chirp_lut[3139] = 8'd 62; long_chirp_lut[3140] = 8'd142; long_chirp_lut[3141] = 8'd216; long_chirp_lut[3142] = 8'd253; long_chirp_lut[3143] = 8'd238; long_chirp_lut[3144] = 8'd177; long_chirp_lut[3145] = 8'd 95; long_chirp_lut[3146] = 8'd 27; long_chirp_lut[3147] = 8'd 1; long_chirp_lut[3148] = 8'd 27; long_chirp_lut[3149] = 8'd 95; long_chirp_lut[3150] = 8'd176; long_chirp_lut[3151] = 8'd237;
|
||||
long_chirp_lut[3152] = 8'd253; long_chirp_lut[3153] = 8'd217; long_chirp_lut[3154] = 8'd144; long_chirp_lut[3155] = 8'd 64; long_chirp_lut[3156] = 8'd 10; long_chirp_lut[3157] = 8'd 5; long_chirp_lut[3158] = 8'd 49; long_chirp_lut[3159] = 8'd126; long_chirp_lut[3160] = 8'd203; long_chirp_lut[3161] = 8'd250; long_chirp_lut[3162] = 8'd246; long_chirp_lut[3163] = 8'd194; long_chirp_lut[3164] = 8'd115; long_chirp_lut[3165] = 8'd 41; long_chirp_lut[3166] = 8'd 2; long_chirp_lut[3167] = 8'd 15;
|
||||
long_chirp_lut[3168] = 8'd 73; long_chirp_lut[3169] = 8'd154; long_chirp_lut[3170] = 8'd224; long_chirp_lut[3171] = 8'd254; long_chirp_lut[3172] = 8'd233; long_chirp_lut[3173] = 8'd170; long_chirp_lut[3174] = 8'd 89; long_chirp_lut[3175] = 8'd 24; long_chirp_lut[3176] = 8'd 1; long_chirp_lut[3177] = 8'd 29; long_chirp_lut[3178] = 8'd 97; long_chirp_lut[3179] = 8'd177; long_chirp_lut[3180] = 8'd237; long_chirp_lut[3181] = 8'd254; long_chirp_lut[3182] = 8'd219; long_chirp_lut[3183] = 8'd148;
|
||||
long_chirp_lut[3184] = 8'd 68; long_chirp_lut[3185] = 8'd 13; long_chirp_lut[3186] = 8'd 3; long_chirp_lut[3187] = 8'd 43; long_chirp_lut[3188] = 8'd117; long_chirp_lut[3189] = 8'd195; long_chirp_lut[3190] = 8'd246; long_chirp_lut[3191] = 8'd250; long_chirp_lut[3192] = 8'd204; long_chirp_lut[3193] = 8'd128; long_chirp_lut[3194] = 8'd 52; long_chirp_lut[3195] = 8'd 6; long_chirp_lut[3196] = 8'd 8; long_chirp_lut[3197] = 8'd 58; long_chirp_lut[3198] = 8'd135; long_chirp_lut[3199] = 8'd209;
|
||||
long_chirp_lut[3200] = 8'd251; long_chirp_lut[3201] = 8'd244; long_chirp_lut[3202] = 8'd191; long_chirp_lut[3203] = 8'd113; long_chirp_lut[3204] = 8'd 41; long_chirp_lut[3205] = 8'd 3; long_chirp_lut[3206] = 8'd 14; long_chirp_lut[3207] = 8'd 70; long_chirp_lut[3208] = 8'd148; long_chirp_lut[3209] = 8'd219; long_chirp_lut[3210] = 8'd253; long_chirp_lut[3211] = 8'd239; long_chirp_lut[3212] = 8'd180; long_chirp_lut[3213] = 8'd101; long_chirp_lut[3214] = 8'd 33; long_chirp_lut[3215] = 8'd 1;
|
||||
long_chirp_lut[3216] = 8'd 19; long_chirp_lut[3217] = 8'd 79; long_chirp_lut[3218] = 8'd158; long_chirp_lut[3219] = 8'd225; long_chirp_lut[3220] = 8'd254; long_chirp_lut[3221] = 8'd234; long_chirp_lut[3222] = 8'd172; long_chirp_lut[3223] = 8'd 93; long_chirp_lut[3224] = 8'd 28; long_chirp_lut[3225] = 8'd 1; long_chirp_lut[3226] = 8'd 23; long_chirp_lut[3227] = 8'd 85; long_chirp_lut[3228] = 8'd164; long_chirp_lut[3229] = 8'd229; long_chirp_lut[3230] = 8'd254; long_chirp_lut[3231] = 8'd231;
|
||||
long_chirp_lut[3232] = 8'd168; long_chirp_lut[3233] = 8'd 89; long_chirp_lut[3234] = 8'd 25; long_chirp_lut[3235] = 8'd 1; long_chirp_lut[3236] = 8'd 25; long_chirp_lut[3237] = 8'd 88; long_chirp_lut[3238] = 8'd167; long_chirp_lut[3239] = 8'd230; long_chirp_lut[3240] = 8'd255; long_chirp_lut[3241] = 8'd230; long_chirp_lut[3242] = 8'd167; long_chirp_lut[3243] = 8'd 88; long_chirp_lut[3244] = 8'd 25; long_chirp_lut[3245] = 8'd 1; long_chirp_lut[3246] = 8'd 24; long_chirp_lut[3247] = 8'd 87;
|
||||
long_chirp_lut[3248] = 8'd166; long_chirp_lut[3249] = 8'd229; long_chirp_lut[3250] = 8'd254; long_chirp_lut[3251] = 8'd232; long_chirp_lut[3252] = 8'd169; long_chirp_lut[3253] = 8'd 91; long_chirp_lut[3254] = 8'd 27; long_chirp_lut[3255] = 8'd 1; long_chirp_lut[3256] = 8'd 22; long_chirp_lut[3257] = 8'd 83; long_chirp_lut[3258] = 8'd161; long_chirp_lut[3259] = 8'd226; long_chirp_lut[3260] = 8'd254; long_chirp_lut[3261] = 8'd235; long_chirp_lut[3262] = 8'd175; long_chirp_lut[3263] = 8'd 98;
|
||||
long_chirp_lut[3264] = 8'd 31; long_chirp_lut[3265] = 8'd 1; long_chirp_lut[3266] = 8'd 18; long_chirp_lut[3267] = 8'd 76; long_chirp_lut[3268] = 8'd153; long_chirp_lut[3269] = 8'd220; long_chirp_lut[3270] = 8'd253; long_chirp_lut[3271] = 8'd240; long_chirp_lut[3272] = 8'd184; long_chirp_lut[3273] = 8'd108; long_chirp_lut[3274] = 8'd 39; long_chirp_lut[3275] = 8'd 3; long_chirp_lut[3276] = 8'd 13; long_chirp_lut[3277] = 8'd 65; long_chirp_lut[3278] = 8'd141; long_chirp_lut[3279] = 8'd211;
|
||||
long_chirp_lut[3280] = 8'd251; long_chirp_lut[3281] = 8'd245; long_chirp_lut[3282] = 8'd196; long_chirp_lut[3283] = 8'd122; long_chirp_lut[3284] = 8'd 50; long_chirp_lut[3285] = 8'd 6; long_chirp_lut[3286] = 8'd 7; long_chirp_lut[3287] = 8'd 52; long_chirp_lut[3288] = 8'd125; long_chirp_lut[3289] = 8'd199; long_chirp_lut[3290] = 8'd246; long_chirp_lut[3291] = 8'd251; long_chirp_lut[3292] = 8'd210; long_chirp_lut[3293] = 8'd139; long_chirp_lut[3294] = 8'd 65; long_chirp_lut[3295] = 8'd 13;
|
||||
long_chirp_lut[3296] = 8'd 2; long_chirp_lut[3297] = 8'd 38; long_chirp_lut[3298] = 8'd105; long_chirp_lut[3299] = 8'd181; long_chirp_lut[3300] = 8'd237; long_chirp_lut[3301] = 8'd254; long_chirp_lut[3302] = 8'd225; long_chirp_lut[3303] = 8'd161; long_chirp_lut[3304] = 8'd 84; long_chirp_lut[3305] = 8'd 24; long_chirp_lut[3306] = 8'd 1; long_chirp_lut[3307] = 8'd 23; long_chirp_lut[3308] = 8'd 83; long_chirp_lut[3309] = 8'd159; long_chirp_lut[3310] = 8'd224; long_chirp_lut[3311] = 8'd254;
|
||||
long_chirp_lut[3312] = 8'd239; long_chirp_lut[3313] = 8'd184; long_chirp_lut[3314] = 8'd109; long_chirp_lut[3315] = 8'd 41; long_chirp_lut[3316] = 8'd 3; long_chirp_lut[3317] = 8'd 10; long_chirp_lut[3318] = 8'd 59; long_chirp_lut[3319] = 8'd132; long_chirp_lut[3320] = 8'd203; long_chirp_lut[3321] = 8'd248; long_chirp_lut[3322] = 8'd250; long_chirp_lut[3323] = 8'd208; long_chirp_lut[3324] = 8'd138; long_chirp_lut[3325] = 8'd 64; long_chirp_lut[3326] = 8'd 13; long_chirp_lut[3327] = 8'd 2;
|
||||
long_chirp_lut[3328] = 8'd 35; long_chirp_lut[3329] = 8'd101; long_chirp_lut[3330] = 8'd176; long_chirp_lut[3331] = 8'd234; long_chirp_lut[3332] = 8'd254; long_chirp_lut[3333] = 8'd230; long_chirp_lut[3334] = 8'd170; long_chirp_lut[3335] = 8'd 95; long_chirp_lut[3336] = 8'd 31; long_chirp_lut[3337] = 8'd 1; long_chirp_lut[3338] = 8'd 15; long_chirp_lut[3339] = 8'd 69; long_chirp_lut[3340] = 8'd142; long_chirp_lut[3341] = 8'd211; long_chirp_lut[3342] = 8'd250; long_chirp_lut[3343] = 8'd247;
|
||||
long_chirp_lut[3344] = 8'd202; long_chirp_lut[3345] = 8'd132; long_chirp_lut[3346] = 8'd 60; long_chirp_lut[3347] = 8'd 11; long_chirp_lut[3348] = 8'd 3; long_chirp_lut[3349] = 8'd 38; long_chirp_lut[3350] = 8'd104; long_chirp_lut[3351] = 8'd178; long_chirp_lut[3352] = 8'd235; long_chirp_lut[3353] = 8'd254; long_chirp_lut[3354] = 8'd231; long_chirp_lut[3355] = 8'd171; long_chirp_lut[3356] = 8'd 97; long_chirp_lut[3357] = 8'd 33; long_chirp_lut[3358] = 8'd 2; long_chirp_lut[3359] = 8'd 13;
|
||||
long_chirp_lut[3360] = 8'd 64; long_chirp_lut[3361] = 8'd136; long_chirp_lut[3362] = 8'd206; long_chirp_lut[3363] = 8'd248; long_chirp_lut[3364] = 8'd250; long_chirp_lut[3365] = 8'd209; long_chirp_lut[3366] = 8'd141; long_chirp_lut[3367] = 8'd 69; long_chirp_lut[3368] = 8'd 16; long_chirp_lut[3369] = 8'd 1; long_chirp_lut[3370] = 8'd 29; long_chirp_lut[3371] = 8'd 90; long_chirp_lut[3372] = 8'd164; long_chirp_lut[3373] = 8'd226; long_chirp_lut[3374] = 8'd254; long_chirp_lut[3375] = 8'd240;
|
||||
long_chirp_lut[3376] = 8'd187; long_chirp_lut[3377] = 8'd115; long_chirp_lut[3378] = 8'd 47; long_chirp_lut[3379] = 8'd 6; long_chirp_lut[3380] = 8'd 6; long_chirp_lut[3381] = 8'd 46; long_chirp_lut[3382] = 8'd114; long_chirp_lut[3383] = 8'd186; long_chirp_lut[3384] = 8'd239; long_chirp_lut[3385] = 8'd254; long_chirp_lut[3386] = 8'd227; long_chirp_lut[3387] = 8'd167; long_chirp_lut[3388] = 8'd 94; long_chirp_lut[3389] = 8'd 32; long_chirp_lut[3390] = 8'd 2; long_chirp_lut[3391] = 8'd 13;
|
||||
long_chirp_lut[3392] = 8'd 63; long_chirp_lut[3393] = 8'd134; long_chirp_lut[3394] = 8'd203; long_chirp_lut[3395] = 8'd247; long_chirp_lut[3396] = 8'd251; long_chirp_lut[3397] = 8'd215; long_chirp_lut[3398] = 8'd150; long_chirp_lut[3399] = 8'd 77; long_chirp_lut[3400] = 8'd 21; long_chirp_lut[3401] = 8'd 1; long_chirp_lut[3402] = 8'd 21; long_chirp_lut[3403] = 8'd 77; long_chirp_lut[3404] = 8'd149; long_chirp_lut[3405] = 8'd214; long_chirp_lut[3406] = 8'd251; long_chirp_lut[3407] = 8'd247;
|
||||
long_chirp_lut[3408] = 8'd204; long_chirp_lut[3409] = 8'd136; long_chirp_lut[3410] = 8'd 66; long_chirp_lut[3411] = 8'd 15; long_chirp_lut[3412] = 8'd 1; long_chirp_lut[3413] = 8'd 28; long_chirp_lut[3414] = 8'd 88; long_chirp_lut[3415] = 8'd160; long_chirp_lut[3416] = 8'd222; long_chirp_lut[3417] = 8'd253; long_chirp_lut[3418] = 8'd244; long_chirp_lut[3419] = 8'd197; long_chirp_lut[3420] = 8'd128; long_chirp_lut[3421] = 8'd 58; long_chirp_lut[3422] = 8'd 12; long_chirp_lut[3423] = 8'd 2;
|
||||
long_chirp_lut[3424] = 8'd 33; long_chirp_lut[3425] = 8'd 94; long_chirp_lut[3426] = 8'd166; long_chirp_lut[3427] = 8'd226; long_chirp_lut[3428] = 8'd254; long_chirp_lut[3429] = 8'd241; long_chirp_lut[3430] = 8'd193; long_chirp_lut[3431] = 8'd123; long_chirp_lut[3432] = 8'd 55; long_chirp_lut[3433] = 8'd 10; long_chirp_lut[3434] = 8'd 3; long_chirp_lut[3435] = 8'd 35; long_chirp_lut[3436] = 8'd 96; long_chirp_lut[3437] = 8'd168; long_chirp_lut[3438] = 8'd227; long_chirp_lut[3439] = 8'd254;
|
||||
long_chirp_lut[3440] = 8'd241; long_chirp_lut[3441] = 8'd192; long_chirp_lut[3442] = 8'd123; long_chirp_lut[3443] = 8'd 55; long_chirp_lut[3444] = 8'd 10; long_chirp_lut[3445] = 8'd 2; long_chirp_lut[3446] = 8'd 34; long_chirp_lut[3447] = 8'd 94; long_chirp_lut[3448] = 8'd166; long_chirp_lut[3449] = 8'd225; long_chirp_lut[3450] = 8'd253; long_chirp_lut[3451] = 8'd243; long_chirp_lut[3452] = 8'd196; long_chirp_lut[3453] = 8'd128; long_chirp_lut[3454] = 8'd 60; long_chirp_lut[3455] = 8'd 13;
|
||||
long_chirp_lut[3456] = 8'd 2; long_chirp_lut[3457] = 8'd 30; long_chirp_lut[3458] = 8'd 88; long_chirp_lut[3459] = 8'd159; long_chirp_lut[3460] = 8'd220; long_chirp_lut[3461] = 8'd252; long_chirp_lut[3462] = 8'd246; long_chirp_lut[3463] = 8'd203; long_chirp_lut[3464] = 8'd137; long_chirp_lut[3465] = 8'd 68; long_chirp_lut[3466] = 8'd 17; long_chirp_lut[3467] = 8'd 1; long_chirp_lut[3468] = 8'd 23; long_chirp_lut[3469] = 8'd 78; long_chirp_lut[3470] = 8'd148; long_chirp_lut[3471] = 8'd211;
|
||||
long_chirp_lut[3472] = 8'd249; long_chirp_lut[3473] = 8'd250; long_chirp_lut[3474] = 8'd213; long_chirp_lut[3475] = 8'd150; long_chirp_lut[3476] = 8'd 80; long_chirp_lut[3477] = 8'd 25; long_chirp_lut[3478] = 8'd 1; long_chirp_lut[3479] = 8'd 15; long_chirp_lut[3480] = 8'd 64; long_chirp_lut[3481] = 8'd132; long_chirp_lut[3482] = 8'd198; long_chirp_lut[3483] = 8'd243; long_chirp_lut[3484] = 8'd253; long_chirp_lut[3485] = 8'd225; long_chirp_lut[3486] = 8'd167; long_chirp_lut[3487] = 8'd 98;
|
||||
long_chirp_lut[3488] = 8'd 37; long_chirp_lut[3489] = 8'd 4; long_chirp_lut[3490] = 8'd 8; long_chirp_lut[3491] = 8'd 48; long_chirp_lut[3492] = 8'd112; long_chirp_lut[3493] = 8'd180; long_chirp_lut[3494] = 8'd233; long_chirp_lut[3495] = 8'd254; long_chirp_lut[3496] = 8'd238; long_chirp_lut[3497] = 8'd188; long_chirp_lut[3498] = 8'd120; long_chirp_lut[3499] = 8'd 55; long_chirp_lut[3500] = 8'd 11; long_chirp_lut[3501] = 8'd 2; long_chirp_lut[3502] = 8'd 30; long_chirp_lut[3503] = 8'd 87;
|
||||
long_chirp_lut[3504] = 8'd157; long_chirp_lut[3505] = 8'd217; long_chirp_lut[3506] = 8'd251; long_chirp_lut[3507] = 8'd248; long_chirp_lut[3508] = 8'd210; long_chirp_lut[3509] = 8'd147; long_chirp_lut[3510] = 8'd 79; long_chirp_lut[3511] = 8'd 25; long_chirp_lut[3512] = 8'd 1; long_chirp_lut[3513] = 8'd 14; long_chirp_lut[3514] = 8'd 61; long_chirp_lut[3515] = 8'd127; long_chirp_lut[3516] = 8'd193; long_chirp_lut[3517] = 8'd240; long_chirp_lut[3518] = 8'd254; long_chirp_lut[3519] = 8'd231;
|
||||
long_chirp_lut[3520] = 8'd178; long_chirp_lut[3521] = 8'd110; long_chirp_lut[3522] = 8'd 47; long_chirp_lut[3523] = 8'd 8; long_chirp_lut[3524] = 8'd 3; long_chirp_lut[3525] = 8'd 35; long_chirp_lut[3526] = 8'd 93; long_chirp_lut[3527] = 8'd162; long_chirp_lut[3528] = 8'd220; long_chirp_lut[3529] = 8'd252; long_chirp_lut[3530] = 8'd247; long_chirp_lut[3531] = 8'd209; long_chirp_lut[3532] = 8'd146; long_chirp_lut[3533] = 8'd 79; long_chirp_lut[3534] = 8'd 25; long_chirp_lut[3535] = 8'd 1;
|
||||
long_chirp_lut[3536] = 8'd 13; long_chirp_lut[3537] = 8'd 58; long_chirp_lut[3538] = 8'd123; long_chirp_lut[3539] = 8'd189; long_chirp_lut[3540] = 8'd237; long_chirp_lut[3541] = 8'd254; long_chirp_lut[3542] = 8'd235; long_chirp_lut[3543] = 8'd185; long_chirp_lut[3544] = 8'd119; long_chirp_lut[3545] = 8'd 55; long_chirp_lut[3546] = 8'd 12; long_chirp_lut[3547] = 8'd 1; long_chirp_lut[3548] = 8'd 27; long_chirp_lut[3549] = 8'd 81; long_chirp_lut[3550] = 8'd148; long_chirp_lut[3551] = 8'd209;
|
||||
long_chirp_lut[3552] = 8'd247; long_chirp_lut[3553] = 8'd252; long_chirp_lut[3554] = 8'd221; long_chirp_lut[3555] = 8'd164; long_chirp_lut[3556] = 8'd 97; long_chirp_lut[3557] = 8'd 38; long_chirp_lut[3558] = 8'd 5; long_chirp_lut[3559] = 8'd 5; long_chirp_lut[3560] = 8'd 40; long_chirp_lut[3561] = 8'd100; long_chirp_lut[3562] = 8'd167; long_chirp_lut[3563] = 8'd223; long_chirp_lut[3564] = 8'd252; long_chirp_lut[3565] = 8'd247; long_chirp_lut[3566] = 8'd209; long_chirp_lut[3567] = 8'd148;
|
||||
long_chirp_lut[3568] = 8'd 81; long_chirp_lut[3569] = 8'd 27; long_chirp_lut[3570] = 8'd 2; long_chirp_lut[3571] = 8'd 11; long_chirp_lut[3572] = 8'd 52; long_chirp_lut[3573] = 8'd114; long_chirp_lut[3574] = 8'd180; long_chirp_lut[3575] = 8'd231; long_chirp_lut[3576] = 8'd254; long_chirp_lut[3577] = 8'd242; long_chirp_lut[3578] = 8'd199; long_chirp_lut[3579] = 8'd136; long_chirp_lut[3580] = 8'd 71; long_chirp_lut[3581] = 8'd 21; long_chirp_lut[3582] = 8'd 1; long_chirp_lut[3583] = 8'd 15;
|
||||
long_chirp_lut[3584] = 8'd 60; long_chirp_lut[3585] = 8'd123; long_chirp_lut[3586] = 8'd188; long_chirp_lut[3587] = 8'd236; long_chirp_lut[3588] = 8'd254; long_chirp_lut[3589] = 8'd239; long_chirp_lut[3590] = 8'd193; long_chirp_lut[3591] = 8'd129; long_chirp_lut[3592] = 8'd 65; long_chirp_lut[3593] = 8'd 18; long_chirp_lut[3594] = 8'd 1; long_chirp_lut[3595] = 8'd 17; long_chirp_lut[3596] = 8'd 64; long_chirp_lut[3597] = 8'd127; long_chirp_lut[3598] = 8'd191; long_chirp_lut[3599] = 8'd237;
|
||||
end
|
||||
|
||||
// Short PLFM chirp LUT (0.5us, 30MHz to 10MHz)
|
||||
initial begin
|
||||
short_chirp_lut[ 0] = 8'd255; short_chirp_lut[ 1] = 8'd129; short_chirp_lut[ 2] = 8'd 1; short_chirp_lut[ 3] = 8'd118; short_chirp_lut[ 4] = 8'd253; short_chirp_lut[ 5] = 8'd155; short_chirp_lut[ 6] = 8'd 7; short_chirp_lut[ 7] = 8'd 75;
|
||||
short_chirp_lut[ 8] = 8'd235; short_chirp_lut[ 9] = 8'd210; short_chirp_lut[10] = 8'd 46; short_chirp_lut[11] = 8'd 17; short_chirp_lut[12] = 8'd167; short_chirp_lut[13] = 8'd254; short_chirp_lut[14] = 8'd145; short_chirp_lut[15] = 8'd 10;
|
||||
short_chirp_lut[16] = 8'd 49; short_chirp_lut[17] = 8'd201; short_chirp_lut[18] = 8'd248; short_chirp_lut[19] = 8'd129; short_chirp_lut[20] = 8'd 8; short_chirp_lut[21] = 8'd 45; short_chirp_lut[22] = 8'd187; short_chirp_lut[23] = 8'd254;
|
||||
short_chirp_lut[24] = 8'd167; short_chirp_lut[25] = 8'd 34; short_chirp_lut[26] = 8'd 10; short_chirp_lut[27] = 8'd118; short_chirp_lut[28] = 8'd235; short_chirp_lut[29] = 8'd238; short_chirp_lut[30] = 8'd127; short_chirp_lut[31] = 8'd 18;
|
||||
short_chirp_lut[32] = 8'd 15; short_chirp_lut[33] = 8'd118; short_chirp_lut[34] = 8'd228; short_chirp_lut[35] = 8'd249; short_chirp_lut[36] = 8'd167; short_chirp_lut[37] = 8'd 54; short_chirp_lut[38] = 8'd 1; short_chirp_lut[39] = 8'd 45;
|
||||
short_chirp_lut[40] = 8'd150; short_chirp_lut[41] = 8'd237; short_chirp_lut[42] = 8'd248; short_chirp_lut[43] = 8'd180; short_chirp_lut[44] = 8'd 80; short_chirp_lut[45] = 8'd 10; short_chirp_lut[46] = 8'd 10; short_chirp_lut[47] = 8'd 75;
|
||||
short_chirp_lut[48] = 8'd167; short_chirp_lut[49] = 8'd237; short_chirp_lut[50] = 8'd253; short_chirp_lut[51] = 8'd210; short_chirp_lut[52] = 8'd132; short_chirp_lut[53] = 8'd 54; short_chirp_lut[54] = 8'd 7; short_chirp_lut[55] = 8'd 6;
|
||||
short_chirp_lut[56] = 8'd 49; short_chirp_lut[57] = 8'd118; short_chirp_lut[58] = 8'd187; short_chirp_lut[59] = 8'd237;
|
||||
end
|
||||
130
9_Firmware/9_2_FPGA/chirp_memory_loader_param.v
Normal file
130
9_Firmware/9_2_FPGA/chirp_memory_loader_param.v
Normal file
@@ -0,0 +1,130 @@
|
||||
`timescale 1ns / 1ps
|
||||
module chirp_memory_loader_param #(
|
||||
parameter LONG_I_FILE_SEG0 = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/long_chirp_seg0_i.mem",
|
||||
parameter LONG_Q_FILE_SEG0 = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/long_chirp_seg0_q.mem",
|
||||
parameter LONG_I_FILE_SEG1 = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/long_chirp_seg1_i.mem",
|
||||
parameter LONG_Q_FILE_SEG1 = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/long_chirp_seg1_q.mem",
|
||||
parameter LONG_I_FILE_SEG2 = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/long_chirp_seg2_i.mem",
|
||||
parameter LONG_Q_FILE_SEG2 = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/long_chirp_seg2_q.mem",
|
||||
parameter LONG_I_FILE_SEG3 = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/long_chirp_seg3_i.mem",
|
||||
parameter LONG_Q_FILE_SEG3 = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/long_chirp_seg3_q.mem",
|
||||
parameter SHORT_I_FILE = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/short_chirp_i.mem",
|
||||
parameter SHORT_Q_FILE = "C:/Users/dell/Desktop/ASUS/RADAR_V5/Firmware/FPGA/PLFM_RADAR_Xilinx_ISE_V2/Python/mem_files/fpga_mem_files/short_chirp_q.mem",
|
||||
parameter DEBUG = 1
|
||||
)(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire [1:0] segment_select,
|
||||
input wire mem_request,
|
||||
input wire use_long_chirp,
|
||||
input wire [9:0] sample_addr,
|
||||
output reg [15:0] ref_i,
|
||||
output reg [15:0] ref_q,
|
||||
output reg mem_ready
|
||||
);
|
||||
|
||||
// Memory declarations - now 4096 samples for 4 segments
|
||||
(* ram_style = "block" *) reg [15:0] long_chirp_i [0:4095];
|
||||
(* ram_style = "block" *) reg [15:0] long_chirp_q [0:4095];
|
||||
(* ram_style = "block" *) reg [15:0] short_chirp_i [0:1023];
|
||||
(* ram_style = "block" *) reg [15:0] short_chirp_q [0:1023];
|
||||
|
||||
// Initialize memory
|
||||
integer i;
|
||||
reg [799:0] debug_msg;
|
||||
|
||||
initial begin
|
||||
if (DEBUG) begin
|
||||
$display("[MEM] Starting memory initialization for 4 long chirp segments");
|
||||
end
|
||||
|
||||
// === LOAD LONG CHIRP - 4 SEGMENTS ===
|
||||
// Segment 0 (addresses 0-1023)
|
||||
$readmemh(LONG_I_FILE_SEG0, long_chirp_i, 0, 1023);
|
||||
$readmemh(LONG_Q_FILE_SEG0, long_chirp_q, 0, 1023);
|
||||
if (DEBUG) $display("[MEM] Loaded long chirp segment 0 (0-1023)");
|
||||
|
||||
// Segment 1 (addresses 1024-2047)
|
||||
$readmemh(LONG_I_FILE_SEG1, long_chirp_i, 1024, 2047);
|
||||
$readmemh(LONG_Q_FILE_SEG1, long_chirp_q, 1024, 2047);
|
||||
if (DEBUG) $display("[MEM] Loaded long chirp segment 1 (1024-2047)");
|
||||
|
||||
// Segment 2 (addresses 2048-3071)
|
||||
$readmemh(LONG_I_FILE_SEG2, long_chirp_i, 2048, 3071);
|
||||
$readmemh(LONG_Q_FILE_SEG2, long_chirp_q, 2048, 3071);
|
||||
if (DEBUG) $display("[MEM] Loaded long chirp segment 2 (2048-3071)");
|
||||
|
||||
// Segment 3 (addresses 3072-4095)
|
||||
$readmemh(LONG_I_FILE_SEG3, long_chirp_i, 3072, 4095);
|
||||
$readmemh(LONG_Q_FILE_SEG3, long_chirp_q, 3072, 4095);
|
||||
if (DEBUG) $display("[MEM] Loaded long chirp segment 3 (3072-4095)");
|
||||
|
||||
// === LOAD SHORT CHIRP ===
|
||||
// Load first 50 samples (0-49)
|
||||
$readmemh(SHORT_I_FILE, short_chirp_i);
|
||||
$readmemh(SHORT_Q_FILE, short_chirp_q);
|
||||
if (DEBUG) $display("[MEM] Loaded short chirp (0-49)");
|
||||
|
||||
// Zero pad remaining 974 samples (50-1023)
|
||||
for (i = 50; i < 1024; i = i + 1) begin
|
||||
short_chirp_i[i] = 16'h0000;
|
||||
short_chirp_q[i] = 16'h0000;
|
||||
end
|
||||
if (DEBUG) $display("[MEM] Zero-padded short chirp from 50-1023");
|
||||
|
||||
// === VERIFICATION ===
|
||||
if (DEBUG) begin
|
||||
$display("[MEM] Memory loading complete. Verification samples:");
|
||||
$display(" Long[0]: I=%h Q=%h", long_chirp_i[0], long_chirp_q[0]);
|
||||
$display(" Long[1023]: I=%h Q=%h", long_chirp_i[1023], long_chirp_q[1023]);
|
||||
$display(" Long[1024]: I=%h Q=%h", long_chirp_i[1024], long_chirp_q[1024]);
|
||||
$display(" Long[2047]: I=%h Q=%h", long_chirp_i[2047], long_chirp_q[2047]);
|
||||
$display(" Long[2048]: I=%h Q=%h", long_chirp_i[2048], long_chirp_q[2048]);
|
||||
$display(" Long[3071]: I=%h Q=%h", long_chirp_i[3071], long_chirp_q[3071]);
|
||||
$display(" Long[3072]: I=%h Q=%h", long_chirp_i[3072], long_chirp_q[3072]);
|
||||
$display(" Long[4095]: I=%h Q=%h", long_chirp_i[4095], long_chirp_q[4095]);
|
||||
$display(" Short[0]: I=%h Q=%h", short_chirp_i[0], short_chirp_q[0]);
|
||||
$display(" Short[49]: I=%h Q=%h", short_chirp_i[49], short_chirp_q[49]);
|
||||
$display(" Short[50]: I=%h Q=%h (zero-padded)", short_chirp_i[50], short_chirp_q[50]);
|
||||
end
|
||||
end
|
||||
|
||||
// Memory access logic
|
||||
reg [11:0] long_addr;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
ref_i <= 16'd0;
|
||||
ref_q <= 16'd0;
|
||||
mem_ready <= 1'b0;
|
||||
end else begin
|
||||
if (mem_request) begin
|
||||
if (use_long_chirp) begin
|
||||
// Direct addressing for 4 segments
|
||||
long_addr = {segment_select, sample_addr}; // segment_select[1:0] + sample_addr[9:0]
|
||||
ref_i <= long_chirp_i[long_addr];
|
||||
ref_q <= long_chirp_q[long_addr];
|
||||
|
||||
if (DEBUG && $time < 100) begin
|
||||
$display("[MEM @%0t] Long chirp: seg=%b, addr=%d, I=%h, Q=%h",
|
||||
$time, segment_select, long_addr,
|
||||
long_chirp_i[long_addr], long_chirp_q[long_addr]);
|
||||
end
|
||||
end else begin
|
||||
// Short chirp (0-1023)
|
||||
ref_i <= short_chirp_i[sample_addr];
|
||||
ref_q <= short_chirp_q[sample_addr];
|
||||
|
||||
if (DEBUG && $time < 100) begin
|
||||
$display("[MEM @%0t] Short chirp: addr=%d, I=%h, Q=%h",
|
||||
$time, sample_addr, short_chirp_i[sample_addr], short_chirp_q[sample_addr]);
|
||||
end
|
||||
end
|
||||
mem_ready <= 1'b1;
|
||||
end else begin
|
||||
mem_ready <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
300
9_Firmware/9_2_FPGA/cic_decimator_4x_enhanced.v
Normal file
300
9_Firmware/9_2_FPGA/cic_decimator_4x_enhanced.v
Normal file
@@ -0,0 +1,300 @@
|
||||
module cic_decimator_4x_enhanced (
|
||||
input wire clk, // 400MHz input clock
|
||||
input wire reset_n,
|
||||
input wire signed [17:0] data_in, // 18-bit input
|
||||
input wire data_valid,
|
||||
output reg signed [17:0] data_out, // 18-bit output
|
||||
output reg data_out_valid, // Valid at 100MHz
|
||||
// Enhanced monitoring outputs
|
||||
output reg saturation_detected, // Latched saturation indicator
|
||||
output reg [7:0] max_value_monitor, // For gain control
|
||||
input wire reset_monitors // Clear saturation and max value
|
||||
);
|
||||
|
||||
parameter STAGES = 5;
|
||||
parameter DECIMATION = 4;
|
||||
parameter COMB_DELAY = 1;
|
||||
|
||||
// Increased bit width for 18-bit input with headroom
|
||||
reg signed [35:0] integrator [0:STAGES-1]; // 36-bit for better dynamic range
|
||||
reg signed [35:0] comb [0:STAGES-1];
|
||||
reg signed [35:0] comb_delay [0:STAGES-1][0:COMB_DELAY-1];
|
||||
|
||||
// Enhanced control and monitoring
|
||||
reg [1:0] decimation_counter;
|
||||
reg data_valid_delayed;
|
||||
reg data_valid_comb;
|
||||
reg [7:0] output_counter;
|
||||
reg [35:0] max_integrator_value;
|
||||
reg overflow_detected;
|
||||
reg overflow_latched; // Latched overflow indicator
|
||||
|
||||
// Diagnostic registers
|
||||
reg [7:0] saturation_event_count;
|
||||
reg [31:0] sample_count;
|
||||
|
||||
// Temporary signals for calculations
|
||||
reg signed [35:0] abs_integrator_value;
|
||||
reg signed [35:0] temp_scaled_output;
|
||||
reg signed [17:0] temp_output; // Temporary output for proper range checking
|
||||
|
||||
integer i, j;
|
||||
|
||||
// Initialize
|
||||
initial begin
|
||||
for (i = 0; i < STAGES; i = i + 1) begin
|
||||
integrator[i] = 0;
|
||||
comb[i] = 0;
|
||||
for (j = 0; j < COMB_DELAY; j = j + 1) begin
|
||||
comb_delay[i][j] = 0;
|
||||
end
|
||||
end
|
||||
decimation_counter = 0;
|
||||
data_valid_delayed = 0;
|
||||
data_valid_comb = 0;
|
||||
output_counter = 0;
|
||||
max_integrator_value = 0;
|
||||
overflow_detected = 0;
|
||||
overflow_latched = 0;
|
||||
saturation_detected = 0;
|
||||
saturation_event_count = 0;
|
||||
sample_count = 0;
|
||||
max_value_monitor = 0;
|
||||
data_out = 0;
|
||||
data_out_valid = 0;
|
||||
abs_integrator_value = 0;
|
||||
temp_scaled_output = 0;
|
||||
temp_output = 0;
|
||||
end
|
||||
|
||||
// Enhanced integrator section with proper saturation monitoring
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
for (i = 0; i < STAGES; i = i + 1) begin
|
||||
integrator[i] <= 0;
|
||||
end
|
||||
decimation_counter <= 0;
|
||||
data_valid_delayed <= 0;
|
||||
data_valid_comb <= 0;
|
||||
max_integrator_value <= 0;
|
||||
overflow_detected <= 0;
|
||||
sample_count <= 0;
|
||||
abs_integrator_value <= 0;
|
||||
|
||||
if (reset_monitors) begin
|
||||
overflow_latched <= 0;
|
||||
saturation_detected <= 0;
|
||||
saturation_event_count <= 0;
|
||||
max_value_monitor <= 0;
|
||||
end
|
||||
end else if (data_valid) begin
|
||||
sample_count <= sample_count + 1;
|
||||
|
||||
// First integrator stage with enhanced saturation detection
|
||||
if (integrator[0] + $signed({{18{data_in[17]}}, data_in}) > (2**35 - 1)) begin
|
||||
integrator[0] <= (2**35 - 1);
|
||||
overflow_detected <= 1'b1;
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
saturation_event_count <= saturation_event_count + 1;
|
||||
$display("CIC_SATURATION: Positive overflow at sample %0d", sample_count);
|
||||
end else if (integrator[0] + $signed({{18{data_in[17]}}, data_in}) < -(2**35)) begin
|
||||
integrator[0] <= -(2**35);
|
||||
overflow_detected <= 1'b1;
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
saturation_event_count <= saturation_event_count + 1;
|
||||
$display("CIC_SATURATION: Negative overflow at sample %0d", sample_count);
|
||||
end else begin
|
||||
integrator[0] <= integrator[0] + $signed({{18{data_in[17]}}, data_in});
|
||||
overflow_detected <= 1'b0; // Only clear immediate detection, not latched
|
||||
end
|
||||
|
||||
// Calculate absolute value for monitoring
|
||||
abs_integrator_value <= (integrator[0][35]) ? -integrator[0] : integrator[0];
|
||||
|
||||
// Track maximum integrator value for gain monitoring (absolute value)
|
||||
if (abs_integrator_value > max_integrator_value) begin
|
||||
max_integrator_value <= abs_integrator_value;
|
||||
max_value_monitor <= abs_integrator_value[31:24]; // Fixed: use the calculated absolute value
|
||||
end
|
||||
|
||||
// Remaining integrator stages with saturation protection
|
||||
for (i = 1; i < STAGES; i = i + 1) begin
|
||||
if (integrator[i] + integrator[i-1] > (2**35 - 1)) begin
|
||||
integrator[i] <= (2**35 - 1);
|
||||
overflow_detected <= 1'b1;
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
end else if (integrator[i] + integrator[i-1] < -(2**35)) begin
|
||||
integrator[i] <= -(2**35);
|
||||
overflow_detected <= 1'b1;
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
end else begin
|
||||
integrator[i] <= integrator[i] + integrator[i-1];
|
||||
end
|
||||
end
|
||||
|
||||
// Enhanced decimation control
|
||||
if (decimation_counter == DECIMATION - 1) begin
|
||||
decimation_counter <= 0;
|
||||
data_valid_delayed <= 1;
|
||||
output_counter <= output_counter + 1;
|
||||
|
||||
/*// Debug output for first few samples
|
||||
if (output_counter < 10) begin
|
||||
$display("CIC_DECIM: sample=%0d, integrator[%0d]=%h, max_val=%h, sat=%b",
|
||||
output_counter, STAGES-1, integrator[STAGES-1],
|
||||
max_integrator_value, saturation_detected);
|
||||
end
|
||||
*/
|
||||
end else begin
|
||||
decimation_counter <= decimation_counter + 1;
|
||||
data_valid_delayed <= 0;
|
||||
end
|
||||
end else begin
|
||||
data_valid_delayed <= 0;
|
||||
overflow_detected <= 1'b0; // Clear immediate detection when no data
|
||||
end
|
||||
|
||||
// Monitor control - clear latched saturation on reset_monitors
|
||||
if (reset_monitors) begin
|
||||
overflow_latched <= 0;
|
||||
saturation_detected <= 0;
|
||||
max_integrator_value <= 0;
|
||||
max_value_monitor <= 0;
|
||||
saturation_event_count <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// Pipeline the valid signal for comb section
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
data_valid_comb <= 0;
|
||||
end else begin
|
||||
data_valid_comb <= data_valid_delayed;
|
||||
end
|
||||
end
|
||||
|
||||
// Enhanced comb section with FIXED scaling and saturation monitoring
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
for (i = 0; i < STAGES; i = i + 1) begin
|
||||
comb[i] <= 0;
|
||||
for (j = 0; j < COMB_DELAY; j = j + 1) begin
|
||||
comb_delay[i][j] <= 0;
|
||||
end
|
||||
end
|
||||
data_out <= 0;
|
||||
data_out_valid <= 0;
|
||||
temp_scaled_output <= 0;
|
||||
temp_output <= 0;
|
||||
end else if (data_valid_comb) begin
|
||||
// Enhanced comb processing with saturation check
|
||||
for (i = 0; i < STAGES; i = i + 1) begin
|
||||
if (i == 0) begin
|
||||
// Check for comb stage saturation
|
||||
if (integrator[STAGES-1] - comb_delay[0][COMB_DELAY-1] > (2**35 - 1)) begin
|
||||
comb[0] <= (2**35 - 1);
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
end else if (integrator[STAGES-1] - comb_delay[0][COMB_DELAY-1] < -(2**35)) begin
|
||||
comb[0] <= -(2**35);
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
end else begin
|
||||
comb[0] <= integrator[STAGES-1] - comb_delay[0][COMB_DELAY-1];
|
||||
end
|
||||
|
||||
// Update delay line for first stage
|
||||
for (j = COMB_DELAY-1; j > 0; j = j - 1) begin
|
||||
comb_delay[0][j] <= comb_delay[0][j-1];
|
||||
end
|
||||
comb_delay[0][0] <= integrator[STAGES-1];
|
||||
end else begin
|
||||
// Check for comb stage saturation
|
||||
if (comb[i-1] - comb_delay[i][COMB_DELAY-1] > (2**35 - 1)) begin
|
||||
comb[i] <= (2**35 - 1);
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
end else if (comb[i-1] - comb_delay[i][COMB_DELAY-1] < -(2**35)) begin
|
||||
comb[i] <= -(2**35);
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
end else begin
|
||||
comb[i] <= comb[i-1] - comb_delay[i][COMB_DELAY-1];
|
||||
end
|
||||
|
||||
// Update delay line
|
||||
for (j = COMB_DELAY-1; j > 0; j = j - 1) begin
|
||||
comb_delay[i][j] <= comb_delay[i][j-1];
|
||||
end
|
||||
comb_delay[i][0] <= comb[i-1];
|
||||
end
|
||||
end
|
||||
|
||||
// FIXED: Use proper scaling for 5 stages and decimation by 4
|
||||
// Gain = (4^5) = 1024 = 2^10, so scale by 2^10 to normalize
|
||||
temp_scaled_output <= comb[STAGES-1] >>> 10;
|
||||
|
||||
// FIXED: Extract 18-bit output properly
|
||||
temp_output <= temp_scaled_output[17:0];
|
||||
|
||||
// FIXED: Proper saturation detection for 18-bit signed range
|
||||
// Check if the 18-bit truncated value matches the intended value
|
||||
if (temp_scaled_output > 131071) begin // 2^17 - 1
|
||||
data_out <= 131071;
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
saturation_event_count <= saturation_event_count + 1;
|
||||
$display("CIC_OUTPUT_SAT: TRUE Positive saturation, raw=%h, scaled=%h, temp_out=%d, final_out=%d",
|
||||
comb[STAGES-1], temp_scaled_output, temp_output, 131071);
|
||||
end else if (temp_scaled_output < -131072) begin // -2^17
|
||||
data_out <= -131072;
|
||||
overflow_latched <= 1'b1;
|
||||
saturation_detected <= 1'b1;
|
||||
saturation_event_count <= saturation_event_count + 1;
|
||||
$display("CIC_OUTPUT_SAT: TRUE Negative saturation, raw=%h, scaled=%h, temp_out=%d, final_out=%d",
|
||||
comb[STAGES-1], temp_scaled_output, temp_output, -131072);
|
||||
end else begin
|
||||
// FIXED: Use the properly truncated 18-bit value
|
||||
data_out <= temp_output;
|
||||
overflow_latched <= 1'b0;
|
||||
saturation_detected <= 1'b0;
|
||||
if (output_counter < 20) begin
|
||||
//$display("CIC_OUTPUT_GOOD: raw=%h, scaled=%h, temp_out=%d, final_out=%d",
|
||||
// comb[STAGES-1], temp_scaled_output, temp_output, data_out);
|
||||
end
|
||||
end
|
||||
|
||||
data_out_valid <= 1;
|
||||
|
||||
// Debug output for first samples
|
||||
if (output_counter < 10) begin
|
||||
// $display("CIC_DEBUG: sample=%0d, raw=%h, scaled=%h, out=%d, sat=%b",
|
||||
// output_counter, comb[STAGES-1], temp_scaled_output, data_out, saturation_detected);
|
||||
end
|
||||
end else begin
|
||||
data_out_valid <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// Continuous monitoring of saturation status
|
||||
always @(posedge clk) begin
|
||||
if (overflow_detected && sample_count < 100) begin
|
||||
$display("CIC_OVERFLOW: Immediate detection at sample %0d", sample_count);
|
||||
end
|
||||
end
|
||||
|
||||
// Clear saturation on external reset
|
||||
always @(posedge reset_monitors) begin
|
||||
if (reset_monitors) begin
|
||||
overflow_latched <= 0;
|
||||
saturation_detected <= 0;
|
||||
saturation_event_count <= 0;
|
||||
//$display("CIC_MONITORS: All monitors reset");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
26
9_Firmware/9_2_FPGA/dac_interface_single.v
Normal file
26
9_Firmware/9_2_FPGA/dac_interface_single.v
Normal file
@@ -0,0 +1,26 @@
|
||||
module dac_interface_enhanced (
|
||||
input wire clk_120m,
|
||||
input wire reset_n,
|
||||
input wire [7:0] chirp_data,
|
||||
input wire chirp_valid,
|
||||
output reg [7:0] dac_data,
|
||||
output wire dac_clk,
|
||||
output wire dac_sleep
|
||||
);
|
||||
|
||||
// Register DAC data to meet timing
|
||||
always @(posedge clk_120m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
dac_data <= 8'd128; // Center value
|
||||
end else if (chirp_valid) begin
|
||||
dac_data <= chirp_data;
|
||||
end else begin
|
||||
dac_data <= 8'd128; // Default to center when no chirp
|
||||
end
|
||||
end
|
||||
|
||||
// DAC clock is same as input clock (120MHz)
|
||||
assign dac_clk = clk_120m;
|
||||
assign dac_sleep = 1'b0;
|
||||
|
||||
endmodule
|
||||
425
9_Firmware/9_2_FPGA/ddc_400m.v
Normal file
425
9_Firmware/9_2_FPGA/ddc_400m.v
Normal file
@@ -0,0 +1,425 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module ddc_400m_enhanced (
|
||||
input wire clk_400m, // 400MHz clock from ADC DCO
|
||||
input wire clk_100m, // 100MHz system clock
|
||||
input wire reset_n,
|
||||
input wire mixers_enable,
|
||||
input wire [7:0] adc_data, // ADC data at 400MHz
|
||||
input wire adc_data_valid_i, // Valid at 400MHz
|
||||
input wire adc_data_valid_q,
|
||||
output wire signed [17:0] baseband_i,
|
||||
output wire signed [17:0] baseband_q,
|
||||
output wire baseband_valid_i,
|
||||
output wire baseband_valid_q,
|
||||
|
||||
output wire [1:0] ddc_status,
|
||||
// Enhanced interfaces
|
||||
output wire [7:0] ddc_diagnostics,
|
||||
output wire mixer_saturation,
|
||||
output wire filter_overflow,
|
||||
input wire bypass_mode, // Test mode
|
||||
|
||||
input wire [1:0] test_mode,
|
||||
input wire [15:0] test_phase_inc,
|
||||
input wire force_saturation,
|
||||
input wire reset_monitors,
|
||||
output wire [31:0] debug_sample_count,
|
||||
output wire [17:0] debug_internal_i,
|
||||
output wire [17:0] debug_internal_q
|
||||
);
|
||||
|
||||
// Parameters for numerical precision
|
||||
parameter ADC_WIDTH = 8;
|
||||
parameter NCO_WIDTH = 16;
|
||||
parameter MIXER_WIDTH = 18;
|
||||
parameter OUTPUT_WIDTH = 18;
|
||||
|
||||
// IF frequency parameters
|
||||
parameter IF_FREQ = 120000000;
|
||||
parameter FS = 400000000;
|
||||
parameter PHASE_WIDTH = 32;
|
||||
|
||||
// Internal signals
|
||||
wire signed [15:0] sin_out, cos_out;
|
||||
wire nco_ready;
|
||||
wire cic_valid;
|
||||
wire fir_valid;
|
||||
wire [17:0] cic_i_out, cic_q_out;
|
||||
wire signed [17:0] fir_i_out, fir_q_out;
|
||||
|
||||
|
||||
// Diagnostic registers
|
||||
reg [2:0] saturation_count;
|
||||
reg overflow_detected;
|
||||
reg [7:0] error_counter;
|
||||
|
||||
// CDC synchronization for control signals
|
||||
reg mixers_enable_sync;
|
||||
reg bypass_mode_sync;
|
||||
|
||||
// Debug monitoring signals
|
||||
reg [31:0] sample_counter;
|
||||
wire signed [17:0] debug_mixed_i_trunc;
|
||||
wire signed [17:0] debug_mixed_q_trunc;
|
||||
|
||||
// Real-time status monitoring
|
||||
reg [7:0] signal_power_i, signal_power_q;
|
||||
|
||||
// Enhanced saturation injection for testing
|
||||
reg force_saturation_sync;
|
||||
|
||||
// Internal mixing signals
|
||||
reg signed [MIXER_WIDTH-1:0] adc_signed;
|
||||
reg signed [MIXER_WIDTH + NCO_WIDTH -1:0] mixed_i, mixed_q;
|
||||
reg mixed_valid;
|
||||
reg mixer_overflow_i, mixer_overflow_q;
|
||||
|
||||
// Output stage registers
|
||||
reg signed [17:0] baseband_i_reg, baseband_q_reg;
|
||||
reg baseband_valid_reg;
|
||||
|
||||
// ============================================================================
|
||||
// Phase Dithering Signals
|
||||
// ============================================================================
|
||||
wire [7:0] phase_dither_bits;
|
||||
wire [31:0] phase_inc_dithered;
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Debug Signal Assignments
|
||||
// ============================================================================
|
||||
assign debug_internal_i = mixed_i[25:8];
|
||||
assign debug_internal_q = mixed_q[25:8];
|
||||
assign debug_sample_count = sample_counter;
|
||||
assign debug_mixed_i_trunc = mixed_i[25:8];
|
||||
assign debug_mixed_q_trunc = mixed_q[25:8];
|
||||
|
||||
// ============================================================================
|
||||
// Clock Domain Crossing for Control Signals
|
||||
// ============================================================================
|
||||
always @(posedge clk_400m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
mixers_enable_sync <= 1'b0;
|
||||
bypass_mode_sync <= 1'b0;
|
||||
force_saturation_sync <= 1'b0;
|
||||
end else begin
|
||||
mixers_enable_sync <= mixers_enable;
|
||||
bypass_mode_sync <= bypass_mode;
|
||||
force_saturation_sync <= force_saturation;
|
||||
end
|
||||
end
|
||||
|
||||
// ============================================================================
|
||||
// Sample Counter and Debug Monitoring
|
||||
// ============================================================================
|
||||
always @(posedge clk_400m or negedge reset_n) begin
|
||||
if (!reset_n || reset_monitors) begin
|
||||
sample_counter <= 0;
|
||||
saturation_count <= 0;
|
||||
error_counter <= 0;
|
||||
end else if (adc_data_valid_i && adc_data_valid_q ) begin
|
||||
sample_counter <= sample_counter + 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Enhanced Phase Dithering Instance
|
||||
// ============================================================================
|
||||
lfsr_dither_enhanced #(
|
||||
.DITHER_WIDTH(8)
|
||||
) phase_dither_gen (
|
||||
.clk(clk_400m),
|
||||
.reset_n(reset_n),
|
||||
.enable(nco_ready),
|
||||
.dither_out(phase_dither_bits)
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
// Phase Increment Calculation with Dithering
|
||||
// ============================================================================
|
||||
// Calculate phase increment for 120MHz IF at 400MHz sampling
|
||||
localparam PHASE_INC_120MHZ = 32'h4CCCCCCD;
|
||||
|
||||
// Apply dithering to reduce spurious tones
|
||||
assign phase_inc_dithered = PHASE_INC_120MHZ + {24'b0, phase_dither_bits};
|
||||
|
||||
// ============================================================================
|
||||
// Enhanced NCO with Diagnostics
|
||||
// ============================================================================
|
||||
nco_400m_enhanced nco_core (
|
||||
.clk_400m(clk_400m),
|
||||
.reset_n(reset_n),
|
||||
.frequency_tuning_word(phase_inc_dithered),
|
||||
.phase_valid(mixers_enable),
|
||||
.phase_offset(16'h0000),
|
||||
.sin_out(sin_out),
|
||||
.cos_out(cos_out),
|
||||
.dds_ready(nco_ready)
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
// Enhanced Mixing Stage with AGC
|
||||
// ============================================================================
|
||||
always @(posedge clk_400m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
adc_signed <= 0;
|
||||
mixed_i <= 0;
|
||||
mixed_q <= 0;
|
||||
mixed_valid <= 0;
|
||||
mixer_overflow_i <= 0;
|
||||
mixer_overflow_q <= 0;
|
||||
saturation_count <= 0;
|
||||
overflow_detected <= 0;
|
||||
end else if (nco_ready && adc_data_valid_i && adc_data_valid_q) begin
|
||||
// Convert ADC data to signed with extended precision
|
||||
adc_signed <= {1'b0, adc_data, {(MIXER_WIDTH-ADC_WIDTH-1){1'b0}}} -
|
||||
{1'b0, {ADC_WIDTH{1'b1}}, {(MIXER_WIDTH-ADC_WIDTH-1){1'b0}}} / 2;
|
||||
|
||||
// Force saturation for testing
|
||||
if (force_saturation_sync) begin
|
||||
mixed_i <= 34'h1FFFFFFFF; // Force positive saturation
|
||||
mixed_q <= 34'h200000000; // Force negative saturation
|
||||
mixer_overflow_i <= 1'b1;
|
||||
mixer_overflow_q <= 1'b1;
|
||||
end else begin
|
||||
|
||||
// Normal mixing
|
||||
mixed_i <= $signed(adc_signed) * $signed(cos_out);
|
||||
mixed_q <= $signed(adc_signed) * $signed(sin_out);
|
||||
|
||||
|
||||
// Enhanced overflow detection with counting
|
||||
mixer_overflow_i <= (mixed_i > (2**(MIXER_WIDTH+NCO_WIDTH-2)-1)) ||
|
||||
(mixed_i < -(2**(MIXER_WIDTH+NCO_WIDTH-2)));
|
||||
mixer_overflow_q <= (mixed_q > (2**(MIXER_WIDTH+NCO_WIDTH-2)-1)) ||
|
||||
(mixed_q < -(2**(MIXER_WIDTH+NCO_WIDTH-2)));
|
||||
end
|
||||
|
||||
mixed_valid <= 1;
|
||||
|
||||
if (mixer_overflow_i || mixer_overflow_q) begin
|
||||
saturation_count <= saturation_count + 1;
|
||||
overflow_detected <= 1'b1;
|
||||
end else begin
|
||||
overflow_detected <= 1'b0;
|
||||
end
|
||||
|
||||
end else begin
|
||||
mixed_valid <= 0;
|
||||
mixer_overflow_i <= 0;
|
||||
mixer_overflow_q <= 0;
|
||||
overflow_detected <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// ============================================================================
|
||||
// Enhanced CIC Decimators
|
||||
// ============================================================================
|
||||
wire cic_valid_i, cic_valid_q;
|
||||
|
||||
cic_decimator_4x_enhanced cic_i_inst (
|
||||
.clk(clk_400m),
|
||||
.reset_n(reset_n),
|
||||
.data_in(mixed_i[33:16]),
|
||||
.data_valid(mixed_valid),
|
||||
.data_out(cic_i_out),
|
||||
.data_out_valid(cic_valid_i)
|
||||
);
|
||||
|
||||
cic_decimator_4x_enhanced cic_q_inst (
|
||||
.clk(clk_400m),
|
||||
.reset_n(reset_n),
|
||||
.data_in(mixed_q[33:16]),
|
||||
.data_valid(mixed_valid),
|
||||
.data_out(cic_q_out),
|
||||
.data_out_valid(cic_valid_q)
|
||||
);
|
||||
|
||||
assign cic_valid = cic_valid_i & cic_valid_q;
|
||||
|
||||
cdc_adc_to_processing #(
|
||||
.WIDTH(18),
|
||||
.STAGES(3)
|
||||
)CDC_FIR_i(
|
||||
.src_clk(clk_400m),
|
||||
.dst_clk(clk_100m),
|
||||
.reset_n(reset_n),
|
||||
.src_data(cic_i_out),
|
||||
.src_valid(cic_valid_i),
|
||||
.dst_data(fir_d_in_i),
|
||||
.dst_valid(fir_in_valid_i)
|
||||
);
|
||||
|
||||
cdc_adc_to_processing #(
|
||||
.WIDTH(18),
|
||||
.STAGES(3)
|
||||
)CDC_FIR_q(
|
||||
.src_clk(clk_400m),
|
||||
.dst_clk(clk_100m),
|
||||
.reset_n(reset_n),
|
||||
.src_data(cic_q_out),
|
||||
.src_valid(cic_valid_q),
|
||||
.dst_data(fir_d_in_q),
|
||||
.dst_valid(fir_in_valid_q)
|
||||
);
|
||||
|
||||
// ============================================================================
|
||||
// Enhanced FIR Filters with FIXED valid signal handling
|
||||
// ============================================================================
|
||||
wire fir_in_valid_i, fir_in_valid_q;
|
||||
wire fir_valid_i, fir_valid_q;
|
||||
wire fir_i_ready, fir_q_ready;
|
||||
wire [17:0] fir_d_in_i, fir_d_in_q;
|
||||
|
||||
// FIR I channel
|
||||
fir_lowpass_parallel_enhanced fir_i_inst (
|
||||
.clk(clk_100m),
|
||||
.reset_n(reset_n),
|
||||
.data_in(fir_d_in_i), // Use synchronized data
|
||||
.data_valid(fir_in_valid_i), // Use synchronized valid
|
||||
.data_out(fir_i_out),
|
||||
.data_out_valid(fir_valid_i),
|
||||
.fir_ready(fir_i_ready),
|
||||
.filter_overflow()
|
||||
);
|
||||
|
||||
// FIR Q channel
|
||||
fir_lowpass_parallel_enhanced fir_q_inst (
|
||||
.clk(clk_100m),
|
||||
.reset_n(reset_n),
|
||||
.data_in(fir_d_in_q), // Use synchronized data
|
||||
.data_valid(fir_in_valid_q), // Use synchronized valid
|
||||
.data_out(fir_q_out),
|
||||
.data_out_valid(fir_valid_q),
|
||||
.fir_ready(fir_q_ready),
|
||||
.filter_overflow()
|
||||
);
|
||||
|
||||
assign fir_valid = fir_valid_i & fir_valid_q;
|
||||
|
||||
// ============================================================================
|
||||
// Enhanced Output Stage
|
||||
// ============================================================================
|
||||
always @(negedge clk_100m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
baseband_i_reg <= 0;
|
||||
baseband_q_reg <= 0;
|
||||
baseband_valid_reg <= 0;
|
||||
end else if (fir_valid) begin
|
||||
baseband_i_reg <= fir_i_out;
|
||||
baseband_q_reg <= fir_q_out;
|
||||
baseband_valid_reg <= 1;
|
||||
end else begin
|
||||
baseband_valid_reg <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Output Assignments
|
||||
// ============================================================================
|
||||
assign baseband_i = baseband_i_reg;
|
||||
assign baseband_q = baseband_q_reg;
|
||||
assign baseband_valid_i = baseband_valid_reg;
|
||||
assign baseband_valid_q = baseband_valid_reg;
|
||||
assign ddc_status = {mixer_overflow_i | mixer_overflow_q, nco_ready};
|
||||
assign mixer_saturation = overflow_detected;
|
||||
assign ddc_diagnostics = {saturation_count, error_counter[4:0]};
|
||||
|
||||
// ============================================================================
|
||||
// Enhanced Debug and Monitoring
|
||||
// ============================================================================
|
||||
reg [31:0] debug_cic_count, debug_fir_count, debug_bb_count;
|
||||
|
||||
always @(posedge clk_100m) begin
|
||||
|
||||
if (fir_valid_i && debug_fir_count < 20) begin
|
||||
debug_fir_count <= debug_fir_count + 1;
|
||||
$display("FIR_OUTPUT: fir_i=%6d, fir_q=%6d", fir_i_out, fir_q_out);
|
||||
end
|
||||
|
||||
if (adc_data_valid_i && adc_data_valid_q && debug_bb_count < 20) begin
|
||||
debug_bb_count <= debug_bb_count + 1;
|
||||
$display("BASEBAND_OUT: i=%6d, q=%6d, count=%0d",
|
||||
baseband_i, baseband_q, debug_bb_count);
|
||||
end
|
||||
end
|
||||
|
||||
// In ddc_400m.v, add these debug signals:
|
||||
|
||||
// Debug monitoring
|
||||
reg [31:0] debug_adc_count = 0;
|
||||
reg [31:0] debug_baseband_count = 0;
|
||||
|
||||
always @(posedge clk_400m) begin
|
||||
if (adc_data_valid_i && adc_data_valid_q && debug_adc_count < 10) begin
|
||||
debug_adc_count <= debug_adc_count + 1;
|
||||
$display("DDC_ADC: data=%0d, count=%0d, time=%t",
|
||||
adc_data, debug_adc_count, $time);
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_100m) begin
|
||||
if (baseband_valid_i && baseband_valid_q && debug_baseband_count < 10) begin
|
||||
debug_baseband_count <= debug_baseband_count + 1;
|
||||
$display("DDC_BASEBAND: i=%0d, q=%0d, count=%0d, time=%t",
|
||||
baseband_i, baseband_q, debug_baseband_count, $time);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================================
|
||||
// Enhanced Phase Dithering Module
|
||||
// ============================================================================
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module lfsr_dither_enhanced #(
|
||||
parameter DITHER_WIDTH = 8 // Increased for better dithering
|
||||
)(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire enable,
|
||||
output wire [DITHER_WIDTH-1:0] dither_out
|
||||
);
|
||||
|
||||
reg [DITHER_WIDTH-1:0] lfsr_reg;
|
||||
reg [15:0] cycle_counter;
|
||||
reg lock_detected;
|
||||
|
||||
// Polynomial for better randomness: x^8 + x^6 + x^5 + x^4 + 1
|
||||
wire feedback;
|
||||
|
||||
generate
|
||||
if (DITHER_WIDTH == 4) begin
|
||||
assign feedback = lfsr_reg[3] ^ lfsr_reg[2];
|
||||
end else if (DITHER_WIDTH == 8) begin
|
||||
assign feedback = lfsr_reg[7] ^ lfsr_reg[5] ^ lfsr_reg[4] ^ lfsr_reg[3];
|
||||
end else begin
|
||||
assign feedback = lfsr_reg[DITHER_WIDTH-1] ^ lfsr_reg[DITHER_WIDTH-2];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
lfsr_reg <= {DITHER_WIDTH{1'b1}}; // Non-zero initial state
|
||||
cycle_counter <= 0;
|
||||
lock_detected <= 0;
|
||||
end else if (enable) begin
|
||||
lfsr_reg <= {lfsr_reg[DITHER_WIDTH-2:0], feedback};
|
||||
cycle_counter <= cycle_counter + 1;
|
||||
|
||||
// Detect LFSR lock after sufficient cycles
|
||||
if (cycle_counter > (2**DITHER_WIDTH * 8)) begin
|
||||
lock_detected <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign dither_out = lfsr_reg;
|
||||
|
||||
endmodule
|
||||
55
9_Firmware/9_2_FPGA/ddc_input_interface.v
Normal file
55
9_Firmware/9_2_FPGA/ddc_input_interface.v
Normal file
@@ -0,0 +1,55 @@
|
||||
`timescale 1ns / 1ps
|
||||
// ddc_input_interface.v
|
||||
module ddc_input_interface (
|
||||
input wire clk, // 100MHz
|
||||
input wire reset_n,
|
||||
|
||||
// DDC Input (18-bit)
|
||||
input wire signed [17:0] ddc_i,
|
||||
input wire signed [17:0] ddc_q,
|
||||
input wire valid_i,
|
||||
input wire valid_q,
|
||||
|
||||
// Scaled output (16-bit)
|
||||
output reg signed [15:0] adc_i,
|
||||
output reg signed [15:0] adc_q,
|
||||
output reg adc_valid,
|
||||
|
||||
// Status
|
||||
output wire data_sync_error
|
||||
);
|
||||
|
||||
// Synchronize valid signals
|
||||
reg valid_i_reg, valid_q_reg;
|
||||
reg valid_sync;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
valid_i_reg <= 1'b0;
|
||||
valid_q_reg <= 1'b0;
|
||||
valid_sync <= 1'b0;
|
||||
adc_valid <= 1'b0;
|
||||
end else begin
|
||||
valid_i_reg <= valid_i;
|
||||
valid_q_reg <= valid_q;
|
||||
|
||||
// Require both I and Q valid simultaneously
|
||||
valid_sync <= valid_i_reg && valid_q_reg;
|
||||
adc_valid <= valid_sync;
|
||||
end
|
||||
end
|
||||
|
||||
// Scale 18-bit to 16-bit with rounding
|
||||
// Option: Keep most significant 16 bits with rounding
|
||||
always @(posedge clk) begin
|
||||
if (valid_sync) begin
|
||||
// Round to nearest: add 0.5 LSB before truncation
|
||||
adc_i <= ddc_i[17:2] + ddc_i[1]; // Rounding
|
||||
adc_q <= ddc_q[17:2] + ddc_q[1]; // Rounding
|
||||
end
|
||||
end
|
||||
|
||||
// Error detection
|
||||
assign data_sync_error = (valid_i_reg ^ valid_q_reg);
|
||||
|
||||
endmodule
|
||||
305
9_Firmware/9_2_FPGA/doppler_processor.v
Normal file
305
9_Firmware/9_2_FPGA/doppler_processor.v
Normal file
@@ -0,0 +1,305 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module doppler_processor_optimized #(
|
||||
parameter DOPPLER_FFT_SIZE = 32,
|
||||
parameter RANGE_BINS = 64,
|
||||
parameter CHIRPS_PER_FRAME = 32,
|
||||
parameter WINDOW_TYPE = 0, // 0=Hamming, 1=Rectangular
|
||||
parameter DATA_WIDTH = 16
|
||||
)(
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire [31:0] range_data,
|
||||
input wire data_valid,
|
||||
input wire new_chirp_frame,
|
||||
output reg [31:0] doppler_output,
|
||||
output reg doppler_valid,
|
||||
output reg [4:0] doppler_bin,
|
||||
output reg [5:0] range_bin,
|
||||
output wire processing_active,
|
||||
output wire frame_complete,
|
||||
output reg [3:0] status
|
||||
);
|
||||
|
||||
// ==============================================
|
||||
// Window Coefficients (Simple Implementation)
|
||||
// ==============================================
|
||||
reg [DATA_WIDTH-1:0] window_coeff [0:31];
|
||||
|
||||
// Generate window coefficients
|
||||
integer w;
|
||||
initial begin
|
||||
if (WINDOW_TYPE == 0) begin
|
||||
// Pre-calculated Hamming window (Q15 format)
|
||||
window_coeff[0] = 16'h0800; window_coeff[1] = 16'h0862;
|
||||
window_coeff[2] = 16'h09CB; window_coeff[3] = 16'h0C3B;
|
||||
window_coeff[4] = 16'h0FB2; window_coeff[5] = 16'h142F;
|
||||
window_coeff[6] = 16'h19B2; window_coeff[7] = 16'h2039;
|
||||
window_coeff[8] = 16'h27C4; window_coeff[9] = 16'h3050;
|
||||
window_coeff[10] = 16'h39DB; window_coeff[11] = 16'h4462;
|
||||
window_coeff[12] = 16'h4FE3; window_coeff[13] = 16'h5C5A;
|
||||
window_coeff[14] = 16'h69C4; window_coeff[15] = 16'h781D;
|
||||
window_coeff[16] = 16'h7FFF; // Peak
|
||||
window_coeff[17] = 16'h781D; window_coeff[18] = 16'h69C4;
|
||||
window_coeff[19] = 16'h5C5A; window_coeff[20] = 16'h4FE3;
|
||||
window_coeff[21] = 16'h4462; window_coeff[22] = 16'h39DB;
|
||||
window_coeff[23] = 16'h3050; window_coeff[24] = 16'h27C4;
|
||||
window_coeff[25] = 16'h2039; window_coeff[26] = 16'h19B2;
|
||||
window_coeff[27] = 16'h142F; window_coeff[28] = 16'h0FB2;
|
||||
window_coeff[29] = 16'h0C3B; window_coeff[30] = 16'h09CB;
|
||||
window_coeff[31] = 16'h0862;
|
||||
end else begin
|
||||
// Rectangular window (all ones)
|
||||
for (w = 0; w < 32; w = w + 1) begin
|
||||
window_coeff[w] = 16'h7FFF;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ==============================================
|
||||
// Memory Declaration - FIXED SIZE
|
||||
// ==============================================
|
||||
localparam MEM_DEPTH = RANGE_BINS * CHIRPS_PER_FRAME;
|
||||
(* ram_style = "block" *) reg [DATA_WIDTH-1:0] doppler_i_mem [0:MEM_DEPTH-1];
|
||||
(* ram_style = "block" *) reg [DATA_WIDTH-1:0] doppler_q_mem [0:MEM_DEPTH-1];
|
||||
|
||||
// ==============================================
|
||||
// Control Registers
|
||||
// ==============================================
|
||||
reg [5:0] write_range_bin; // Changed to match RANGE_BINS width
|
||||
reg [4:0] write_chirp_index; // Changed to match CHIRPS_PER_FRAME width
|
||||
reg [5:0] read_range_bin;
|
||||
reg [4:0] read_doppler_index; // Changed name for clarity
|
||||
reg frame_buffer_full;
|
||||
reg [9:0] chirps_received; // Enough for up to 1024 chirps
|
||||
reg [1:0] chirp_state; // Track chirp accumulation state
|
||||
|
||||
|
||||
// ==============================================
|
||||
// FFT Interface
|
||||
// ==============================================
|
||||
reg fft_start;
|
||||
wire fft_ready;
|
||||
reg [DATA_WIDTH-1:0] fft_input_i;
|
||||
reg [DATA_WIDTH-1:0] fft_input_q;
|
||||
reg signed [31:0] mult_i, mult_q; // 32-bit to avoid overflow
|
||||
|
||||
reg fft_input_valid;
|
||||
reg fft_input_last;
|
||||
wire [DATA_WIDTH-1:0] fft_output_i;
|
||||
wire [DATA_WIDTH-1:0] fft_output_q;
|
||||
wire fft_output_valid;
|
||||
wire fft_output_last;
|
||||
|
||||
// ==============================================
|
||||
// Addressing
|
||||
// ==============================================
|
||||
wire [10:0] mem_write_addr;
|
||||
wire [10:0] mem_read_addr;
|
||||
|
||||
// Proper address calculation using parameters
|
||||
assign mem_write_addr = (write_chirp_index * RANGE_BINS) + write_range_bin;
|
||||
assign mem_read_addr = (read_doppler_index * RANGE_BINS) + read_range_bin;
|
||||
|
||||
// Alternative organization (choose one):
|
||||
// If you want range-major organization (all chirps for one range bin together):
|
||||
// assign mem_write_addr = (write_range_bin * CHIRPS_PER_FRAME) + write_chirp_index;
|
||||
// assign mem_read_addr = (read_range_bin * CHIRPS_PER_FRAME) + read_doppler_index;
|
||||
|
||||
// ==============================================
|
||||
// State Machine
|
||||
// ==============================================
|
||||
reg [2:0] state;
|
||||
localparam S_IDLE = 3'b000;
|
||||
localparam S_ACCUMULATE = 3'b001;
|
||||
localparam S_LOAD_FFT = 3'b010;
|
||||
localparam S_FFT_WAIT = 3'b011;
|
||||
localparam S_OUTPUT = 3'b100;
|
||||
|
||||
// Frame sync detection
|
||||
reg new_chirp_frame_d1;
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) new_chirp_frame_d1 <= 0;
|
||||
else new_chirp_frame_d1 <= new_chirp_frame;
|
||||
end
|
||||
wire frame_start_pulse = new_chirp_frame & ~new_chirp_frame_d1;
|
||||
|
||||
// ==============================================
|
||||
// Main State Machine - FIXED
|
||||
// ==============================================
|
||||
reg [5:0] fft_sample_counter;
|
||||
reg [9:0] processing_timeout;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
state <= S_IDLE;
|
||||
write_range_bin <= 0;
|
||||
write_chirp_index <= 0;
|
||||
read_range_bin <= 0;
|
||||
read_doppler_index <= 0;
|
||||
frame_buffer_full <= 0;
|
||||
doppler_valid <= 0;
|
||||
fft_start <= 0;
|
||||
fft_input_valid <= 0;
|
||||
fft_input_last <= 0;
|
||||
fft_sample_counter <= 0;
|
||||
processing_timeout <= 0;
|
||||
status <= 0;
|
||||
chirps_received <= 0;
|
||||
chirp_state <= 0;
|
||||
end else begin
|
||||
doppler_valid <= 0;
|
||||
fft_input_valid <= 0;
|
||||
fft_input_last <= 0;
|
||||
|
||||
if (processing_timeout > 0) begin
|
||||
processing_timeout <= processing_timeout - 1;
|
||||
end
|
||||
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (frame_start_pulse) begin
|
||||
// Start new frame
|
||||
write_chirp_index <= 0;
|
||||
write_range_bin <= 0;
|
||||
frame_buffer_full <= 0;
|
||||
chirps_received <= 0;
|
||||
//chirp_state <= 1; // Start accumulating
|
||||
end
|
||||
|
||||
if (data_valid && !frame_buffer_full) begin
|
||||
state <= S_ACCUMULATE;
|
||||
write_range_bin <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
S_ACCUMULATE: begin
|
||||
if (data_valid) begin
|
||||
// Store with proper addressing
|
||||
doppler_i_mem[mem_write_addr] <= range_data[15:0];
|
||||
doppler_q_mem[mem_write_addr] <= range_data[31:16];
|
||||
|
||||
// Debug output to see what's being written
|
||||
// $display("Time=%t: Write addr=%d (chirp=%d, range=%d), Data=%h",
|
||||
// $time, mem_write_addr, write_chirp_index, write_range_bin, range_data);
|
||||
|
||||
// Increment range bin
|
||||
if (write_range_bin < RANGE_BINS - 1) begin
|
||||
write_range_bin <= write_range_bin + 1;
|
||||
end else begin
|
||||
// Completed one chirp
|
||||
write_range_bin <= 0;
|
||||
write_chirp_index <= write_chirp_index + 1;
|
||||
chirps_received <= chirps_received + 1;
|
||||
|
||||
// Check if frame is complete
|
||||
if (write_chirp_index >= CHIRPS_PER_FRAME - 1) begin
|
||||
frame_buffer_full <= 1;
|
||||
chirp_state <= 0; // Stop accumulating
|
||||
// Could automatically start processing here:
|
||||
state <= S_LOAD_FFT;
|
||||
read_range_bin <= 0;
|
||||
read_doppler_index <= 0;
|
||||
fft_sample_counter <= 0;
|
||||
fft_start <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// [Rest of S_LOAD_FFT, S_FFT_WAIT, S_OUTPUT states remain similar]
|
||||
// But with fixed addressing in S_LOAD_FFT:
|
||||
S_LOAD_FFT: begin
|
||||
fft_start <= 0;
|
||||
|
||||
if (fft_sample_counter < DOPPLER_FFT_SIZE) begin
|
||||
// Use correct addressing for reading
|
||||
mult_i <= $signed(doppler_i_mem[mem_read_addr]) *
|
||||
$signed(window_coeff[read_doppler_index]);
|
||||
mult_q <= $signed(doppler_q_mem[mem_read_addr]) *
|
||||
$signed(window_coeff[read_doppler_index]);
|
||||
|
||||
// Round instead of truncate
|
||||
fft_input_i <= (mult_i + (1 << 14)) >>> 15; // Round to nearest
|
||||
fft_input_q <= (mult_q + (1 << 14)) >>> 15;
|
||||
|
||||
fft_input_valid <= 1;
|
||||
|
||||
if (fft_sample_counter == DOPPLER_FFT_SIZE - 1) begin
|
||||
fft_input_last <= 1;
|
||||
end
|
||||
|
||||
// Increment chirp index for next sample
|
||||
read_doppler_index <= read_doppler_index + 1;
|
||||
fft_sample_counter <= fft_sample_counter + 1;
|
||||
end else begin
|
||||
state <= S_FFT_WAIT;
|
||||
fft_sample_counter <= 0;
|
||||
processing_timeout <= 100;
|
||||
end
|
||||
end
|
||||
|
||||
S_FFT_WAIT: begin
|
||||
if (fft_output_valid) begin
|
||||
doppler_output <= {fft_output_q[15:0], fft_output_i[15:0]};
|
||||
doppler_bin <= fft_sample_counter;
|
||||
range_bin <= read_range_bin;
|
||||
doppler_valid <= 1;
|
||||
|
||||
fft_sample_counter <= fft_sample_counter + 1;
|
||||
|
||||
if (fft_output_last) begin
|
||||
state <= S_OUTPUT;
|
||||
fft_sample_counter <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
if (processing_timeout == 0) begin
|
||||
state <= S_OUTPUT;
|
||||
end
|
||||
end
|
||||
|
||||
S_OUTPUT: begin
|
||||
if (read_range_bin < RANGE_BINS - 1) begin
|
||||
read_range_bin <= read_range_bin + 1;
|
||||
read_doppler_index <= 0;
|
||||
state <= S_LOAD_FFT;
|
||||
fft_start <= 1;
|
||||
end else begin
|
||||
state <= S_IDLE;
|
||||
frame_buffer_full <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endcase
|
||||
|
||||
status <= {state, frame_buffer_full};
|
||||
end
|
||||
end
|
||||
|
||||
// ==============================================
|
||||
// FFT Module
|
||||
// ==============================================
|
||||
xfft_32 fft_inst (
|
||||
.aclk(clk),
|
||||
.aresetn(reset_n),
|
||||
.s_axis_config_tdata(8'h01),
|
||||
.s_axis_config_tvalid(fft_start),
|
||||
.s_axis_config_tready(fft_ready),
|
||||
.s_axis_data_tdata({fft_input_q, fft_input_i}),
|
||||
.s_axis_data_tvalid(fft_input_valid),
|
||||
.s_axis_data_tlast(fft_input_last),
|
||||
.m_axis_data_tdata({fft_output_q, fft_output_i}),
|
||||
.m_axis_data_tvalid(fft_output_valid),
|
||||
.m_axis_data_tlast(fft_output_last),
|
||||
.m_axis_data_tready(1'b1)
|
||||
);
|
||||
|
||||
// ==============================================
|
||||
// Status Outputs
|
||||
// ==============================================
|
||||
assign processing_active = (state != S_IDLE);
|
||||
assign frame_complete = (state == S_IDLE && frame_buffer_full == 0);
|
||||
|
||||
|
||||
endmodule
|
||||
26
9_Firmware/9_2_FPGA/edge_detector.v
Normal file
26
9_Firmware/9_2_FPGA/edge_detector.v
Normal file
@@ -0,0 +1,26 @@
|
||||
module edge_detector_enhanced (
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire signal_in,
|
||||
output wire rising_falling_edge
|
||||
);
|
||||
|
||||
reg signal_in_prev;
|
||||
reg signal_in_prev2;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
signal_in_prev <= 1'b0;
|
||||
signal_in_prev2 <= 1'b0;
|
||||
end else begin
|
||||
signal_in_prev <= signal_in;
|
||||
signal_in_prev2 <= signal_in_prev;
|
||||
end
|
||||
end
|
||||
|
||||
// Rising edge: was low, now high (with synchronization) signal_in_prev & ~signal_in_prev2;
|
||||
//Falling edge: was high, now low (with synchronization) falling_edge = ~signal_in_prev & signal_in_prev2
|
||||
assign rising_falling_edge = (signal_in_prev & ~signal_in_prev2)|(~signal_in_prev & signal_in_prev2);
|
||||
|
||||
|
||||
endmodule
|
||||
124
9_Firmware/9_2_FPGA/fft_1024_forward.v
Normal file
124
9_Firmware/9_2_FPGA/fft_1024_forward.v
Normal file
@@ -0,0 +1,124 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module fft_1024_forward_enhanced (
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire [15:0] data_i,
|
||||
input wire [15:0] data_q,
|
||||
input wire data_valid,
|
||||
output wire [15:0] fft_i,
|
||||
output wire [15:0] fft_q,
|
||||
output wire fft_valid
|
||||
);
|
||||
|
||||
// ========== MATCH YOUR FFT IP CONFIGURATION ==========
|
||||
wire [15:0] s_axis_config_tdata; // 16-bit for your IP
|
||||
wire s_axis_config_tvalid;
|
||||
wire s_axis_config_tready;
|
||||
wire [31:0] s_axis_data_tdata; // 32-bit for your IP {Q[15:0],I[15:0]}
|
||||
wire s_axis_data_tvalid;
|
||||
wire s_axis_data_tready;
|
||||
wire s_axis_data_tlast;
|
||||
wire [31:0] m_axis_data_tdata; // 32-bit for your IP
|
||||
wire m_axis_data_tvalid;
|
||||
wire m_axis_data_tready;
|
||||
wire m_axis_data_tlast;
|
||||
|
||||
// Configuration: 16-bit, bit 0 = 1 for forward FFT...
|
||||
assign s_axis_config_tdata = 16'h0001;
|
||||
assign s_axis_config_tvalid = 1'b1; // Keep valid until accepted
|
||||
|
||||
|
||||
assign s_axis_data_tdata = {data_q, data_i}; // {Q, I}
|
||||
assign s_axis_data_tvalid = data_valid;
|
||||
|
||||
// Frame counter for tlast
|
||||
reg [9:0] sample_count;
|
||||
reg frame_active;
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
sample_count <= 0;
|
||||
frame_active <= 0;
|
||||
end else begin
|
||||
if (data_valid && !frame_active) begin
|
||||
frame_active <= 1'b1;
|
||||
sample_count <= 0;
|
||||
end
|
||||
|
||||
if (frame_active && data_valid) begin
|
||||
if (sample_count == 1023) begin
|
||||
sample_count <= 0;
|
||||
frame_active <= 0;
|
||||
end else begin
|
||||
sample_count <= sample_count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
assign s_axis_data_tlast = (sample_count == 1023) && data_valid;
|
||||
|
||||
// Output: Extract from 64-bit output
|
||||
// Assuming output format is also {Q[31:0], I[31:0]}
|
||||
assign fft_i = m_axis_data_tdata[15:0]; // Lower 16 bits = I
|
||||
assign fft_q = m_axis_data_tdata[31:16]; // Upper 16 bits = Q
|
||||
assign fft_valid = m_axis_data_tvalid;
|
||||
assign m_axis_data_tready = 1'b1;
|
||||
|
||||
// ========== DEBUG ==========
|
||||
/*
|
||||
reg [31:0] debug_counter = 0;
|
||||
always @(posedge clk) begin
|
||||
debug_counter <= debug_counter + 1;
|
||||
|
||||
// Monitor first 2000 cycles
|
||||
if (debug_counter < 2000) begin
|
||||
// Configuration
|
||||
if (s_axis_config_tvalid && s_axis_config_tready) begin
|
||||
$display("[FFT_CORRECTED @%d] CONFIG ACCEPTED! tdata=%h",
|
||||
debug_counter, s_axis_config_tdata);
|
||||
end
|
||||
|
||||
// Data input
|
||||
if (s_axis_data_tvalid && s_axis_data_tready && debug_counter < 1050) begin
|
||||
$display("[FFT_CORRECTED @%d] Data in: I=%h Q=%h count=%d tlast=%b",
|
||||
debug_counter, data_i, data_q, sample_count, s_axis_data_tlast);
|
||||
end
|
||||
|
||||
// Data output
|
||||
if (m_axis_data_tvalid && debug_counter < 3000) begin
|
||||
$display("[FFT_CORRECTED @%d] FFT OUT: I=%h Q=%h",
|
||||
debug_counter, fft_i, fft_q);
|
||||
end
|
||||
|
||||
// Stuck detection
|
||||
if (debug_counter == 100 && !s_axis_config_tready) begin
|
||||
$display("[FFT_CORRECTED] WARNING: config_tready still 0 after 100 cycles");
|
||||
end
|
||||
end
|
||||
end
|
||||
*/
|
||||
// ========== FFT IP INSTANCE ==========
|
||||
// This must match the name in your project
|
||||
FFT_enhanced fft_forward_inst (
|
||||
.aclk(clk),
|
||||
.aresetn(reset_n), // Active-low reset
|
||||
|
||||
// Configuration (16-bit)
|
||||
.s_axis_config_tdata(s_axis_config_tdata),
|
||||
.s_axis_config_tvalid(s_axis_config_tvalid),
|
||||
.s_axis_config_tready(s_axis_config_tready),
|
||||
|
||||
// Data input (64-bit)
|
||||
.s_axis_data_tdata(s_axis_data_tdata),
|
||||
.s_axis_data_tvalid(s_axis_data_tvalid),
|
||||
.s_axis_data_tready(s_axis_data_tready),
|
||||
.s_axis_data_tlast(s_axis_data_tlast),
|
||||
|
||||
// Data output (64-bit)
|
||||
.m_axis_data_tdata(m_axis_data_tdata),
|
||||
.m_axis_data_tvalid(m_axis_data_tvalid),
|
||||
.m_axis_data_tlast(m_axis_data_tlast)
|
||||
|
||||
);
|
||||
|
||||
endmodule
|
||||
97
9_Firmware/9_2_FPGA/fft_1024_inverse.v
Normal file
97
9_Firmware/9_2_FPGA/fft_1024_inverse.v
Normal file
@@ -0,0 +1,97 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module fft_1024_inverse_enhanced (
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire [15:0] data_i,
|
||||
input wire [15:0] data_q,
|
||||
input wire data_valid,
|
||||
output wire [15:0] ifft_i,
|
||||
output wire [15:0] ifft_q,
|
||||
output wire ifft_valid
|
||||
);
|
||||
|
||||
// ========== MATCH YOUR FFT IP CONFIGURATION ==========
|
||||
wire [15:0] s_axis_config_tdata; // 16-bit
|
||||
wire s_axis_config_tvalid;
|
||||
wire s_axis_config_tready;
|
||||
wire [31:0] s_axis_data_tdata; // 32-bit for your IP {Q[15:0],I[15:0]}
|
||||
wire s_axis_data_tvalid;
|
||||
wire s_axis_data_tready;
|
||||
wire s_axis_data_tlast;
|
||||
wire [31:0] m_axis_data_tdata; // 32-bit
|
||||
wire m_axis_data_tvalid;
|
||||
wire m_axis_data_tready;
|
||||
wire m_axis_data_tlast;
|
||||
|
||||
// Configuration: bit 0 = 0 for inverse FFT
|
||||
assign s_axis_config_tdata = 16'h0000;
|
||||
assign s_axis_config_tvalid = 1'b1;
|
||||
|
||||
|
||||
assign s_axis_data_tdata = {data_q, data_i};
|
||||
assign s_axis_data_tvalid = data_valid;
|
||||
|
||||
// Frame counter
|
||||
reg [9:0] sample_count;
|
||||
reg frame_active;
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
sample_count <= 0;
|
||||
frame_active <= 0;
|
||||
end else begin
|
||||
if (data_valid && !frame_active) begin
|
||||
frame_active <= 1'b1;
|
||||
sample_count <= 0;
|
||||
end
|
||||
|
||||
if (frame_active && data_valid) begin
|
||||
if (sample_count == 1023) begin
|
||||
sample_count <= 0;
|
||||
frame_active <= 0;
|
||||
end else begin
|
||||
sample_count <= sample_count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
assign s_axis_data_tlast = (sample_count == 1023) && data_valid;
|
||||
// Output
|
||||
assign ifft_i = m_axis_data_tdata[15:0]; // I = lower 16 bits
|
||||
assign ifft_q = m_axis_data_tdata[31:16]; // Q = upper 16 bits
|
||||
assign ifft_valid = m_axis_data_tvalid;
|
||||
assign m_axis_data_tready = 1'b1;
|
||||
|
||||
// Debug
|
||||
reg [31:0] debug_counter;
|
||||
always @(posedge clk) begin
|
||||
debug_counter <= debug_counter + 1;
|
||||
|
||||
if (debug_counter < 1000) begin
|
||||
if (s_axis_config_tvalid && s_axis_config_tready) begin
|
||||
$display("[IFFT_CORRECTED @%d] CONFIG ACCEPTED!", debug_counter);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// IFFT IP instance
|
||||
FFT_enhanced ifft_inverse_inst ( // Same IP core, different configuration
|
||||
.aclk(clk),
|
||||
.aresetn(reset_n),
|
||||
|
||||
.s_axis_config_tdata(s_axis_config_tdata),
|
||||
.s_axis_config_tvalid(s_axis_config_tvalid),
|
||||
.s_axis_config_tready(s_axis_config_tready),
|
||||
|
||||
.s_axis_data_tdata(s_axis_data_tdata),
|
||||
.s_axis_data_tvalid(s_axis_data_tvalid),
|
||||
.s_axis_data_tready(s_axis_data_tready),
|
||||
.s_axis_data_tlast(s_axis_data_tlast),
|
||||
|
||||
.m_axis_data_tdata(m_axis_data_tdata),
|
||||
.m_axis_data_tvalid(m_axis_data_tvalid),
|
||||
.m_axis_data_tlast(m_axis_data_tlast)
|
||||
|
||||
);
|
||||
|
||||
endmodule
|
||||
124
9_Firmware/9_2_FPGA/fir_lowpass.v
Normal file
124
9_Firmware/9_2_FPGA/fir_lowpass.v
Normal file
@@ -0,0 +1,124 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module fir_lowpass_parallel_enhanced (
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire signed [17:0] data_in,
|
||||
input wire data_valid,
|
||||
output reg signed [17:0] data_out,
|
||||
output reg data_out_valid,
|
||||
output wire fir_ready,
|
||||
output wire filter_overflow
|
||||
);
|
||||
|
||||
parameter TAPS = 32;
|
||||
parameter COEFF_WIDTH = 18;
|
||||
parameter DATA_WIDTH = 18;
|
||||
parameter ACCUM_WIDTH = 36;
|
||||
|
||||
// Filter coefficients
|
||||
reg signed [COEFF_WIDTH-1:0] coeff [0:TAPS-1];
|
||||
|
||||
// Parallel delay line
|
||||
reg signed [DATA_WIDTH-1:0] delay_line [0:TAPS-1];
|
||||
|
||||
// Parallel multiply-accumulate structure
|
||||
wire signed [DATA_WIDTH+COEFF_WIDTH-1:0] mult_result [0:TAPS-1];
|
||||
|
||||
// Wires for parallel addition (combinatorial)
|
||||
wire signed [ACCUM_WIDTH-1:0] sum_stage1_0, sum_stage1_1, sum_stage1_2, sum_stage1_3;
|
||||
wire signed [ACCUM_WIDTH-1:0] sum_stage2_0, sum_stage2_1;
|
||||
wire signed [ACCUM_WIDTH-1:0] sum_stage3;
|
||||
|
||||
// Registered accumulator
|
||||
reg signed [ACCUM_WIDTH-1:0] accumulator_reg;
|
||||
|
||||
// Initialize coefficients
|
||||
initial begin
|
||||
// Proper low-pass filter coefficients
|
||||
coeff[ 0] = 18'sh00AD; coeff[ 1] = 18'sh00CE; coeff[ 2] = 18'sh3FD87; coeff[ 3] = 18'sh02A6;
|
||||
coeff[ 4] = 18'sh00E0; coeff[ 5] = 18'sh3F8C0; coeff[ 6] = 18'sh0A45; coeff[ 7] = 18'sh3FD82;
|
||||
coeff[ 8] = 18'sh3F0B5; coeff[ 9] = 18'sh1CAD; coeff[10] = 18'sh3EE59; coeff[11] = 18'sh3E821;
|
||||
coeff[12] = 18'sh4841; coeff[13] = 18'sh3B340; coeff[14] = 18'sh3E299; coeff[15] = 18'sh1FFFF;
|
||||
coeff[16] = 18'sh1FFFF; coeff[17] = 18'sh3E299; coeff[18] = 18'sh3B340; coeff[19] = 18'sh4841;
|
||||
coeff[20] = 18'sh3E821; coeff[21] = 18'sh3EE59; coeff[22] = 18'sh1CAD; coeff[23] = 18'sh3F0B5;
|
||||
coeff[24] = 18'sh3FD82; coeff[25] = 18'sh0A45; coeff[26] = 18'sh3F8C0; coeff[27] = 18'sh00E0;
|
||||
coeff[28] = 18'sh02A6; coeff[29] = 18'sh3FD87; coeff[30] = 18'sh00CE; coeff[31] = 18'sh00AD;
|
||||
end
|
||||
|
||||
// Generate parallel multipliers
|
||||
genvar k;
|
||||
generate
|
||||
for (k = 0; k < TAPS; k = k + 1) begin : mult_gen
|
||||
assign mult_result[k] = delay_line[k] * coeff[k];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// COMBINATORIAL PARALLEL ADDITION TREE
|
||||
// Stage 1: Group of 8
|
||||
assign sum_stage1_0 = mult_result[0] + mult_result[1] + mult_result[2] + mult_result[3] +
|
||||
mult_result[4] + mult_result[5] + mult_result[6] + mult_result[7];
|
||||
assign sum_stage1_1 = mult_result[8] + mult_result[9] + mult_result[10] + mult_result[11] +
|
||||
mult_result[12] + mult_result[13] + mult_result[14] + mult_result[15];
|
||||
assign sum_stage1_2 = mult_result[16] + mult_result[17] + mult_result[18] + mult_result[19] +
|
||||
mult_result[20] + mult_result[21] + mult_result[22] + mult_result[23];
|
||||
assign sum_stage1_3 = mult_result[24] + mult_result[25] + mult_result[26] + mult_result[27] +
|
||||
mult_result[28] + mult_result[29] + mult_result[30] + mult_result[31];
|
||||
|
||||
// Stage 2: Combine groups of 2
|
||||
assign sum_stage2_0 = sum_stage1_0 + sum_stage1_1;
|
||||
assign sum_stage2_1 = sum_stage1_2 + sum_stage1_3;
|
||||
|
||||
// Stage 3: Final sum
|
||||
assign sum_stage3 = sum_stage2_0 + sum_stage2_1;
|
||||
|
||||
integer i;
|
||||
|
||||
// SINGLE-CYCLE PIPELINE PROCESSING
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
// Reset delay line
|
||||
for (i = 0; i < TAPS; i = i + 1) begin
|
||||
delay_line[i] <= 0;
|
||||
end
|
||||
accumulator_reg <= 0;
|
||||
data_out <= 0;
|
||||
data_out_valid <= 0;
|
||||
end else begin
|
||||
// Always shift in new data when valid
|
||||
if (data_valid) begin
|
||||
// Shift delay line
|
||||
for (i = TAPS-1; i > 0; i = i - 1) begin
|
||||
delay_line[i] <= delay_line[i-1];
|
||||
end
|
||||
delay_line[0] <= data_in;
|
||||
|
||||
// Register the combinatorial sum
|
||||
accumulator_reg <= sum_stage3;
|
||||
|
||||
// Output with 1-cycle latency
|
||||
data_out_valid <= 1'b1;
|
||||
end else begin
|
||||
data_out_valid <= 1'b0;
|
||||
end
|
||||
|
||||
// Output saturation logic (registered)
|
||||
if (accumulator_reg > (2**(ACCUM_WIDTH-2)-1)) begin
|
||||
data_out <= (2**(DATA_WIDTH-1))-1;
|
||||
end else if (accumulator_reg < -(2**(ACCUM_WIDTH-2))) begin
|
||||
data_out <= -(2**(DATA_WIDTH-1));
|
||||
end else begin
|
||||
// Round and truncate (keep middle bits)
|
||||
data_out <= accumulator_reg[ACCUM_WIDTH-2:DATA_WIDTH-1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Always ready to accept new data
|
||||
assign fir_ready = 1'b1;
|
||||
|
||||
// Overflow detection (simplified)
|
||||
assign filter_overflow = (accumulator_reg > (2**(ACCUM_WIDTH-2)-1)) ||
|
||||
(accumulator_reg < -(2**(ACCUM_WIDTH-2)));
|
||||
|
||||
endmodule
|
||||
137
9_Firmware/9_2_FPGA/frequency_matched_filter.v
Normal file
137
9_Firmware/9_2_FPGA/frequency_matched_filter.v
Normal file
@@ -0,0 +1,137 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
// frequency_matched_filter_conjugate.v
|
||||
module frequency_matched_filter (
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
|
||||
// Input from Forward FFT (16-bit Q15)
|
||||
input wire signed [15:0] fft_real_in,
|
||||
input wire signed [15:0] fft_imag_in,
|
||||
input wire fft_valid_in,
|
||||
|
||||
// Reference Chirp (16-bit Q15) - assumed to be FFT of transmitted chirp
|
||||
|
||||
input wire signed [15:0] ref_chirp_real,
|
||||
input wire signed [15:0] ref_chirp_imag,
|
||||
|
||||
// Output (16-bit Q15) - FFT(input) ? conj(FFT(reference))
|
||||
output wire signed [15:0] filtered_real,
|
||||
output wire signed [15:0] filtered_imag,
|
||||
output wire filtered_valid,
|
||||
|
||||
output wire [1:0] state
|
||||
);
|
||||
|
||||
// Complex multiplication: (a + jb) ? (c - jd) = (ac + bd) + j(bc - ad)
|
||||
// Note: We use CONJUGATE of reference for matched filter
|
||||
|
||||
// Pipeline registers
|
||||
reg signed [15:0] a_reg, b_reg, c_reg, d_reg;
|
||||
reg valid_p1;
|
||||
reg signed [31:0] ac_reg, bd_reg, bc_reg, ad_reg;
|
||||
reg valid_p2;
|
||||
reg signed [31:0] real_sum, imag_sum;
|
||||
reg valid_p3;
|
||||
reg signed [15:0] real_out, imag_out;
|
||||
reg valid_out;
|
||||
|
||||
// Address counter
|
||||
reg [9:0] addr_counter;
|
||||
|
||||
|
||||
// ========== PIPELINE STAGE 1: REGISTER INPUTS ==========
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
a_reg <= 16'd0; b_reg <= 16'd0;
|
||||
c_reg <= 16'd0; d_reg <= 16'd0;
|
||||
valid_p1 <= 1'b0;
|
||||
end else begin
|
||||
if (fft_valid_in) begin
|
||||
a_reg <= fft_real_in; // a
|
||||
b_reg <= fft_imag_in; // b
|
||||
c_reg <= ref_chirp_real; // c
|
||||
d_reg <= ref_chirp_imag; // d
|
||||
end
|
||||
valid_p1 <= fft_valid_in;
|
||||
end
|
||||
end
|
||||
|
||||
// ========== PIPELINE STAGE 2: MULTIPLICATIONS ==========
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
ac_reg <= 32'd0; bd_reg <= 32'd0;
|
||||
bc_reg <= 32'd0; ad_reg <= 32'd0;
|
||||
valid_p2 <= 1'b0;
|
||||
end else begin
|
||||
// Q15 ? Q15 = Q30
|
||||
ac_reg <= a_reg * c_reg; // ac
|
||||
bd_reg <= b_reg * d_reg; // bd
|
||||
bc_reg <= b_reg * c_reg; // bc
|
||||
ad_reg <= a_reg * d_reg; // ad
|
||||
|
||||
valid_p2 <= valid_p1;
|
||||
end
|
||||
end
|
||||
|
||||
// ========== PIPELINE STAGE 3: ADDITIONS ==========
|
||||
// For conjugate multiplication: (ac + bd) + j(bc - ad)
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
real_sum <= 32'd0;
|
||||
imag_sum <= 32'd0;
|
||||
valid_p3 <= 1'b0;
|
||||
end else begin
|
||||
real_sum <= ac_reg + bd_reg; // ac + bd
|
||||
imag_sum <= bc_reg - ad_reg; // bc - ad
|
||||
|
||||
valid_p3 <= valid_p2;
|
||||
end
|
||||
end
|
||||
|
||||
// ========== PIPELINE STAGE 4: SATURATION ==========
|
||||
function automatic signed [15:0] saturate_and_scale;
|
||||
input signed [31:0] q30_value;
|
||||
reg signed [15:0] result;
|
||||
reg signed [31:0] rounded;
|
||||
begin
|
||||
// Round to nearest: add 0.5 LSB (bit 14)
|
||||
rounded = q30_value + (1 << 14);
|
||||
|
||||
// Check for overflow
|
||||
if (rounded > 32'sh3FFF8000) begin // > 32767.5 in Q30
|
||||
result = 16'h7FFF;
|
||||
end else if (rounded < 32'shC0008000) begin // < -32768.5 in Q30
|
||||
result = 16'h8000;
|
||||
end else begin
|
||||
// Take bits [30:15] for Q15
|
||||
result = rounded[30:15];
|
||||
end
|
||||
|
||||
saturate_and_scale = result;
|
||||
end
|
||||
endfunction
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
real_out <= 16'd0;
|
||||
imag_out <= 16'd0;
|
||||
valid_out <= 1'b0;
|
||||
end else begin
|
||||
if (valid_p3) begin
|
||||
real_out <= saturate_and_scale(real_sum);
|
||||
imag_out <= saturate_and_scale(imag_sum);
|
||||
end
|
||||
valid_out <= valid_p3;
|
||||
end
|
||||
end
|
||||
|
||||
// ========== OUTPUT ASSIGNMENTS ==========
|
||||
assign filtered_real = real_out;
|
||||
assign filtered_imag = imag_out;
|
||||
assign filtered_valid = valid_out;
|
||||
|
||||
// Simple state output
|
||||
assign state = {valid_out, valid_p3};
|
||||
|
||||
endmodule
|
||||
107
9_Firmware/9_2_FPGA/latency_buffer_2159.v
Normal file
107
9_Firmware/9_2_FPGA/latency_buffer_2159.v
Normal file
@@ -0,0 +1,107 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
// latency_buffer_2159_fixed.v
|
||||
module latency_buffer_2159 #(
|
||||
parameter DATA_WIDTH = 32,
|
||||
parameter LATENCY = 3187
|
||||
) (
|
||||
input wire clk,
|
||||
input wire reset_n,
|
||||
input wire [DATA_WIDTH-1:0] data_in,
|
||||
input wire valid_in,
|
||||
output wire [DATA_WIDTH-1:0] data_out,
|
||||
output wire valid_out
|
||||
);
|
||||
|
||||
// ========== FIXED PARAMETERS ==========
|
||||
localparam ADDR_WIDTH = 12; // Enough for 4096 entries (>2159)
|
||||
|
||||
// ========== FIXED LOGIC ==========
|
||||
(* ram_style = "block" *) reg [DATA_WIDTH-1:0] bram [0:4095];
|
||||
reg [ADDR_WIDTH-1:0] write_ptr;
|
||||
reg [ADDR_WIDTH-1:0] read_ptr;
|
||||
reg valid_out_reg;
|
||||
|
||||
// Delay counter to track when LATENCY cycles have passed
|
||||
reg [ADDR_WIDTH-1:0] delay_counter;
|
||||
reg buffer_has_data; // Flag when buffer has accumulated LATENCY samples
|
||||
|
||||
// ========== FIXED INITIALIZATION ==========
|
||||
integer k;
|
||||
initial begin
|
||||
for (k = 0; k < 4096; k = k + 1) begin
|
||||
bram[k] = {DATA_WIDTH{1'b0}};
|
||||
end
|
||||
write_ptr = 0;
|
||||
read_ptr = 0;
|
||||
valid_out_reg = 0;
|
||||
delay_counter = 0;
|
||||
buffer_has_data = 0;
|
||||
end
|
||||
|
||||
// ========== FIXED STATE MACHINE ==========
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
write_ptr <= 0;
|
||||
read_ptr <= 0;
|
||||
valid_out_reg <= 0;
|
||||
delay_counter <= 0;
|
||||
buffer_has_data <= 0;
|
||||
end else begin
|
||||
// Default: no valid output
|
||||
valid_out_reg <= 0;
|
||||
|
||||
// ===== WRITE SIDE =====
|
||||
if (valid_in) begin
|
||||
// Store data
|
||||
bram[write_ptr] <= data_in;
|
||||
|
||||
// Increment write pointer (wrap at 4095)
|
||||
if (write_ptr == 4095) begin
|
||||
write_ptr <= 0;
|
||||
end else begin
|
||||
write_ptr <= write_ptr + 1;
|
||||
end
|
||||
|
||||
// Count how many samples we've written
|
||||
if (delay_counter < LATENCY) begin
|
||||
delay_counter <= delay_counter + 1;
|
||||
|
||||
// When we've written LATENCY samples, buffer is "primed"
|
||||
if (delay_counter == LATENCY - 1) begin
|
||||
buffer_has_data <= 1'b1;
|
||||
// $display("[LAT_BUF] Buffer now has %d samples (primed)", LATENCY);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ===== READ SIDE =====
|
||||
// Only start reading after we have LATENCY samples in buffer
|
||||
if (buffer_has_data && valid_in) begin
|
||||
// Read pointer follows write pointer with LATENCY delay
|
||||
// Calculate: read_ptr = (write_ptr - LATENCY) mod 4096
|
||||
|
||||
// Handle wrap-around correctly
|
||||
if (write_ptr >= LATENCY) begin
|
||||
read_ptr <= write_ptr - LATENCY;
|
||||
end else begin
|
||||
// Wrap around: 4096 + write_ptr - LATENCY
|
||||
read_ptr <= 4096 + write_ptr - LATENCY;
|
||||
end
|
||||
|
||||
// Output is valid
|
||||
valid_out_reg <= 1'b1;
|
||||
|
||||
//$display("[LAT_BUF] Reading: write_ptr=%d, read_ptr=%d, data=%h",
|
||||
// write_ptr, read_ptr, bram[read_ptr]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ========== OUTPUTS ==========
|
||||
assign data_out = bram[read_ptr];
|
||||
assign valid_out = valid_out_reg;
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
1024
9_Firmware/9_2_FPGA/long_chirp_seg0_i.mem
Normal file
1024
9_Firmware/9_2_FPGA/long_chirp_seg0_i.mem
Normal file
File diff suppressed because it is too large
Load Diff
1024
9_Firmware/9_2_FPGA/long_chirp_seg0_q.mem
Normal file
1024
9_Firmware/9_2_FPGA/long_chirp_seg0_q.mem
Normal file
File diff suppressed because it is too large
Load Diff
1024
9_Firmware/9_2_FPGA/long_chirp_seg1_i.mem
Normal file
1024
9_Firmware/9_2_FPGA/long_chirp_seg1_i.mem
Normal file
File diff suppressed because it is too large
Load Diff
1024
9_Firmware/9_2_FPGA/long_chirp_seg1_q.mem
Normal file
1024
9_Firmware/9_2_FPGA/long_chirp_seg1_q.mem
Normal file
File diff suppressed because it is too large
Load Diff
1024
9_Firmware/9_2_FPGA/long_chirp_seg2_i.mem
Normal file
1024
9_Firmware/9_2_FPGA/long_chirp_seg2_i.mem
Normal file
File diff suppressed because it is too large
Load Diff
1024
9_Firmware/9_2_FPGA/long_chirp_seg2_q.mem
Normal file
1024
9_Firmware/9_2_FPGA/long_chirp_seg2_q.mem
Normal file
File diff suppressed because it is too large
Load Diff
45
9_Firmware/9_2_FPGA/lvds_to_cmos_400m.v
Normal file
45
9_Firmware/9_2_FPGA/lvds_to_cmos_400m.v
Normal file
@@ -0,0 +1,45 @@
|
||||
`timescale 1ns / 1ps
|
||||
module lvds_to_cmos_400m (
|
||||
// ADC Physical Interface (LVDS Inputs)
|
||||
input wire clk_400m_p, // Data Clock Output P (400MHz LVDS, 2.5V)
|
||||
input wire clk_400m_n, // Data Clock Output N (400MHz LVDS, 2.5V)
|
||||
input wire reset_n, // Active-low reset
|
||||
|
||||
// CMOS Output Interface (400MHz Domain)
|
||||
output reg clk_400m_cmos // ADC data clock (CMOS, 3.3V)
|
||||
);
|
||||
|
||||
// LVDS to single-ended conversion
|
||||
wire clk_400m_se; // Single-ended DCO from ADC
|
||||
|
||||
|
||||
// IBUFDS for DCO clock (LVDS to CMOS conversion)
|
||||
IBUFDS #(
|
||||
.DIFF_TERM("FALSE"), // DISABLE internal termination (using external 100O)
|
||||
.IOSTANDARD("LVDS_25") // 2.5V LVDS standard
|
||||
) ibufds_dco (
|
||||
.O(clk_400m_se), // Single-ended 400MHz clock
|
||||
.I(clk_400m_p),
|
||||
.IB(clk_400m_n)
|
||||
);
|
||||
|
||||
// Optional: Global clock buffer for better clock distribution
|
||||
wire clk_400m_buffered;
|
||||
BUFG bufg_dco (
|
||||
.I(clk_400m_se),
|
||||
.O(clk_400m_buffered)
|
||||
);
|
||||
|
||||
|
||||
// Main processing: Capture on rising edge only
|
||||
always @(posedge clk_400m_buffered or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
// Reset state
|
||||
clk_400m_cmos <= 1'b0;
|
||||
end else begin
|
||||
// Output buffered DCO clock
|
||||
clk_400m_cmos <= clk_400m_buffered;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
410
9_Firmware/9_2_FPGA/matched_filter_multi_segment.v
Normal file
410
9_Firmware/9_2_FPGA/matched_filter_multi_segment.v
Normal file
@@ -0,0 +1,410 @@
|
||||
`timescale 1ns / 1ps
|
||||
// matched_filter_multi_segment.v
|
||||
module matched_filter_multi_segment (
|
||||
input wire clk, // 100MHz
|
||||
input wire reset_n,
|
||||
|
||||
// Input from DDC (100 MSPS)
|
||||
input wire signed [17:0] ddc_i,
|
||||
input wire signed [17:0] ddc_q,
|
||||
input wire ddc_valid,
|
||||
|
||||
// Chirp control (from sequence controller)
|
||||
input wire use_long_chirp, //
|
||||
input wire [5:0] chirp_counter, //
|
||||
|
||||
// Microcontroller sync signals
|
||||
input wire mc_new_chirp, // Toggle for new chirp (32)
|
||||
input wire mc_new_elevation, // Toggle for new elevation (32)
|
||||
input wire mc_new_azimuth, // Toggle for new azimuth (50)
|
||||
|
||||
input wire [15:0] long_chirp_real,
|
||||
input wire [15:0] long_chirp_imag,
|
||||
input wire [15:0] short_chirp_real,
|
||||
input wire [15:0] short_chirp_imag,
|
||||
|
||||
// Memory system interface
|
||||
output reg [1:0] segment_request,
|
||||
output wire [9:0] sample_addr_out, // Tell memory which sample we need
|
||||
output reg mem_request,
|
||||
input wire mem_ready,
|
||||
|
||||
// Output: Pulse compressed
|
||||
output wire signed [15:0] pc_i_w,
|
||||
output wire signed [15:0] pc_q_w,
|
||||
output wire pc_valid_w,
|
||||
|
||||
// Status
|
||||
output reg [3:0] status
|
||||
);
|
||||
|
||||
// ========== FIXED PARAMETERS ==========
|
||||
parameter BUFFER_SIZE = 1024;
|
||||
parameter LONG_CHIRP_SAMPLES = 3000; // Still 3000 samples total
|
||||
parameter SHORT_CHIRP_SAMPLES = 50; // 0.5µs @ 100MHz
|
||||
parameter OVERLAP_SAMPLES = 128; // Standard for 1024-pt FFT
|
||||
parameter SEGMENT_ADVANCE = BUFFER_SIZE - OVERLAP_SAMPLES; // 896 samples
|
||||
parameter DEBUG = 1; // Debug output control
|
||||
|
||||
// Calculate segments needed with overlap
|
||||
// For 3072 samples with 128 overlap:
|
||||
// Segments = ceil((3072 - 128) / 896) = ceil(2944/896) = 4
|
||||
parameter LONG_SEGMENTS = 4; // Now exactly 4 segments!
|
||||
parameter SHORT_SEGMENTS = 1; // 50 samples padded to 1024
|
||||
|
||||
// ========== FIXED INTERNAL SIGNALS ==========
|
||||
reg signed [31:0] pc_i, pc_q;
|
||||
reg pc_valid;
|
||||
|
||||
// Dual buffer for overlap-save
|
||||
reg signed [15:0] input_buffer_i [0:BUFFER_SIZE-1];
|
||||
reg signed [15:0] input_buffer_q [0:BUFFER_SIZE-1];
|
||||
reg [10:0] buffer_write_ptr;
|
||||
reg [10:0] buffer_read_ptr;
|
||||
reg buffer_has_data;
|
||||
reg buffer_processing;
|
||||
reg [15:0] chirp_samples_collected;
|
||||
|
||||
// State machine
|
||||
reg [3:0] state;
|
||||
localparam ST_IDLE = 0;
|
||||
localparam ST_COLLECT_DATA = 1;
|
||||
localparam ST_ZERO_PAD = 2;
|
||||
localparam ST_WAIT_REF = 3;
|
||||
localparam ST_PROCESSING = 4;
|
||||
localparam ST_WAIT_FFT = 5;
|
||||
localparam ST_OUTPUT = 6;
|
||||
localparam ST_NEXT_SEGMENT = 7;
|
||||
|
||||
// Segment tracking
|
||||
reg [2:0] current_segment; // 0-3
|
||||
reg [2:0] total_segments;
|
||||
reg segment_done;
|
||||
reg chirp_complete;
|
||||
|
||||
// Microcontroller sync detection
|
||||
reg mc_new_chirp_prev, mc_new_elevation_prev, mc_new_azimuth_prev;
|
||||
wire chirp_start_pulse = mc_new_chirp && !mc_new_chirp_prev;
|
||||
wire elevation_change_pulse = mc_new_elevation && !mc_new_elevation_prev;
|
||||
wire azimuth_change_pulse = mc_new_azimuth && !mc_new_azimuth_prev;
|
||||
|
||||
// Processing chain signals
|
||||
wire [15:0] fft_pc_i, fft_pc_q;
|
||||
wire fft_pc_valid;
|
||||
wire [3:0] fft_chain_state;
|
||||
|
||||
// Buffer for FFT input
|
||||
reg [15:0] fft_input_i, fft_input_q;
|
||||
reg fft_input_valid;
|
||||
reg fft_start;
|
||||
|
||||
// ========== SAMPLE ADDRESS OUTPUT ==========
|
||||
assign sample_addr_out = buffer_read_ptr;
|
||||
|
||||
// ========== MICROCONTROLLER SYNC ==========
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
mc_new_chirp_prev <= 1'b0;
|
||||
mc_new_elevation_prev <= 1'b0;
|
||||
mc_new_azimuth_prev <= 1'b0;
|
||||
end else begin
|
||||
mc_new_chirp_prev <= mc_new_chirp;
|
||||
mc_new_elevation_prev <= mc_new_elevation;
|
||||
mc_new_azimuth_prev <= mc_new_azimuth;
|
||||
end
|
||||
end
|
||||
|
||||
// ========== BUFFER INITIALIZATION ==========
|
||||
integer buf_init;
|
||||
initial begin
|
||||
for (buf_init = 0; buf_init < BUFFER_SIZE; buf_init = buf_init + 1) begin
|
||||
input_buffer_i[buf_init] = 16'd0;
|
||||
input_buffer_q[buf_init] = 16'd0;
|
||||
end
|
||||
end
|
||||
|
||||
// ========== FIXED STATE MACHINE WITH OVERLAP-SAVE ==========
|
||||
integer i;
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
state <= ST_IDLE;
|
||||
buffer_write_ptr <= 0;
|
||||
buffer_read_ptr <= 0;
|
||||
buffer_has_data <= 0;
|
||||
buffer_processing <= 0;
|
||||
current_segment <= 0;
|
||||
segment_done <= 0;
|
||||
segment_request <= 0;
|
||||
mem_request <= 0;
|
||||
pc_valid <= 0;
|
||||
status <= 0;
|
||||
chirp_samples_collected <= 0;
|
||||
chirp_complete <= 0;
|
||||
fft_input_valid <= 0;
|
||||
fft_start <= 0;
|
||||
end else begin
|
||||
pc_valid <= 0;
|
||||
mem_request <= 0;
|
||||
fft_input_valid <= 0;
|
||||
|
||||
case (state)
|
||||
ST_IDLE: begin
|
||||
// Reset for new chirp
|
||||
buffer_write_ptr <= 0;
|
||||
buffer_read_ptr <= 0;
|
||||
buffer_has_data <= 0;
|
||||
buffer_processing <= 0;
|
||||
current_segment <= 0;
|
||||
segment_done <= 0;
|
||||
chirp_samples_collected <= 0;
|
||||
chirp_complete <= 0;
|
||||
|
||||
// Wait for chirp start from microcontroller
|
||||
if (chirp_start_pulse) begin
|
||||
state <= ST_COLLECT_DATA;
|
||||
total_segments <= use_long_chirp ? LONG_SEGMENTS[2:0] : SHORT_SEGMENTS[2:0];
|
||||
|
||||
$display("[MULTI_SEG_FIXED] Starting %s chirp, segments: %d",
|
||||
use_long_chirp ? "LONG" : "SHORT",
|
||||
use_long_chirp ? LONG_SEGMENTS : SHORT_SEGMENTS);
|
||||
$display("[MULTI_SEG_FIXED] Overlap: %d samples, Advance: %d samples",
|
||||
OVERLAP_SAMPLES, SEGMENT_ADVANCE);
|
||||
end
|
||||
end
|
||||
|
||||
ST_COLLECT_DATA: begin
|
||||
// Collect samples for current segment with overlap-save
|
||||
if (ddc_valid) begin
|
||||
// Store in buffer
|
||||
input_buffer_i[buffer_write_ptr] <= ddc_i[17:2] + ddc_i[1];
|
||||
input_buffer_q[buffer_write_ptr] <= ddc_q[17:2] + ddc_q[1];
|
||||
|
||||
buffer_write_ptr <= buffer_write_ptr + 1;
|
||||
chirp_samples_collected <= chirp_samples_collected + 1;
|
||||
|
||||
// Debug: Show first few samples
|
||||
if (chirp_samples_collected < 10 && buffer_write_ptr < 10) begin
|
||||
$display("[MULTI_SEG_FIXED] Store[%0d]: I=%h Q=%h",
|
||||
buffer_write_ptr,
|
||||
ddc_i[17:2] + ddc_i[1],
|
||||
ddc_q[17:2] + ddc_q[1]);
|
||||
end
|
||||
|
||||
// Check conditions based on chirp type
|
||||
if (use_long_chirp) begin
|
||||
// LONG CHIRP: Process when we have SEGMENT_ADVANCE new samples
|
||||
// (buffer contains overlap from previous segment + new data)
|
||||
|
||||
// Check if we have enough NEW data to process
|
||||
if (buffer_write_ptr >= SEGMENT_ADVANCE) begin
|
||||
buffer_has_data <= 1;
|
||||
state <= ST_WAIT_REF;
|
||||
segment_request <= current_segment[1:0]; // Use lower 2 bits
|
||||
mem_request <= 1;
|
||||
|
||||
$display("[MULTI_SEG_FIXED] Segment %d ready: %d samples collected",
|
||||
current_segment, chirp_samples_collected);
|
||||
end
|
||||
|
||||
// Check if end of chirp reached
|
||||
if (chirp_samples_collected >= LONG_CHIRP_SAMPLES - 1) begin
|
||||
chirp_complete <= 1;
|
||||
$display("[MULTI_SEG_FIXED] End of long chirp reached");
|
||||
end
|
||||
end else begin
|
||||
// SHORT CHIRP: Only 50 samples, then zero-pad
|
||||
if (chirp_samples_collected >= SHORT_CHIRP_SAMPLES - 1) begin
|
||||
state <= ST_ZERO_PAD;
|
||||
$display("[MULTI_SEG_FIXED] Short chirp: collected %d samples, starting zero-pad",
|
||||
chirp_samples_collected + 1);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ST_ZERO_PAD: begin
|
||||
// For short chirp: zero-pad remaining buffer
|
||||
input_buffer_i[buffer_write_ptr] <= 16'd0;
|
||||
input_buffer_q[buffer_write_ptr] <= 16'd0;
|
||||
buffer_write_ptr <= buffer_write_ptr + 1;
|
||||
|
||||
if (buffer_write_ptr >= BUFFER_SIZE - 1) begin
|
||||
// Done zero-padding
|
||||
buffer_has_data <= 1;
|
||||
buffer_write_ptr <= 0;
|
||||
state <= ST_WAIT_REF;
|
||||
segment_request <= 0; // Only one segment for short chirp
|
||||
mem_request <= 1;
|
||||
$display("[MULTI_SEG_FIXED] Zero-pad complete, buffer full");
|
||||
end
|
||||
end
|
||||
|
||||
ST_WAIT_REF: begin
|
||||
// Wait for memory to provide reference coefficients
|
||||
if (mem_ready) begin
|
||||
// Start processing
|
||||
buffer_processing <= 1;
|
||||
buffer_read_ptr <= 0;
|
||||
fft_start <= 1;
|
||||
state <= ST_PROCESSING;
|
||||
|
||||
$display("[MULTI_SEG_FIXED] Reference ready, starting processing segment %d",
|
||||
current_segment);
|
||||
end
|
||||
end
|
||||
|
||||
ST_PROCESSING: begin
|
||||
// Feed data to FFT chain
|
||||
if ((buffer_processing) && (buffer_read_ptr < BUFFER_SIZE)) begin
|
||||
// 1. Feed ADC data to FFT
|
||||
fft_input_i <= input_buffer_i[buffer_read_ptr];
|
||||
fft_input_q <= input_buffer_q[buffer_read_ptr];
|
||||
fft_input_valid <= 1;
|
||||
|
||||
// 2. Request corresponding reference sample
|
||||
mem_request <= 1'b1;
|
||||
|
||||
// Debug every 100 samples
|
||||
if (buffer_read_ptr % 100 == 0) begin
|
||||
$display("[MULTI_SEG_FIXED] Processing[%0d]: ADC I=%h Q=%h",
|
||||
buffer_read_ptr,
|
||||
input_buffer_i[buffer_read_ptr],
|
||||
input_buffer_q[buffer_read_ptr]);
|
||||
end
|
||||
|
||||
buffer_read_ptr <= buffer_read_ptr + 1;
|
||||
|
||||
end else if (buffer_read_ptr >= BUFFER_SIZE) begin
|
||||
// Done feeding buffer
|
||||
fft_input_valid <= 0;
|
||||
mem_request <= 0;
|
||||
buffer_processing <= 0;
|
||||
buffer_has_data <= 0;
|
||||
state <= ST_WAIT_FFT; // CRITICAL: Wait for FFT completion
|
||||
|
||||
$display("[MULTI_SEG_FIXED] Finished feeding %d samples to FFT, waiting...",
|
||||
BUFFER_SIZE);
|
||||
end
|
||||
end
|
||||
|
||||
ST_WAIT_FFT: begin
|
||||
// Wait for the processing chain to complete (2159 cycles latency)
|
||||
if (fft_pc_valid) begin
|
||||
state <= ST_OUTPUT;
|
||||
$display("[MULTI_SEG_FIXED] FFT processing complete for segment %d",
|
||||
current_segment);
|
||||
end
|
||||
end
|
||||
|
||||
ST_OUTPUT: begin
|
||||
// Store FFT output
|
||||
pc_i <= fft_pc_i;
|
||||
pc_q <= fft_pc_q;
|
||||
pc_valid <= 1;
|
||||
segment_done <= 1;
|
||||
|
||||
$display("[MULTI_SEG_FIXED] Output segment %d: I=%h Q=%h",
|
||||
current_segment, fft_pc_i, fft_pc_q);
|
||||
|
||||
// Check if we need more segments
|
||||
if (current_segment < total_segments - 1 || !chirp_complete) begin
|
||||
state <= ST_NEXT_SEGMENT;
|
||||
end else begin
|
||||
// All segments complete
|
||||
state <= ST_IDLE;
|
||||
$display("[MULTI_SEG_FIXED] All %d segments complete",
|
||||
total_segments);
|
||||
end
|
||||
end
|
||||
|
||||
ST_NEXT_SEGMENT: begin
|
||||
// Prepare for next segment with OVERLAP-SAVE
|
||||
current_segment <= current_segment + 1;
|
||||
segment_done <= 0;
|
||||
|
||||
if (use_long_chirp) begin
|
||||
// OVERLAP-SAVE: Keep last OVERLAP_SAMPLES for next segment
|
||||
// Shift data in buffer to preserve overlap
|
||||
|
||||
for (i = 0; i < OVERLAP_SAMPLES; i = i + 1) begin
|
||||
input_buffer_i[i] <= input_buffer_i[i + SEGMENT_ADVANCE];
|
||||
input_buffer_q[i] <= input_buffer_q[i + SEGMENT_ADVANCE];
|
||||
end
|
||||
|
||||
// Start writing after the overlap
|
||||
buffer_write_ptr <= OVERLAP_SAMPLES;
|
||||
|
||||
$display("[MULTI_SEG_FIXED] Overlap-save: kept %d samples, write_ptr=%d",
|
||||
OVERLAP_SAMPLES, OVERLAP_SAMPLES);
|
||||
end else begin
|
||||
// Short chirp: only one segment
|
||||
buffer_write_ptr <= 0;
|
||||
end
|
||||
|
||||
// Continue collecting or finish
|
||||
if (!chirp_complete) begin
|
||||
state <= ST_COLLECT_DATA;
|
||||
$display("[MULTI_SEG_FIXED] Starting segment %d/%d",
|
||||
current_segment + 1, total_segments);
|
||||
end else begin
|
||||
state <= ST_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
// Update status
|
||||
status <= {state[2:0], use_long_chirp};
|
||||
end
|
||||
end
|
||||
|
||||
// ========== PROCESSING CHAIN INSTANTIATION ==========
|
||||
matched_filter_processing_chain m_f_p_c(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
|
||||
// Input ADC Data
|
||||
.adc_data_i(fft_input_i),
|
||||
.adc_data_q(fft_input_q),
|
||||
.adc_valid(fft_input_valid),// && buffer_processing),
|
||||
|
||||
// Chirp Selection
|
||||
.chirp_counter(chirp_counter),
|
||||
|
||||
// Reference Chirp Memory Interfaces
|
||||
.long_chirp_real(long_chirp_real),
|
||||
.long_chirp_imag(long_chirp_imag),
|
||||
.short_chirp_real(short_chirp_real),
|
||||
.short_chirp_imag(short_chirp_imag),
|
||||
|
||||
// Output
|
||||
.range_profile_i(fft_pc_i),
|
||||
.range_profile_q(fft_pc_q),
|
||||
.range_profile_valid(fft_pc_valid),
|
||||
|
||||
// Status
|
||||
.chain_state(fft_chain_state)
|
||||
);
|
||||
|
||||
// ========== DEBUG MONITOR ==========
|
||||
reg [31:0] dbg_cycles;
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
dbg_cycles <= 0;
|
||||
end else begin
|
||||
dbg_cycles <= dbg_cycles + 1;
|
||||
|
||||
// Monitor state transitions
|
||||
if (dbg_cycles % 1000 == 0 && state != ST_IDLE) begin
|
||||
$display("[MULTI_SEG_MONITOR @%0d] state=%0d, segment=%0d/%0d, samples=%0d",
|
||||
dbg_cycles, state, current_segment, total_segments,
|
||||
chirp_samples_collected);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ========== OUTPUT CONNECTIONS ==========
|
||||
assign pc_i_w = fft_pc_i;
|
||||
assign pc_q_w = fft_pc_q;
|
||||
assign pc_valid_w = fft_pc_valid;
|
||||
|
||||
endmodule
|
||||
117
9_Firmware/9_2_FPGA/nco_400m_enhanced.v
Normal file
117
9_Firmware/9_2_FPGA/nco_400m_enhanced.v
Normal file
@@ -0,0 +1,117 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module nco_400m_enhanced (
|
||||
input wire clk_400m,
|
||||
input wire reset_n,
|
||||
input wire [31:0] frequency_tuning_word,
|
||||
input wire phase_valid,
|
||||
input wire [15:0] phase_offset,
|
||||
output reg signed [15:0] sin_out,
|
||||
output reg signed [15:0] cos_out,
|
||||
output reg dds_ready
|
||||
);
|
||||
|
||||
// Phase accumulator with registered outputs for better timing
|
||||
reg [31:0] phase_accumulator;
|
||||
reg [31:0] phase_accumulator_reg;
|
||||
reg [31:0] phase_with_offset;
|
||||
reg phase_valid_delayed;
|
||||
|
||||
// Use only the top 8 bits for LUT addressing (256-entry LUT equivalent)
|
||||
wire [7:0] lut_address = phase_with_offset[31:24];
|
||||
|
||||
// Quarter-wave sine LUT (0-90 degrees only)
|
||||
reg [15:0] sin_lut [0:63]; // 64 entries for 0-90 degrees
|
||||
|
||||
// Initialize sine LUT
|
||||
integer lut_init_i;
|
||||
initial begin
|
||||
for (lut_init_i = 0; lut_init_i < 64; lut_init_i = lut_init_i + 1) begin
|
||||
sin_lut[lut_init_i] = 16'h0000;
|
||||
end
|
||||
|
||||
// Initialize quarter-wave sine LUT (0-90 degrees)
|
||||
sin_lut[0] = 16'h0000; sin_lut[1] = 16'h0324; sin_lut[2] = 16'h0647; sin_lut[3] = 16'h096A;
|
||||
sin_lut[4] = 16'h0C8B; sin_lut[5] = 16'h0FA9; sin_lut[6] = 16'h12C4; sin_lut[7] = 16'h15DB;
|
||||
sin_lut[8] = 16'h18EC; sin_lut[9] = 16'h1BF8; sin_lut[10] = 16'h1EFC; sin_lut[11] = 16'h21F8;
|
||||
sin_lut[12] = 16'h24EB; sin_lut[13] = 16'h27D4; sin_lut[14] = 16'h2AB1; sin_lut[15] = 16'h2D82;
|
||||
sin_lut[16] = 16'h3045; sin_lut[17] = 16'h32F9; sin_lut[18] = 16'h359D; sin_lut[19] = 16'h3830;
|
||||
sin_lut[20] = 16'h3AB1; sin_lut[21] = 16'h3D1E; sin_lut[22] = 16'h3F76; sin_lut[23] = 16'h41B8;
|
||||
sin_lut[24] = 16'h43E3; sin_lut[25] = 16'h45F5; sin_lut[26] = 16'h47EE; sin_lut[27] = 16'h49CD;
|
||||
sin_lut[28] = 16'h4B90; sin_lut[29] = 16'h4D37; sin_lut[30] = 16'h4EC1; sin_lut[31] = 16'h502D;
|
||||
sin_lut[32] = 16'h517A; sin_lut[33] = 16'h52A8; sin_lut[34] = 16'h53B6; sin_lut[35] = 16'h54A4;
|
||||
sin_lut[36] = 16'h5572; sin_lut[37] = 16'h561F; sin_lut[38] = 16'h56AA; sin_lut[39] = 16'h5715;
|
||||
sin_lut[40] = 16'h575E; sin_lut[41] = 16'h5785; sin_lut[42] = 16'h578B; sin_lut[43] = 16'h576E;
|
||||
sin_lut[44] = 16'h5730; sin_lut[45] = 16'h56D0; sin_lut[46] = 16'h564E; sin_lut[47] = 16'h55AB;
|
||||
sin_lut[48] = 16'h54E7; sin_lut[49] = 16'h5403; sin_lut[50] = 16'h52FE; sin_lut[51] = 16'h51DA;
|
||||
sin_lut[52] = 16'h5096; sin_lut[53] = 16'h4F34; sin_lut[54] = 16'h4DB4; sin_lut[55] = 16'h4C17;
|
||||
sin_lut[56] = 16'h4A5E; sin_lut[57] = 16'h4889; sin_lut[58] = 16'h4699; sin_lut[59] = 16'h448F;
|
||||
sin_lut[60] = 16'h426B; sin_lut[61] = 16'h402F; sin_lut[62] = 16'h3DDB; sin_lut[63] = 16'h3B71;
|
||||
end
|
||||
|
||||
// Quadrant determination
|
||||
wire [1:0] quadrant = lut_address[7:6]; // 00: Q1, 01: Q2, 10: Q3, 11: Q4
|
||||
wire [5:0] lut_index = (quadrant[1] ? ~lut_address[5:0] : lut_address[5:0]); // Mirror for Q2/Q3
|
||||
|
||||
// Sine and cosine calculation with quadrant mapping
|
||||
wire [15:0] sin_abs = sin_lut[lut_index];
|
||||
wire [15:0] cos_abs = sin_lut[63 - lut_index]; // Cosine is phase-shifted sine
|
||||
|
||||
// Pipeline stage for better timing
|
||||
always @(posedge clk_400m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
phase_accumulator <= 32'h00000000;
|
||||
phase_accumulator_reg <= 32'h00000000;
|
||||
phase_with_offset <= 32'h00000000;
|
||||
phase_valid_delayed <= 1'b0;
|
||||
dds_ready <= 1'b0;
|
||||
sin_out <= 16'h0000;
|
||||
cos_out <= 16'h7FFF;
|
||||
end else begin
|
||||
phase_valid_delayed <= phase_valid;
|
||||
|
||||
if (phase_valid) begin
|
||||
// Update phase accumulator with dithered frequency tuning word
|
||||
phase_accumulator <= phase_accumulator + frequency_tuning_word;
|
||||
phase_accumulator_reg <= phase_accumulator;
|
||||
|
||||
// Apply phase offset
|
||||
phase_with_offset <= phase_accumulator + {phase_offset, 16'b0};
|
||||
dds_ready <= 1'b1;
|
||||
end else begin
|
||||
dds_ready <= 1'b0;
|
||||
end
|
||||
|
||||
// Generate outputs with one cycle delay for pipelining
|
||||
if (phase_valid_delayed) begin
|
||||
// Calculate sine and cosine with proper quadrant signs
|
||||
case (quadrant)
|
||||
2'b00: begin // Quadrant I: sin+, cos+
|
||||
sin_out <= sin_abs;
|
||||
cos_out <= cos_abs;
|
||||
end
|
||||
2'b01: begin // Quadrant II: sin+, cos-
|
||||
sin_out <= sin_abs;
|
||||
cos_out <= -cos_abs;
|
||||
end
|
||||
2'b10: begin // Quadrant III: sin-, cos-
|
||||
sin_out <= -sin_abs;
|
||||
cos_out <= -cos_abs;
|
||||
end
|
||||
2'b11: begin // Quadrant IV: sin-, cos+
|
||||
sin_out <= -sin_abs;
|
||||
cos_out <= cos_abs;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Add this to ensure LUT is properly loaded:
|
||||
initial begin
|
||||
// Wait a small amount of time for LUT initialization
|
||||
#10;
|
||||
$display("NCO: Sine LUT initialized with %0d entries", 64);
|
||||
end
|
||||
|
||||
endmodule
|
||||
801
9_Firmware/9_2_FPGA/plfm_chirp_controller.v
Normal file
801
9_Firmware/9_2_FPGA/plfm_chirp_controller.v
Normal file
@@ -0,0 +1,801 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module plfm_chirp_controller_enhanced (
|
||||
input wire clk_120m,
|
||||
input wire clk_100m,
|
||||
input wire reset_n,
|
||||
input wire new_chirp,
|
||||
input wire new_elevation,
|
||||
input wire new_azimuth,
|
||||
input wire mixers_enable,
|
||||
output reg [7:0] chirp_data,
|
||||
output reg chirp_valid,
|
||||
output wire new_chirp_frame,
|
||||
output reg chirp_done,
|
||||
output reg rf_switch_ctrl,
|
||||
output wire rx_mixer_en,
|
||||
output wire tx_mixer_en,
|
||||
output wire adar_tx_load_1,
|
||||
output wire adar_rx_load_1,
|
||||
output wire adar_tx_load_2,
|
||||
output wire adar_rx_load_2,
|
||||
output wire adar_tx_load_3,
|
||||
output wire adar_rx_load_3,
|
||||
output wire adar_tx_load_4,
|
||||
output wire adar_rx_load_4,
|
||||
output reg adar_tr_1,
|
||||
output reg adar_tr_2,
|
||||
output reg adar_tr_3,
|
||||
output reg adar_tr_4,
|
||||
output reg [5:0] chirp_counter,
|
||||
output reg [5:0] elevation_counter,
|
||||
output reg [5:0] azimuth_counter
|
||||
);
|
||||
|
||||
// Chirp parameters
|
||||
parameter F_START = 30000000; // 30 MHz (starting frequency)
|
||||
parameter F_END = 10000000; // 10 MHz (ending frequency)
|
||||
parameter FS = 120000000; // 120 MHz
|
||||
|
||||
// Timing parameters
|
||||
parameter T1_SAMPLES = 3600; // 30us at 120MHz
|
||||
parameter T1_RADAR_LISTENING = 16440; //137us at 120MHz
|
||||
parameter T2_SAMPLES = 60; // 0.5us at 120MHz
|
||||
parameter T2_RADAR_LISTENING = 20940; //174.5us at 120MHz
|
||||
parameter GUARD_SAMPLES = 21048; // 175.4us at 120MHz
|
||||
|
||||
// Chirp and beam parameters
|
||||
parameter CHIRP_MAX = 32;
|
||||
parameter ELEVATION_MAX = 31;
|
||||
parameter AZIMUTH_MAX = 50;
|
||||
|
||||
// State parameters
|
||||
parameter IDLE = 3'b000;
|
||||
parameter LONG_CHIRP = 3'b001;
|
||||
parameter LONG_LISTEN = 3'b010;
|
||||
parameter GUARD_TIME = 3'b011;
|
||||
parameter SHORT_CHIRP = 3'b100;
|
||||
parameter SHORT_LISTEN = 3'b101;
|
||||
parameter DONE = 3'b110;
|
||||
|
||||
reg [2:0] current_state;
|
||||
reg [2:0] next_state;
|
||||
|
||||
// Control registers
|
||||
reg [15:0] sample_counter;
|
||||
|
||||
// Edge detection for input signals
|
||||
wire chirp__toggling, elevation__toggling, azimuth__toggling;
|
||||
|
||||
// LUTs for chirp waveforms
|
||||
reg [7:0] long_chirp_lut [0:3599]; // T1_SAMPLES-1
|
||||
reg [7:0] short_chirp_lut [0:59]; // T2_SAMPLES-1
|
||||
|
||||
// Edge detection
|
||||
assign chirp__toggling = new_chirp;
|
||||
assign elevation__toggling = new_elevation;
|
||||
assign azimuth__toggling = new_azimuth;
|
||||
assign new_chirp_frame = (current_state == IDLE && next_state == LONG_CHIRP);
|
||||
|
||||
// Mixers Enabling
|
||||
assign rx_mixer_en = mixers_enable;
|
||||
assign tx_mixer_en = mixers_enable;
|
||||
|
||||
// ADTR1000 pull to ground tx and rx load pins if not used
|
||||
assign adar_tx_load_1 = 1'b0;
|
||||
assign adar_rx_load_1 = 1'b0;
|
||||
assign adar_tx_load_2 = 1'b0;
|
||||
assign adar_rx_load_2 = 1'b0;
|
||||
assign adar_tx_load_3 = 1'b0;
|
||||
assign adar_rx_load_3 = 1'b0;
|
||||
assign adar_tx_load_4 = 1'b0;
|
||||
assign adar_rx_load_4 = 1'b0;
|
||||
|
||||
|
||||
|
||||
|
||||
// LUT Initialization - Complete short chirp LUT
|
||||
// Long PLFM chirp LUT (30us, 30MHz to 10MHz)
|
||||
initial begin
|
||||
long_chirp_lut[ 0] = 8'd255; long_chirp_lut[ 1] = 8'd237; long_chirp_lut[ 2] = 8'd191; long_chirp_lut[ 3] = 8'd127; long_chirp_lut[ 4] = 8'd 64; long_chirp_lut[ 5] = 8'd 17; long_chirp_lut[ 6] = 8'd 1; long_chirp_lut[ 7] = 8'd 18;
|
||||
long_chirp_lut[ 8] = 8'd 65; long_chirp_lut[ 9] = 8'd129; long_chirp_lut[ 10] = 8'd193; long_chirp_lut[ 11] = 8'd239; long_chirp_lut[ 12] = 8'd254; long_chirp_lut[ 13] = 8'd236; long_chirp_lut[ 14] = 8'd188; long_chirp_lut[ 15] = 8'd123;
|
||||
long_chirp_lut[ 16] = 8'd 60; long_chirp_lut[ 17] = 8'd 15; long_chirp_lut[ 18] = 8'd 1; long_chirp_lut[ 19] = 8'd 21; long_chirp_lut[ 20] = 8'd 71; long_chirp_lut[ 21] = 8'd136; long_chirp_lut[ 22] = 8'd199; long_chirp_lut[ 23] = 8'd242;
|
||||
long_chirp_lut[ 24] = 8'd254; long_chirp_lut[ 25] = 8'd231; long_chirp_lut[ 26] = 8'd180; long_chirp_lut[ 27] = 8'd114; long_chirp_lut[ 28] = 8'd 52; long_chirp_lut[ 29] = 8'd 11; long_chirp_lut[ 30] = 8'd 2; long_chirp_lut[ 31] = 8'd 27;
|
||||
long_chirp_lut[ 32] = 8'd 81; long_chirp_lut[ 33] = 8'd148; long_chirp_lut[ 34] = 8'd209; long_chirp_lut[ 35] = 8'd247; long_chirp_lut[ 36] = 8'd252; long_chirp_lut[ 37] = 8'd223; long_chirp_lut[ 38] = 8'd167; long_chirp_lut[ 39] = 8'd100;
|
||||
long_chirp_lut[ 40] = 8'd 40; long_chirp_lut[ 41] = 8'd 5; long_chirp_lut[ 42] = 8'd 5; long_chirp_lut[ 43] = 8'd 38; long_chirp_lut[ 44] = 8'd 97; long_chirp_lut[ 45] = 8'd164; long_chirp_lut[ 46] = 8'd221; long_chirp_lut[ 47] = 8'd252;
|
||||
long_chirp_lut[ 48] = 8'd247; long_chirp_lut[ 49] = 8'd209; long_chirp_lut[ 50] = 8'd148; long_chirp_lut[ 51] = 8'd 81; long_chirp_lut[ 52] = 8'd 27; long_chirp_lut[ 53] = 8'd 1; long_chirp_lut[ 54] = 8'd 12; long_chirp_lut[ 55] = 8'd 55;
|
||||
long_chirp_lut[ 56] = 8'd119; long_chirp_lut[ 57] = 8'd185; long_chirp_lut[ 58] = 8'd235; long_chirp_lut[ 59] = 8'd254; long_chirp_lut[ 60] = 8'd237; long_chirp_lut[ 61] = 8'd189; long_chirp_lut[ 62] = 8'd123; long_chirp_lut[ 63] = 8'd 58;
|
||||
long_chirp_lut[ 64] = 8'd 13; long_chirp_lut[ 65] = 8'd 1; long_chirp_lut[ 66] = 8'd 25; long_chirp_lut[ 67] = 8'd 79; long_chirp_lut[ 68] = 8'd146; long_chirp_lut[ 69] = 8'd209; long_chirp_lut[ 70] = 8'd247; long_chirp_lut[ 71] = 8'd252;
|
||||
long_chirp_lut[ 72] = 8'd220; long_chirp_lut[ 73] = 8'd162; long_chirp_lut[ 74] = 8'd 93; long_chirp_lut[ 75] = 8'd 35; long_chirp_lut[ 76] = 8'd 3; long_chirp_lut[ 77] = 8'd 8; long_chirp_lut[ 78] = 8'd 47; long_chirp_lut[ 79] = 8'd110;
|
||||
long_chirp_lut[ 80] = 8'd178; long_chirp_lut[ 81] = 8'd231; long_chirp_lut[ 82] = 8'd254; long_chirp_lut[ 83] = 8'd240; long_chirp_lut[ 84] = 8'd193; long_chirp_lut[ 85] = 8'd127; long_chirp_lut[ 86] = 8'd 61; long_chirp_lut[ 87] = 8'd 14;
|
||||
long_chirp_lut[ 88] = 8'd 1; long_chirp_lut[ 89] = 8'd 25; long_chirp_lut[ 90] = 8'd 79; long_chirp_lut[ 91] = 8'd147; long_chirp_lut[ 92] = 8'd210; long_chirp_lut[ 93] = 8'd248; long_chirp_lut[ 94] = 8'd251; long_chirp_lut[ 95] = 8'd217;
|
||||
long_chirp_lut[ 96] = 8'd157; long_chirp_lut[ 97] = 8'd 87; long_chirp_lut[ 98] = 8'd 30; long_chirp_lut[ 99] = 8'd 2; long_chirp_lut[ 100] = 8'd 11; long_chirp_lut[ 101] = 8'd 55; long_chirp_lut[ 102] = 8'd120; long_chirp_lut[ 103] = 8'd188;
|
||||
long_chirp_lut[ 104] = 8'd238; long_chirp_lut[ 105] = 8'd254; long_chirp_lut[ 106] = 8'd233; long_chirp_lut[ 107] = 8'd180; long_chirp_lut[ 108] = 8'd112; long_chirp_lut[ 109] = 8'd 48; long_chirp_lut[ 110] = 8'd 8; long_chirp_lut[ 111] = 8'd 4;
|
||||
long_chirp_lut[ 112] = 8'd 37; long_chirp_lut[ 113] = 8'd 98; long_chirp_lut[ 114] = 8'd167; long_chirp_lut[ 115] = 8'd225; long_chirp_lut[ 116] = 8'd253; long_chirp_lut[ 117] = 8'd243; long_chirp_lut[ 118] = 8'd198; long_chirp_lut[ 119] = 8'd132;
|
||||
long_chirp_lut[ 120] = 8'd 64; long_chirp_lut[ 121] = 8'd 15; long_chirp_lut[ 122] = 8'd 1; long_chirp_lut[ 123] = 8'd 25; long_chirp_lut[ 124] = 8'd 80; long_chirp_lut[ 125] = 8'd150; long_chirp_lut[ 126] = 8'd213; long_chirp_lut[ 127] = 8'd250;
|
||||
long_chirp_lut[ 128] = 8'd249; long_chirp_lut[ 129] = 8'd211; long_chirp_lut[ 130] = 8'd148; long_chirp_lut[ 131] = 8'd 78; long_chirp_lut[ 132] = 8'd 23; long_chirp_lut[ 133] = 8'd 1; long_chirp_lut[ 134] = 8'd 17; long_chirp_lut[ 135] = 8'd 68;
|
||||
long_chirp_lut[ 136] = 8'd137; long_chirp_lut[ 137] = 8'd203; long_chirp_lut[ 138] = 8'd246; long_chirp_lut[ 139] = 8'd252; long_chirp_lut[ 140] = 8'd220; long_chirp_lut[ 141] = 8'd159; long_chirp_lut[ 142] = 8'd 88; long_chirp_lut[ 143] = 8'd 30;
|
||||
long_chirp_lut[ 144] = 8'd 2; long_chirp_lut[ 145] = 8'd 13; long_chirp_lut[ 146] = 8'd 60; long_chirp_lut[ 147] = 8'd128; long_chirp_lut[ 148] = 8'd196; long_chirp_lut[ 149] = 8'd243; long_chirp_lut[ 150] = 8'd253; long_chirp_lut[ 151] = 8'd225;
|
||||
long_chirp_lut[ 152] = 8'd166; long_chirp_lut[ 153] = 8'd 94; long_chirp_lut[ 154] = 8'd 34; long_chirp_lut[ 155] = 8'd 2; long_chirp_lut[ 156] = 8'd 10; long_chirp_lut[ 157] = 8'd 55; long_chirp_lut[ 158] = 8'd123; long_chirp_lut[ 159] = 8'd192;
|
||||
long_chirp_lut[ 160] = 8'd241; long_chirp_lut[ 161] = 8'd254; long_chirp_lut[ 162] = 8'd227; long_chirp_lut[ 163] = 8'd168; long_chirp_lut[ 164] = 8'd 96; long_chirp_lut[ 165] = 8'd 35; long_chirp_lut[ 166] = 8'd 3; long_chirp_lut[ 167] = 8'd 10;
|
||||
long_chirp_lut[ 168] = 8'd 55; long_chirp_lut[ 169] = 8'd123; long_chirp_lut[ 170] = 8'd193; long_chirp_lut[ 171] = 8'd241; long_chirp_lut[ 172] = 8'd254; long_chirp_lut[ 173] = 8'd226; long_chirp_lut[ 174] = 8'd166; long_chirp_lut[ 175] = 8'd 94;
|
||||
long_chirp_lut[ 176] = 8'd 33; long_chirp_lut[ 177] = 8'd 2; long_chirp_lut[ 178] = 8'd 12; long_chirp_lut[ 179] = 8'd 58; long_chirp_lut[ 180] = 8'd128; long_chirp_lut[ 181] = 8'd197; long_chirp_lut[ 182] = 8'd244; long_chirp_lut[ 183] = 8'd253;
|
||||
long_chirp_lut[ 184] = 8'd222; long_chirp_lut[ 185] = 8'd160; long_chirp_lut[ 186] = 8'd 88; long_chirp_lut[ 187] = 8'd 28; long_chirp_lut[ 188] = 8'd 1; long_chirp_lut[ 189] = 8'd 15; long_chirp_lut[ 190] = 8'd 66; long_chirp_lut[ 191] = 8'd136;
|
||||
long_chirp_lut[ 192] = 8'd204; long_chirp_lut[ 193] = 8'd247; long_chirp_lut[ 194] = 8'd251; long_chirp_lut[ 195] = 8'd214; long_chirp_lut[ 196] = 8'd149; long_chirp_lut[ 197] = 8'd 77; long_chirp_lut[ 198] = 8'd 21; long_chirp_lut[ 199] = 8'd 1;
|
||||
long_chirp_lut[ 200] = 8'd 21; long_chirp_lut[ 201] = 8'd 77; long_chirp_lut[ 202] = 8'd150; long_chirp_lut[ 203] = 8'd215; long_chirp_lut[ 204] = 8'd251; long_chirp_lut[ 205] = 8'd247; long_chirp_lut[ 206] = 8'd203; long_chirp_lut[ 207] = 8'd134;
|
||||
long_chirp_lut[ 208] = 8'd 63; long_chirp_lut[ 209] = 8'd 13; long_chirp_lut[ 210] = 8'd 2; long_chirp_lut[ 211] = 8'd 32; long_chirp_lut[ 212] = 8'd 94; long_chirp_lut[ 213] = 8'd167; long_chirp_lut[ 214] = 8'd227; long_chirp_lut[ 215] = 8'd254;
|
||||
long_chirp_lut[ 216] = 8'd239; long_chirp_lut[ 217] = 8'd186; long_chirp_lut[ 218] = 8'd114; long_chirp_lut[ 219] = 8'd 46; long_chirp_lut[ 220] = 8'd 6; long_chirp_lut[ 221] = 8'd 6; long_chirp_lut[ 222] = 8'd 47; long_chirp_lut[ 223] = 8'd115;
|
||||
long_chirp_lut[ 224] = 8'd187; long_chirp_lut[ 225] = 8'd240; long_chirp_lut[ 226] = 8'd254; long_chirp_lut[ 227] = 8'd226; long_chirp_lut[ 228] = 8'd164; long_chirp_lut[ 229] = 8'd 90; long_chirp_lut[ 230] = 8'd 29; long_chirp_lut[ 231] = 8'd 1;
|
||||
long_chirp_lut[ 232] = 8'd 16; long_chirp_lut[ 233] = 8'd 69; long_chirp_lut[ 234] = 8'd141; long_chirp_lut[ 235] = 8'd209; long_chirp_lut[ 236] = 8'd250; long_chirp_lut[ 237] = 8'd248; long_chirp_lut[ 238] = 8'd206; long_chirp_lut[ 239] = 8'd136;
|
||||
long_chirp_lut[ 240] = 8'd 64; long_chirp_lut[ 241] = 8'd 13; long_chirp_lut[ 242] = 8'd 2; long_chirp_lut[ 243] = 8'd 33; long_chirp_lut[ 244] = 8'd 97; long_chirp_lut[ 245] = 8'd171; long_chirp_lut[ 246] = 8'd231; long_chirp_lut[ 247] = 8'd254;
|
||||
long_chirp_lut[ 248] = 8'd235; long_chirp_lut[ 249] = 8'd178; long_chirp_lut[ 250] = 8'd104; long_chirp_lut[ 251] = 8'd 38; long_chirp_lut[ 252] = 8'd 3; long_chirp_lut[ 253] = 8'd 11; long_chirp_lut[ 254] = 8'd 60; long_chirp_lut[ 255] = 8'd132;
|
||||
long_chirp_lut[ 256] = 8'd202; long_chirp_lut[ 257] = 8'd247; long_chirp_lut[ 258] = 8'd250; long_chirp_lut[ 259] = 8'd211; long_chirp_lut[ 260] = 8'd142; long_chirp_lut[ 261] = 8'd 69; long_chirp_lut[ 262] = 8'd 15; long_chirp_lut[ 263] = 8'd 1;
|
||||
long_chirp_lut[ 264] = 8'd 31; long_chirp_lut[ 265] = 8'd 95; long_chirp_lut[ 266] = 8'd170; long_chirp_lut[ 267] = 8'd230; long_chirp_lut[ 268] = 8'd254; long_chirp_lut[ 269] = 8'd234; long_chirp_lut[ 270] = 8'd176; long_chirp_lut[ 271] = 8'd101;
|
||||
long_chirp_lut[ 272] = 8'd 35; long_chirp_lut[ 273] = 8'd 2; long_chirp_lut[ 274] = 8'd 13; long_chirp_lut[ 275] = 8'd 64; long_chirp_lut[ 276] = 8'd138; long_chirp_lut[ 277] = 8'd208; long_chirp_lut[ 278] = 8'd250; long_chirp_lut[ 279] = 8'd248;
|
||||
long_chirp_lut[ 280] = 8'd203; long_chirp_lut[ 281] = 8'd132; long_chirp_lut[ 282] = 8'd 59; long_chirp_lut[ 283] = 8'd 10; long_chirp_lut[ 284] = 8'd 3; long_chirp_lut[ 285] = 8'd 41; long_chirp_lut[ 286] = 8'd109; long_chirp_lut[ 287] = 8'd184;
|
||||
long_chirp_lut[ 288] = 8'd239; long_chirp_lut[ 289] = 8'd254; long_chirp_lut[ 290] = 8'd224; long_chirp_lut[ 291] = 8'd159; long_chirp_lut[ 292] = 8'd 83; long_chirp_lut[ 293] = 8'd 23; long_chirp_lut[ 294] = 8'd 1; long_chirp_lut[ 295] = 8'd 24;
|
||||
long_chirp_lut[ 296] = 8'd 84; long_chirp_lut[ 297] = 8'd161; long_chirp_lut[ 298] = 8'd225; long_chirp_lut[ 299] = 8'd254; long_chirp_lut[ 300] = 8'd237; long_chirp_lut[ 301] = 8'd181; long_chirp_lut[ 302] = 8'd105; long_chirp_lut[ 303] = 8'd 38;
|
||||
long_chirp_lut[ 304] = 8'd 2; long_chirp_lut[ 305] = 8'd 13; long_chirp_lut[ 306] = 8'd 65; long_chirp_lut[ 307] = 8'd139; long_chirp_lut[ 308] = 8'd210; long_chirp_lut[ 309] = 8'd251; long_chirp_lut[ 310] = 8'd246; long_chirp_lut[ 311] = 8'd199;
|
||||
long_chirp_lut[ 312] = 8'd125; long_chirp_lut[ 313] = 8'd 52; long_chirp_lut[ 314] = 8'd 7; long_chirp_lut[ 315] = 8'd 6; long_chirp_lut[ 316] = 8'd 50; long_chirp_lut[ 317] = 8'd122; long_chirp_lut[ 318] = 8'd196; long_chirp_lut[ 319] = 8'd245;
|
||||
long_chirp_lut[ 320] = 8'd251; long_chirp_lut[ 321] = 8'd211; long_chirp_lut[ 322] = 8'd141; long_chirp_lut[ 323] = 8'd 65; long_chirp_lut[ 324] = 8'd 13; long_chirp_lut[ 325] = 8'd 3; long_chirp_lut[ 326] = 8'd 39; long_chirp_lut[ 327] = 8'd108;
|
||||
long_chirp_lut[ 328] = 8'd184; long_chirp_lut[ 329] = 8'd240; long_chirp_lut[ 330] = 8'd253; long_chirp_lut[ 331] = 8'd220; long_chirp_lut[ 332] = 8'd153; long_chirp_lut[ 333] = 8'd 76; long_chirp_lut[ 334] = 8'd 18; long_chirp_lut[ 335] = 8'd 1;
|
||||
long_chirp_lut[ 336] = 8'd 31; long_chirp_lut[ 337] = 8'd 98; long_chirp_lut[ 338] = 8'd175; long_chirp_lut[ 339] = 8'd235; long_chirp_lut[ 340] = 8'd254; long_chirp_lut[ 341] = 8'd226; long_chirp_lut[ 342] = 8'd161; long_chirp_lut[ 343] = 8'd 83;
|
||||
long_chirp_lut[ 344] = 8'd 22; long_chirp_lut[ 345] = 8'd 1; long_chirp_lut[ 346] = 8'd 27; long_chirp_lut[ 347] = 8'd 91; long_chirp_lut[ 348] = 8'd169; long_chirp_lut[ 349] = 8'd232; long_chirp_lut[ 350] = 8'd254; long_chirp_lut[ 351] = 8'd229;
|
||||
long_chirp_lut[ 352] = 8'd166; long_chirp_lut[ 353] = 8'd 87; long_chirp_lut[ 354] = 8'd 24; long_chirp_lut[ 355] = 8'd 1; long_chirp_lut[ 356] = 8'd 25; long_chirp_lut[ 357] = 8'd 88; long_chirp_lut[ 358] = 8'd167; long_chirp_lut[ 359] = 8'd230;
|
||||
long_chirp_lut[ 360] = 8'd255; long_chirp_lut[ 361] = 8'd230; long_chirp_lut[ 362] = 8'd167; long_chirp_lut[ 363] = 8'd 88; long_chirp_lut[ 364] = 8'd 25; long_chirp_lut[ 365] = 8'd 1; long_chirp_lut[ 366] = 8'd 25; long_chirp_lut[ 367] = 8'd 89;
|
||||
long_chirp_lut[ 368] = 8'd168; long_chirp_lut[ 369] = 8'd231; long_chirp_lut[ 370] = 8'd254; long_chirp_lut[ 371] = 8'd229; long_chirp_lut[ 372] = 8'd164; long_chirp_lut[ 373] = 8'd 85; long_chirp_lut[ 374] = 8'd 23; long_chirp_lut[ 375] = 8'd 1;
|
||||
long_chirp_lut[ 376] = 8'd 28; long_chirp_lut[ 377] = 8'd 93; long_chirp_lut[ 378] = 8'd172; long_chirp_lut[ 379] = 8'd234; long_chirp_lut[ 380] = 8'd254; long_chirp_lut[ 381] = 8'd225; long_chirp_lut[ 382] = 8'd158; long_chirp_lut[ 383] = 8'd 79;
|
||||
long_chirp_lut[ 384] = 8'd 19; long_chirp_lut[ 385] = 8'd 1; long_chirp_lut[ 386] = 8'd 33; long_chirp_lut[ 387] = 8'd101; long_chirp_lut[ 388] = 8'd180; long_chirp_lut[ 389] = 8'd239; long_chirp_lut[ 390] = 8'd253; long_chirp_lut[ 391] = 8'd219;
|
||||
long_chirp_lut[ 392] = 8'd148; long_chirp_lut[ 393] = 8'd 70; long_chirp_lut[ 394] = 8'd 14; long_chirp_lut[ 395] = 8'd 3; long_chirp_lut[ 396] = 8'd 41; long_chirp_lut[ 397] = 8'd113; long_chirp_lut[ 398] = 8'd191; long_chirp_lut[ 399] = 8'd244;
|
||||
long_chirp_lut[ 400] = 8'd251; long_chirp_lut[ 401] = 8'd209; long_chirp_lut[ 402] = 8'd135; long_chirp_lut[ 403] = 8'd 58; long_chirp_lut[ 404] = 8'd 8; long_chirp_lut[ 405] = 8'd 6; long_chirp_lut[ 406] = 8'd 52; long_chirp_lut[ 407] = 8'd128;
|
||||
long_chirp_lut[ 408] = 8'd204; long_chirp_lut[ 409] = 8'd250; long_chirp_lut[ 410] = 8'd246; long_chirp_lut[ 411] = 8'd195; long_chirp_lut[ 412] = 8'd117; long_chirp_lut[ 413] = 8'd 43; long_chirp_lut[ 414] = 8'd 3; long_chirp_lut[ 415] = 8'd 13;
|
||||
long_chirp_lut[ 416] = 8'd 68; long_chirp_lut[ 417] = 8'd148; long_chirp_lut[ 418] = 8'd219; long_chirp_lut[ 419] = 8'd254; long_chirp_lut[ 420] = 8'd237; long_chirp_lut[ 421] = 8'd177; long_chirp_lut[ 422] = 8'd 97; long_chirp_lut[ 423] = 8'd 29;
|
||||
long_chirp_lut[ 424] = 8'd 1; long_chirp_lut[ 425] = 8'd 24; long_chirp_lut[ 426] = 8'd 89; long_chirp_lut[ 427] = 8'd170; long_chirp_lut[ 428] = 8'd233; long_chirp_lut[ 429] = 8'd254; long_chirp_lut[ 430] = 8'd224; long_chirp_lut[ 431] = 8'd154;
|
||||
long_chirp_lut[ 432] = 8'd 73; long_chirp_lut[ 433] = 8'd 15; long_chirp_lut[ 434] = 8'd 2; long_chirp_lut[ 435] = 8'd 41; long_chirp_lut[ 436] = 8'd115; long_chirp_lut[ 437] = 8'd194; long_chirp_lut[ 438] = 8'd246; long_chirp_lut[ 439] = 8'd250;
|
||||
long_chirp_lut[ 440] = 8'd203; long_chirp_lut[ 441] = 8'd126; long_chirp_lut[ 442] = 8'd 49; long_chirp_lut[ 443] = 8'd 5; long_chirp_lut[ 444] = 8'd 10; long_chirp_lut[ 445] = 8'd 64; long_chirp_lut[ 446] = 8'd144; long_chirp_lut[ 447] = 8'd217;
|
||||
long_chirp_lut[ 448] = 8'd253; long_chirp_lut[ 449] = 8'd237; long_chirp_lut[ 450] = 8'd176; long_chirp_lut[ 451] = 8'd 95; long_chirp_lut[ 452] = 8'd 27; long_chirp_lut[ 453] = 8'd 1; long_chirp_lut[ 454] = 8'd 27; long_chirp_lut[ 455] = 8'd 95;
|
||||
long_chirp_lut[ 456] = 8'd177; long_chirp_lut[ 457] = 8'd238; long_chirp_lut[ 458] = 8'd253; long_chirp_lut[ 459] = 8'd216; long_chirp_lut[ 460] = 8'd142; long_chirp_lut[ 461] = 8'd 62; long_chirp_lut[ 462] = 8'd 9; long_chirp_lut[ 463] = 8'd 6;
|
||||
long_chirp_lut[ 464] = 8'd 53; long_chirp_lut[ 465] = 8'd132; long_chirp_lut[ 466] = 8'd209; long_chirp_lut[ 467] = 8'd251; long_chirp_lut[ 468] = 8'd242; long_chirp_lut[ 469] = 8'd185; long_chirp_lut[ 470] = 8'd104; long_chirp_lut[ 471] = 8'd 32;
|
||||
long_chirp_lut[ 472] = 8'd 1; long_chirp_lut[ 473] = 8'd 23; long_chirp_lut[ 474] = 8'd 89; long_chirp_lut[ 475] = 8'd171; long_chirp_lut[ 476] = 8'd235; long_chirp_lut[ 477] = 8'd254; long_chirp_lut[ 478] = 8'd219; long_chirp_lut[ 479] = 8'd145;
|
||||
long_chirp_lut[ 480] = 8'd 64; long_chirp_lut[ 481] = 8'd 10; long_chirp_lut[ 482] = 8'd 5; long_chirp_lut[ 483] = 8'd 53; long_chirp_lut[ 484] = 8'd132; long_chirp_lut[ 485] = 8'd209; long_chirp_lut[ 486] = 8'd252; long_chirp_lut[ 487] = 8'd241;
|
||||
long_chirp_lut[ 488] = 8'd182; long_chirp_lut[ 489] = 8'd100; long_chirp_lut[ 490] = 8'd 29; long_chirp_lut[ 491] = 8'd 1; long_chirp_lut[ 492] = 8'd 26; long_chirp_lut[ 493] = 8'd 96; long_chirp_lut[ 494] = 8'd178; long_chirp_lut[ 495] = 8'd240;
|
||||
long_chirp_lut[ 496] = 8'd253; long_chirp_lut[ 497] = 8'd212; long_chirp_lut[ 498] = 8'd135; long_chirp_lut[ 499] = 8'd 55; long_chirp_lut[ 500] = 8'd 6; long_chirp_lut[ 501] = 8'd 9; long_chirp_lut[ 502] = 8'd 64; long_chirp_lut[ 503] = 8'd146;
|
||||
long_chirp_lut[ 504] = 8'd220; long_chirp_lut[ 505] = 8'd254; long_chirp_lut[ 506] = 8'd233; long_chirp_lut[ 507] = 8'd167; long_chirp_lut[ 508] = 8'd 83; long_chirp_lut[ 509] = 8'd 19; long_chirp_lut[ 510] = 8'd 2; long_chirp_lut[ 511] = 8'd 39;
|
||||
long_chirp_lut[ 512] = 8'd115; long_chirp_lut[ 513] = 8'd197; long_chirp_lut[ 514] = 8'd248; long_chirp_lut[ 515] = 8'd247; long_chirp_lut[ 516] = 8'd193; long_chirp_lut[ 517] = 8'd111; long_chirp_lut[ 518] = 8'd 36; long_chirp_lut[ 519] = 8'd 1;
|
||||
long_chirp_lut[ 520] = 8'd 21; long_chirp_lut[ 521] = 8'd 88; long_chirp_lut[ 522] = 8'd172; long_chirp_lut[ 523] = 8'd237; long_chirp_lut[ 524] = 8'd253; long_chirp_lut[ 525] = 8'd214; long_chirp_lut[ 526] = 8'd137; long_chirp_lut[ 527] = 8'd 56;
|
||||
long_chirp_lut[ 528] = 8'd 6; long_chirp_lut[ 529] = 8'd 10; long_chirp_lut[ 530] = 8'd 66; long_chirp_lut[ 531] = 8'd149; long_chirp_lut[ 532] = 8'd223; long_chirp_lut[ 533] = 8'd254; long_chirp_lut[ 534] = 8'd230; long_chirp_lut[ 535] = 8'd160;
|
||||
long_chirp_lut[ 536] = 8'd 76; long_chirp_lut[ 537] = 8'd 14; long_chirp_lut[ 538] = 8'd 3; long_chirp_lut[ 539] = 8'd 48; long_chirp_lut[ 540] = 8'd127; long_chirp_lut[ 541] = 8'd207; long_chirp_lut[ 542] = 8'd252; long_chirp_lut[ 543] = 8'd241;
|
||||
long_chirp_lut[ 544] = 8'd179; long_chirp_lut[ 545] = 8'd 94; long_chirp_lut[ 546] = 8'd 24; long_chirp_lut[ 547] = 8'd 1; long_chirp_lut[ 548] = 8'd 34; long_chirp_lut[ 549] = 8'd109; long_chirp_lut[ 550] = 8'd193; long_chirp_lut[ 551] = 8'd247;
|
||||
long_chirp_lut[ 552] = 8'd247; long_chirp_lut[ 553] = 8'd194; long_chirp_lut[ 554] = 8'd111; long_chirp_lut[ 555] = 8'd 35; long_chirp_lut[ 556] = 8'd 1; long_chirp_lut[ 557] = 8'd 24; long_chirp_lut[ 558] = 8'd 94; long_chirp_lut[ 559] = 8'd179;
|
||||
long_chirp_lut[ 560] = 8'd241; long_chirp_lut[ 561] = 8'd251; long_chirp_lut[ 562] = 8'd206; long_chirp_lut[ 563] = 8'd124; long_chirp_lut[ 564] = 8'd 45; long_chirp_lut[ 565] = 8'd 2; long_chirp_lut[ 566] = 8'd 17; long_chirp_lut[ 567] = 8'd 82;
|
||||
long_chirp_lut[ 568] = 8'd168; long_chirp_lut[ 569] = 8'd235; long_chirp_lut[ 570] = 8'd253; long_chirp_lut[ 571] = 8'd214; long_chirp_lut[ 572] = 8'd135; long_chirp_lut[ 573] = 8'd 53; long_chirp_lut[ 574] = 8'd 4; long_chirp_lut[ 575] = 8'd 13;
|
||||
long_chirp_lut[ 576] = 8'd 73; long_chirp_lut[ 577] = 8'd159; long_chirp_lut[ 578] = 8'd230; long_chirp_lut[ 579] = 8'd254; long_chirp_lut[ 580] = 8'd220; long_chirp_lut[ 581] = 8'd143; long_chirp_lut[ 582] = 8'd 59; long_chirp_lut[ 583] = 8'd 6;
|
||||
long_chirp_lut[ 584] = 8'd 10; long_chirp_lut[ 585] = 8'd 68; long_chirp_lut[ 586] = 8'd153; long_chirp_lut[ 587] = 8'd227; long_chirp_lut[ 588] = 8'd254; long_chirp_lut[ 589] = 8'd223; long_chirp_lut[ 590] = 8'd148; long_chirp_lut[ 591] = 8'd 63;
|
||||
long_chirp_lut[ 592] = 8'd 8; long_chirp_lut[ 593] = 8'd 8; long_chirp_lut[ 594] = 8'd 65; long_chirp_lut[ 595] = 8'd150; long_chirp_lut[ 596] = 8'd225; long_chirp_lut[ 597] = 8'd254; long_chirp_lut[ 598] = 8'd225; long_chirp_lut[ 599] = 8'd150;
|
||||
long_chirp_lut[ 600] = 8'd 64; long_chirp_lut[ 601] = 8'd 8; long_chirp_lut[ 602] = 8'd 8; long_chirp_lut[ 603] = 8'd 64; long_chirp_lut[ 604] = 8'd150; long_chirp_lut[ 605] = 8'd225; long_chirp_lut[ 606] = 8'd254; long_chirp_lut[ 607] = 8'd224;
|
||||
long_chirp_lut[ 608] = 8'd148; long_chirp_lut[ 609] = 8'd 63; long_chirp_lut[ 610] = 8'd 8; long_chirp_lut[ 611] = 8'd 9; long_chirp_lut[ 612] = 8'd 66; long_chirp_lut[ 613] = 8'd153; long_chirp_lut[ 614] = 8'd227; long_chirp_lut[ 615] = 8'd254;
|
||||
long_chirp_lut[ 616] = 8'd222; long_chirp_lut[ 617] = 8'd144; long_chirp_lut[ 618] = 8'd 59; long_chirp_lut[ 619] = 8'd 6; long_chirp_lut[ 620] = 8'd 11; long_chirp_lut[ 621] = 8'd 71; long_chirp_lut[ 622] = 8'd158; long_chirp_lut[ 623] = 8'd231;
|
||||
long_chirp_lut[ 624] = 8'd254; long_chirp_lut[ 625] = 8'd217; long_chirp_lut[ 626] = 8'd137; long_chirp_lut[ 627] = 8'd 53; long_chirp_lut[ 628] = 8'd 4; long_chirp_lut[ 629] = 8'd 14; long_chirp_lut[ 630] = 8'd 79; long_chirp_lut[ 631] = 8'd167;
|
||||
long_chirp_lut[ 632] = 8'd236; long_chirp_lut[ 633] = 8'd253; long_chirp_lut[ 634] = 8'd210; long_chirp_lut[ 635] = 8'd127; long_chirp_lut[ 636] = 8'd 45; long_chirp_lut[ 637] = 8'd 2; long_chirp_lut[ 638] = 8'd 20; long_chirp_lut[ 639] = 8'd 90;
|
||||
long_chirp_lut[ 640] = 8'd178; long_chirp_lut[ 641] = 8'd242; long_chirp_lut[ 642] = 8'd250; long_chirp_lut[ 643] = 8'd200; long_chirp_lut[ 644] = 8'd114; long_chirp_lut[ 645] = 8'd 35; long_chirp_lut[ 646] = 8'd 1; long_chirp_lut[ 647] = 8'd 28;
|
||||
long_chirp_lut[ 648] = 8'd104; long_chirp_lut[ 649] = 8'd191; long_chirp_lut[ 650] = 8'd247; long_chirp_lut[ 651] = 8'd246; long_chirp_lut[ 652] = 8'd186; long_chirp_lut[ 653] = 8'd 98; long_chirp_lut[ 654] = 8'd 24; long_chirp_lut[ 655] = 8'd 1;
|
||||
long_chirp_lut[ 656] = 8'd 39; long_chirp_lut[ 657] = 8'd121; long_chirp_lut[ 658] = 8'd206; long_chirp_lut[ 659] = 8'd252; long_chirp_lut[ 660] = 8'd237; long_chirp_lut[ 661] = 8'd169; long_chirp_lut[ 662] = 8'd 80; long_chirp_lut[ 663] = 8'd 14;
|
||||
long_chirp_lut[ 664] = 8'd 4; long_chirp_lut[ 665] = 8'd 55; long_chirp_lut[ 666] = 8'd141; long_chirp_lut[ 667] = 8'd221; long_chirp_lut[ 668] = 8'd254; long_chirp_lut[ 669] = 8'd225; long_chirp_lut[ 670] = 8'd148; long_chirp_lut[ 671] = 8'd 60;
|
||||
long_chirp_lut[ 672] = 8'd 6; long_chirp_lut[ 673] = 8'd 12; long_chirp_lut[ 674] = 8'd 75; long_chirp_lut[ 675] = 8'd164; long_chirp_lut[ 676] = 8'd235; long_chirp_lut[ 677] = 8'd253; long_chirp_lut[ 678] = 8'd208; long_chirp_lut[ 679] = 8'd123;
|
||||
long_chirp_lut[ 680] = 8'd 40; long_chirp_lut[ 681] = 8'd 1; long_chirp_lut[ 682] = 8'd 25; long_chirp_lut[ 683] = 8'd100; long_chirp_lut[ 684] = 8'd189; long_chirp_lut[ 685] = 8'd247; long_chirp_lut[ 686] = 8'd246; long_chirp_lut[ 687] = 8'd185;
|
||||
long_chirp_lut[ 688] = 8'd 96; long_chirp_lut[ 689] = 8'd 22; long_chirp_lut[ 690] = 8'd 2; long_chirp_lut[ 691] = 8'd 44; long_chirp_lut[ 692] = 8'd129; long_chirp_lut[ 693] = 8'd213; long_chirp_lut[ 694] = 8'd254; long_chirp_lut[ 695] = 8'd231;
|
||||
long_chirp_lut[ 696] = 8'd157; long_chirp_lut[ 697] = 8'd 67; long_chirp_lut[ 698] = 8'd 8; long_chirp_lut[ 699] = 8'd 9; long_chirp_lut[ 700] = 8'd 71; long_chirp_lut[ 701] = 8'd160; long_chirp_lut[ 702] = 8'd234; long_chirp_lut[ 703] = 8'd253;
|
||||
long_chirp_lut[ 704] = 8'd209; long_chirp_lut[ 705] = 8'd123; long_chirp_lut[ 706] = 8'd 40; long_chirp_lut[ 707] = 8'd 1; long_chirp_lut[ 708] = 8'd 26; long_chirp_lut[ 709] = 8'd103; long_chirp_lut[ 710] = 8'd193; long_chirp_lut[ 711] = 8'd249;
|
||||
long_chirp_lut[ 712] = 8'd243; long_chirp_lut[ 713] = 8'd178; long_chirp_lut[ 714] = 8'd 88; long_chirp_lut[ 715] = 8'd 17; long_chirp_lut[ 716] = 8'd 3; long_chirp_lut[ 717] = 8'd 53; long_chirp_lut[ 718] = 8'd141; long_chirp_lut[ 719] = 8'd222;
|
||||
long_chirp_lut[ 720] = 8'd255; long_chirp_lut[ 721] = 8'd222; long_chirp_lut[ 722] = 8'd141; long_chirp_lut[ 723] = 8'd 53; long_chirp_lut[ 724] = 8'd 3; long_chirp_lut[ 725] = 8'd 18; long_chirp_lut[ 726] = 8'd 89; long_chirp_lut[ 727] = 8'd180;
|
||||
long_chirp_lut[ 728] = 8'd244; long_chirp_lut[ 729] = 8'd248; long_chirp_lut[ 730] = 8'd189; long_chirp_lut[ 731] = 8'd 99; long_chirp_lut[ 732] = 8'd 23; long_chirp_lut[ 733] = 8'd 2; long_chirp_lut[ 734] = 8'd 45; long_chirp_lut[ 735] = 8'd132;
|
||||
long_chirp_lut[ 736] = 8'd216; long_chirp_lut[ 737] = 8'd254; long_chirp_lut[ 738] = 8'd227; long_chirp_lut[ 739] = 8'd147; long_chirp_lut[ 740] = 8'd 58; long_chirp_lut[ 741] = 8'd 4; long_chirp_lut[ 742] = 8'd 15; long_chirp_lut[ 743] = 8'd 85;
|
||||
long_chirp_lut[ 744] = 8'd177; long_chirp_lut[ 745] = 8'd243; long_chirp_lut[ 746] = 8'd249; long_chirp_lut[ 747] = 8'd191; long_chirp_lut[ 748] = 8'd100; long_chirp_lut[ 749] = 8'd 23; long_chirp_lut[ 750] = 8'd 2; long_chirp_lut[ 751] = 8'd 46;
|
||||
long_chirp_lut[ 752] = 8'd133; long_chirp_lut[ 753] = 8'd217; long_chirp_lut[ 754] = 8'd254; long_chirp_lut[ 755] = 8'd224; long_chirp_lut[ 756] = 8'd143; long_chirp_lut[ 757] = 8'd 54; long_chirp_lut[ 758] = 8'd 3; long_chirp_lut[ 759] = 8'd 18;
|
||||
long_chirp_lut[ 760] = 8'd 91; long_chirp_lut[ 761] = 8'd183; long_chirp_lut[ 762] = 8'd246; long_chirp_lut[ 763] = 8'd246; long_chirp_lut[ 764] = 8'd183; long_chirp_lut[ 765] = 8'd 91; long_chirp_lut[ 766] = 8'd 18; long_chirp_lut[ 767] = 8'd 3;
|
||||
long_chirp_lut[ 768] = 8'd 55; long_chirp_lut[ 769] = 8'd145; long_chirp_lut[ 770] = 8'd226; long_chirp_lut[ 771] = 8'd254; long_chirp_lut[ 772] = 8'd215; long_chirp_lut[ 773] = 8'd129; long_chirp_lut[ 774] = 8'd 42; long_chirp_lut[ 775] = 8'd 1;
|
||||
long_chirp_lut[ 776] = 8'd 28; long_chirp_lut[ 777] = 8'd108; long_chirp_lut[ 778] = 8'd199; long_chirp_lut[ 779] = 8'd251; long_chirp_lut[ 780] = 8'd237; long_chirp_lut[ 781] = 8'd165; long_chirp_lut[ 782] = 8'd 72; long_chirp_lut[ 783] = 8'd 9;
|
||||
long_chirp_lut[ 784] = 8'd 10; long_chirp_lut[ 785] = 8'd 74; long_chirp_lut[ 786] = 8'd167; long_chirp_lut[ 787] = 8'd239; long_chirp_lut[ 788] = 8'd250; long_chirp_lut[ 789] = 8'd195; long_chirp_lut[ 790] = 8'd104; long_chirp_lut[ 791] = 8'd 25;
|
||||
long_chirp_lut[ 792] = 8'd 2; long_chirp_lut[ 793] = 8'd 47; long_chirp_lut[ 794] = 8'd136; long_chirp_lut[ 795] = 8'd220; long_chirp_lut[ 796] = 8'd254; long_chirp_lut[ 797] = 8'd220; long_chirp_lut[ 798] = 8'd135; long_chirp_lut[ 799] = 8'd 46;
|
||||
long_chirp_lut[ 800] = 8'd 1; long_chirp_lut[ 801] = 8'd 26; long_chirp_lut[ 802] = 8'd106; long_chirp_lut[ 803] = 8'd197; long_chirp_lut[ 804] = 8'd251; long_chirp_lut[ 805] = 8'd237; long_chirp_lut[ 806] = 8'd163; long_chirp_lut[ 807] = 8'd 70;
|
||||
long_chirp_lut[ 808] = 8'd 8; long_chirp_lut[ 809] = 8'd 11; long_chirp_lut[ 810] = 8'd 79; long_chirp_lut[ 811] = 8'd173; long_chirp_lut[ 812] = 8'd242; long_chirp_lut[ 813] = 8'd248; long_chirp_lut[ 814] = 8'd188; long_chirp_lut[ 815] = 8'd 94;
|
||||
long_chirp_lut[ 816] = 8'd 19; long_chirp_lut[ 817] = 8'd 3; long_chirp_lut[ 818] = 8'd 57; long_chirp_lut[ 819] = 8'd149; long_chirp_lut[ 820] = 8'd229; long_chirp_lut[ 821] = 8'd254; long_chirp_lut[ 822] = 8'd208; long_chirp_lut[ 823] = 8'd118;
|
||||
long_chirp_lut[ 824] = 8'd 33; long_chirp_lut[ 825] = 8'd 1; long_chirp_lut[ 826] = 8'd 39; long_chirp_lut[ 827] = 8'd126; long_chirp_lut[ 828] = 8'd214; long_chirp_lut[ 829] = 8'd254; long_chirp_lut[ 830] = 8'd224; long_chirp_lut[ 831] = 8'd139;
|
||||
long_chirp_lut[ 832] = 8'd 48; long_chirp_lut[ 833] = 8'd 2; long_chirp_lut[ 834] = 8'd 25; long_chirp_lut[ 835] = 8'd106; long_chirp_lut[ 836] = 8'd199; long_chirp_lut[ 837] = 8'd252; long_chirp_lut[ 838] = 8'd235; long_chirp_lut[ 839] = 8'd158;
|
||||
long_chirp_lut[ 840] = 8'd 64; long_chirp_lut[ 841] = 8'd 5; long_chirp_lut[ 842] = 8'd 15; long_chirp_lut[ 843] = 8'd 88; long_chirp_lut[ 844] = 8'd183; long_chirp_lut[ 845] = 8'd247; long_chirp_lut[ 846] = 8'd243; long_chirp_lut[ 847] = 8'd174;
|
||||
long_chirp_lut[ 848] = 8'd 79; long_chirp_lut[ 849] = 8'd 11; long_chirp_lut[ 850] = 8'd 9; long_chirp_lut[ 851] = 8'd 74; long_chirp_lut[ 852] = 8'd169; long_chirp_lut[ 853] = 8'd241; long_chirp_lut[ 854] = 8'd249; long_chirp_lut[ 855] = 8'd187;
|
||||
long_chirp_lut[ 856] = 8'd 92; long_chirp_lut[ 857] = 8'd 17; long_chirp_lut[ 858] = 8'd 5; long_chirp_lut[ 859] = 8'd 62; long_chirp_lut[ 860] = 8'd157; long_chirp_lut[ 861] = 8'd235; long_chirp_lut[ 862] = 8'd252; long_chirp_lut[ 863] = 8'd198;
|
||||
long_chirp_lut[ 864] = 8'd104; long_chirp_lut[ 865] = 8'd 23; long_chirp_lut[ 866] = 8'd 2; long_chirp_lut[ 867] = 8'd 53; long_chirp_lut[ 868] = 8'd146; long_chirp_lut[ 869] = 8'd229; long_chirp_lut[ 870] = 8'd253; long_chirp_lut[ 871] = 8'd206;
|
||||
long_chirp_lut[ 872] = 8'd113; long_chirp_lut[ 873] = 8'd 29; long_chirp_lut[ 874] = 8'd 1; long_chirp_lut[ 875] = 8'd 46; long_chirp_lut[ 876] = 8'd138; long_chirp_lut[ 877] = 8'd224; long_chirp_lut[ 878] = 8'd254; long_chirp_lut[ 879] = 8'd211;
|
||||
long_chirp_lut[ 880] = 8'd120; long_chirp_lut[ 881] = 8'd 33; long_chirp_lut[ 882] = 8'd 1; long_chirp_lut[ 883] = 8'd 42; long_chirp_lut[ 884] = 8'd132; long_chirp_lut[ 885] = 8'd220; long_chirp_lut[ 886] = 8'd254; long_chirp_lut[ 887] = 8'd215;
|
||||
long_chirp_lut[ 888] = 8'd125; long_chirp_lut[ 889] = 8'd 36; long_chirp_lut[ 890] = 8'd 1; long_chirp_lut[ 891] = 8'd 39; long_chirp_lut[ 892] = 8'd129; long_chirp_lut[ 893] = 8'd218; long_chirp_lut[ 894] = 8'd254; long_chirp_lut[ 895] = 8'd217;
|
||||
long_chirp_lut[ 896] = 8'd127; long_chirp_lut[ 897] = 8'd 38; long_chirp_lut[ 898] = 8'd 1; long_chirp_lut[ 899] = 8'd 38; long_chirp_lut[ 900] = 8'd127; long_chirp_lut[ 901] = 8'd217; long_chirp_lut[ 902] = 8'd254; long_chirp_lut[ 903] = 8'd217;
|
||||
long_chirp_lut[ 904] = 8'd127; long_chirp_lut[ 905] = 8'd 37; long_chirp_lut[ 906] = 8'd 1; long_chirp_lut[ 907] = 8'd 38; long_chirp_lut[ 908] = 8'd129; long_chirp_lut[ 909] = 8'd218; long_chirp_lut[ 910] = 8'd254; long_chirp_lut[ 911] = 8'd216;
|
||||
long_chirp_lut[ 912] = 8'd125; long_chirp_lut[ 913] = 8'd 36; long_chirp_lut[ 914] = 8'd 1; long_chirp_lut[ 915] = 8'd 41; long_chirp_lut[ 916] = 8'd132; long_chirp_lut[ 917] = 8'd221; long_chirp_lut[ 918] = 8'd254; long_chirp_lut[ 919] = 8'd212;
|
||||
long_chirp_lut[ 920] = 8'd120; long_chirp_lut[ 921] = 8'd 32; long_chirp_lut[ 922] = 8'd 1; long_chirp_lut[ 923] = 8'd 45; long_chirp_lut[ 924] = 8'd138; long_chirp_lut[ 925] = 8'd225; long_chirp_lut[ 926] = 8'd254; long_chirp_lut[ 927] = 8'd207;
|
||||
long_chirp_lut[ 928] = 8'd113; long_chirp_lut[ 929] = 8'd 27; long_chirp_lut[ 930] = 8'd 2; long_chirp_lut[ 931] = 8'd 51; long_chirp_lut[ 932] = 8'd146; long_chirp_lut[ 933] = 8'd230; long_chirp_lut[ 934] = 8'd253; long_chirp_lut[ 935] = 8'd200;
|
||||
long_chirp_lut[ 936] = 8'd104; long_chirp_lut[ 937] = 8'd 22; long_chirp_lut[ 938] = 8'd 3; long_chirp_lut[ 939] = 8'd 60; long_chirp_lut[ 940] = 8'd157; long_chirp_lut[ 941] = 8'd236; long_chirp_lut[ 942] = 8'd250; long_chirp_lut[ 943] = 8'd190;
|
||||
long_chirp_lut[ 944] = 8'd 92; long_chirp_lut[ 945] = 8'd 15; long_chirp_lut[ 946] = 8'd 6; long_chirp_lut[ 947] = 8'd 71; long_chirp_lut[ 948] = 8'd169; long_chirp_lut[ 949] = 8'd243; long_chirp_lut[ 950] = 8'd246; long_chirp_lut[ 951] = 8'd178;
|
||||
long_chirp_lut[ 952] = 8'd 79; long_chirp_lut[ 953] = 8'd 9; long_chirp_lut[ 954] = 8'd 12; long_chirp_lut[ 955] = 8'd 84; long_chirp_lut[ 956] = 8'd183; long_chirp_lut[ 957] = 8'd248; long_chirp_lut[ 958] = 8'd240; long_chirp_lut[ 959] = 8'd162;
|
||||
long_chirp_lut[ 960] = 8'd 64; long_chirp_lut[ 961] = 8'd 4; long_chirp_lut[ 962] = 8'd 20; long_chirp_lut[ 963] = 8'd101; long_chirp_lut[ 964] = 8'd199; long_chirp_lut[ 965] = 8'd253; long_chirp_lut[ 966] = 8'd230; long_chirp_lut[ 967] = 8'd144;
|
||||
long_chirp_lut[ 968] = 8'd 48; long_chirp_lut[ 969] = 8'd 1; long_chirp_lut[ 970] = 8'd 31; long_chirp_lut[ 971] = 8'd121; long_chirp_lut[ 972] = 8'd214; long_chirp_lut[ 973] = 8'd254; long_chirp_lut[ 974] = 8'd216; long_chirp_lut[ 975] = 8'd123;
|
||||
long_chirp_lut[ 976] = 8'd 33; long_chirp_lut[ 977] = 8'd 1; long_chirp_lut[ 978] = 8'd 47; long_chirp_lut[ 979] = 8'd143; long_chirp_lut[ 980] = 8'd229; long_chirp_lut[ 981] = 8'd253; long_chirp_lut[ 982] = 8'd198; long_chirp_lut[ 983] = 8'd100;
|
||||
long_chirp_lut[ 984] = 8'd 19; long_chirp_lut[ 985] = 8'd 5; long_chirp_lut[ 986] = 8'd 67; long_chirp_lut[ 987] = 8'd167; long_chirp_lut[ 988] = 8'd242; long_chirp_lut[ 989] = 8'd246; long_chirp_lut[ 990] = 8'd176; long_chirp_lut[ 991] = 8'd 76;
|
||||
long_chirp_lut[ 992] = 8'd 8; long_chirp_lut[ 993] = 8'd 14; long_chirp_lut[ 994] = 8'd 92; long_chirp_lut[ 995] = 8'd191; long_chirp_lut[ 996] = 8'd251; long_chirp_lut[ 997] = 8'd234; long_chirp_lut[ 998] = 8'd149; long_chirp_lut[ 999] = 8'd 52;
|
||||
long_chirp_lut[1000] = 8'd 1; long_chirp_lut[1001] = 8'd 30; long_chirp_lut[1002] = 8'd120; long_chirp_lut[1003] = 8'd215; long_chirp_lut[1004] = 8'd254; long_chirp_lut[1005] = 8'd214; long_chirp_lut[1006] = 8'd119; long_chirp_lut[1007] = 8'd 30;
|
||||
long_chirp_lut[1008] = 8'd 2; long_chirp_lut[1009] = 8'd 53; long_chirp_lut[1010] = 8'd151; long_chirp_lut[1011] = 8'd235; long_chirp_lut[1012] = 8'd250; long_chirp_lut[1013] = 8'd188; long_chirp_lut[1014] = 8'd 88; long_chirp_lut[1015] = 8'd 12;
|
||||
long_chirp_lut[1016] = 8'd 10; long_chirp_lut[1017] = 8'd 82; long_chirp_lut[1018] = 8'd183; long_chirp_lut[1019] = 8'd249; long_chirp_lut[1020] = 8'd237; long_chirp_lut[1021] = 8'd156; long_chirp_lut[1022] = 8'd 56; long_chirp_lut[1023] = 8'd 2;
|
||||
long_chirp_lut[1024] = 8'd 28; long_chirp_lut[1025] = 8'd117; long_chirp_lut[1026] = 8'd213; long_chirp_lut[1027] = 8'd254; long_chirp_lut[1028] = 8'd215; long_chirp_lut[1029] = 8'd119; long_chirp_lut[1030] = 8'd 29; long_chirp_lut[1031] = 8'd 2;
|
||||
long_chirp_lut[1032] = 8'd 55; long_chirp_lut[1033] = 8'd155; long_chirp_lut[1034] = 8'd237; long_chirp_lut[1035] = 8'd249; long_chirp_lut[1036] = 8'd183; long_chirp_lut[1037] = 8'd 81; long_chirp_lut[1038] = 8'd 9; long_chirp_lut[1039] = 8'd 13;
|
||||
long_chirp_lut[1040] = 8'd 91; long_chirp_lut[1041] = 8'd192; long_chirp_lut[1042] = 8'd252; long_chirp_lut[1043] = 8'd231; long_chirp_lut[1044] = 8'd143; long_chirp_lut[1045] = 8'd 46; long_chirp_lut[1046] = 8'd 1; long_chirp_lut[1047] = 8'd 38;
|
||||
long_chirp_lut[1048] = 8'd133; long_chirp_lut[1049] = 8'd225; long_chirp_lut[1050] = 8'd253; long_chirp_lut[1051] = 8'd200; long_chirp_lut[1052] = 8'd100; long_chirp_lut[1053] = 8'd 17; long_chirp_lut[1054] = 8'd 6; long_chirp_lut[1055] = 8'd 74;
|
||||
long_chirp_lut[1056] = 8'd177; long_chirp_lut[1057] = 8'd247; long_chirp_lut[1058] = 8'd240; long_chirp_lut[1059] = 8'd159; long_chirp_lut[1060] = 8'd 58; long_chirp_lut[1061] = 8'd 2; long_chirp_lut[1062] = 8'd 28; long_chirp_lut[1063] = 8'd120;
|
||||
long_chirp_lut[1064] = 8'd216; long_chirp_lut[1065] = 8'd254; long_chirp_lut[1066] = 8'd210; long_chirp_lut[1067] = 8'd111; long_chirp_lut[1068] = 8'd 23; long_chirp_lut[1069] = 8'd 4; long_chirp_lut[1070] = 8'd 66; long_chirp_lut[1071] = 8'd168;
|
||||
long_chirp_lut[1072] = 8'd244; long_chirp_lut[1073] = 8'd243; long_chirp_lut[1074] = 8'd166; long_chirp_lut[1075] = 8'd 64; long_chirp_lut[1076] = 8'd 3; long_chirp_lut[1077] = 8'd 25; long_chirp_lut[1078] = 8'd114; long_chirp_lut[1079] = 8'd212;
|
||||
long_chirp_lut[1080] = 8'd255; long_chirp_lut[1081] = 8'd212; long_chirp_lut[1082] = 8'd114; long_chirp_lut[1083] = 8'd 25; long_chirp_lut[1084] = 8'd 3; long_chirp_lut[1085] = 8'd 64; long_chirp_lut[1086] = 8'd167; long_chirp_lut[1087] = 8'd244;
|
||||
long_chirp_lut[1088] = 8'd243; long_chirp_lut[1089] = 8'd165; long_chirp_lut[1090] = 8'd 62; long_chirp_lut[1091] = 8'd 3; long_chirp_lut[1092] = 8'd 26; long_chirp_lut[1093] = 8'd117; long_chirp_lut[1094] = 8'd215; long_chirp_lut[1095] = 8'd254;
|
||||
long_chirp_lut[1096] = 8'd209; long_chirp_lut[1097] = 8'd109; long_chirp_lut[1098] = 8'd 21; long_chirp_lut[1099] = 8'd 5; long_chirp_lut[1100] = 8'd 71; long_chirp_lut[1101] = 8'd174; long_chirp_lut[1102] = 8'd247; long_chirp_lut[1103] = 8'd239;
|
||||
long_chirp_lut[1104] = 8'd157; long_chirp_lut[1105] = 8'd 54; long_chirp_lut[1106] = 8'd 1; long_chirp_lut[1107] = 8'd 33; long_chirp_lut[1108] = 8'd129; long_chirp_lut[1109] = 8'd223; long_chirp_lut[1110] = 8'd253; long_chirp_lut[1111] = 8'd199;
|
||||
long_chirp_lut[1112] = 8'd 96; long_chirp_lut[1113] = 8'd 14; long_chirp_lut[1114] = 8'd 9; long_chirp_lut[1115] = 8'd 84; long_chirp_lut[1116] = 8'd189; long_chirp_lut[1117] = 8'd251; long_chirp_lut[1118] = 8'd230; long_chirp_lut[1119] = 8'd139;
|
||||
long_chirp_lut[1120] = 8'd 40; long_chirp_lut[1121] = 8'd 1; long_chirp_lut[1122] = 8'd 47; long_chirp_lut[1123] = 8'd148; long_chirp_lut[1124] = 8'd235; long_chirp_lut[1125] = 8'd249; long_chirp_lut[1126] = 8'd180; long_chirp_lut[1127] = 8'd 75;
|
||||
long_chirp_lut[1128] = 8'd 6; long_chirp_lut[1129] = 8'd 20; long_chirp_lut[1130] = 8'd107; long_chirp_lut[1131] = 8'd209; long_chirp_lut[1132] = 8'd254; long_chirp_lut[1133] = 8'd213; long_chirp_lut[1134] = 8'd114; long_chirp_lut[1135] = 8'd 23;
|
||||
long_chirp_lut[1136] = 8'd 4; long_chirp_lut[1137] = 8'd 70; long_chirp_lut[1138] = 8'd175; long_chirp_lut[1139] = 8'd248; long_chirp_lut[1140] = 8'd237; long_chirp_lut[1141] = 8'd152; long_chirp_lut[1142] = 8'd 49; long_chirp_lut[1143] = 8'd 1;
|
||||
long_chirp_lut[1144] = 8'd 39; long_chirp_lut[1145] = 8'd139; long_chirp_lut[1146] = 8'd231; long_chirp_lut[1147] = 8'd251; long_chirp_lut[1148] = 8'd186; long_chirp_lut[1149] = 8'd 81; long_chirp_lut[1150] = 8'd 8; long_chirp_lut[1151] = 8'd 18;
|
||||
long_chirp_lut[1152] = 8'd104; long_chirp_lut[1153] = 8'd206; long_chirp_lut[1154] = 8'd254; long_chirp_lut[1155] = 8'd214; long_chirp_lut[1156] = 8'd114; long_chirp_lut[1157] = 8'd 23; long_chirp_lut[1158] = 8'd 5; long_chirp_lut[1159] = 8'd 72;
|
||||
long_chirp_lut[1160] = 8'd178; long_chirp_lut[1161] = 8'd249; long_chirp_lut[1162] = 8'd235; long_chirp_lut[1163] = 8'd146; long_chirp_lut[1164] = 8'd 45; long_chirp_lut[1165] = 8'd 1; long_chirp_lut[1166] = 8'd 45; long_chirp_lut[1167] = 8'd148;
|
||||
long_chirp_lut[1168] = 8'd236; long_chirp_lut[1169] = 8'd248; long_chirp_lut[1170] = 8'd176; long_chirp_lut[1171] = 8'd 70; long_chirp_lut[1172] = 8'd 4; long_chirp_lut[1173] = 8'd 25; long_chirp_lut[1174] = 8'd118; long_chirp_lut[1175] = 8'd218;
|
||||
long_chirp_lut[1176] = 8'd254; long_chirp_lut[1177] = 8'd201; long_chirp_lut[1178] = 8'd 97; long_chirp_lut[1179] = 8'd 14; long_chirp_lut[1180] = 8'd 11; long_chirp_lut[1181] = 8'd 90; long_chirp_lut[1182] = 8'd196; long_chirp_lut[1183] = 8'd253;
|
||||
long_chirp_lut[1184] = 8'd222; long_chirp_lut[1185] = 8'd123; long_chirp_lut[1186] = 8'd 28; long_chirp_lut[1187] = 8'd 3; long_chirp_lut[1188] = 8'd 66; long_chirp_lut[1189] = 8'd173; long_chirp_lut[1190] = 8'd247; long_chirp_lut[1191] = 8'd237;
|
||||
long_chirp_lut[1192] = 8'd148; long_chirp_lut[1193] = 8'd 45; long_chirp_lut[1194] = 8'd 1; long_chirp_lut[1195] = 8'd 46; long_chirp_lut[1196] = 8'd150; long_chirp_lut[1197] = 8'd238; long_chirp_lut[1198] = 8'd247; long_chirp_lut[1199] = 8'd171;
|
||||
long_chirp_lut[1200] = 8'd 64; long_chirp_lut[1201] = 8'd 2; long_chirp_lut[1202] = 8'd 30; long_chirp_lut[1203] = 8'd128; long_chirp_lut[1204] = 8'd225; long_chirp_lut[1205] = 8'd252; long_chirp_lut[1206] = 8'd190; long_chirp_lut[1207] = 8'd 83;
|
||||
long_chirp_lut[1208] = 8'd 8; long_chirp_lut[1209] = 8'd 18; long_chirp_lut[1210] = 8'd107; long_chirp_lut[1211] = 8'd211; long_chirp_lut[1212] = 8'd254; long_chirp_lut[1213] = 8'd207; long_chirp_lut[1214] = 8'd102; long_chirp_lut[1215] = 8'd 15;
|
||||
long_chirp_lut[1216] = 8'd 10; long_chirp_lut[1217] = 8'd 89; long_chirp_lut[1218] = 8'd196; long_chirp_lut[1219] = 8'd254; long_chirp_lut[1220] = 8'd220; long_chirp_lut[1221] = 8'd119; long_chirp_lut[1222] = 8'd 25; long_chirp_lut[1223] = 8'd 4;
|
||||
long_chirp_lut[1224] = 8'd 73; long_chirp_lut[1225] = 8'd182; long_chirp_lut[1226] = 8'd251; long_chirp_lut[1227] = 8'd230; long_chirp_lut[1228] = 8'd135; long_chirp_lut[1229] = 8'd 35; long_chirp_lut[1230] = 8'd 2; long_chirp_lut[1231] = 8'd 60;
|
||||
long_chirp_lut[1232] = 8'd168; long_chirp_lut[1233] = 8'd246; long_chirp_lut[1234] = 8'd238; long_chirp_lut[1235] = 8'd149; long_chirp_lut[1236] = 8'd 45; long_chirp_lut[1237] = 8'd 1; long_chirp_lut[1238] = 8'd 49; long_chirp_lut[1239] = 8'd155;
|
||||
long_chirp_lut[1240] = 8'd241; long_chirp_lut[1241] = 8'd244; long_chirp_lut[1242] = 8'd161; long_chirp_lut[1243] = 8'd 54; long_chirp_lut[1244] = 8'd 1; long_chirp_lut[1245] = 8'd 41; long_chirp_lut[1246] = 8'd144; long_chirp_lut[1247] = 8'd236;
|
||||
long_chirp_lut[1248] = 8'd247; long_chirp_lut[1249] = 8'd171; long_chirp_lut[1250] = 8'd 62; long_chirp_lut[1251] = 8'd 2; long_chirp_lut[1252] = 8'd 34; long_chirp_lut[1253] = 8'd135; long_chirp_lut[1254] = 8'd231; long_chirp_lut[1255] = 8'd250;
|
||||
long_chirp_lut[1256] = 8'd179; long_chirp_lut[1257] = 8'd 70; long_chirp_lut[1258] = 8'd 3; long_chirp_lut[1259] = 8'd 29; long_chirp_lut[1260] = 8'd127; long_chirp_lut[1261] = 8'd226; long_chirp_lut[1262] = 8'd252; long_chirp_lut[1263] = 8'd185;
|
||||
long_chirp_lut[1264] = 8'd 76; long_chirp_lut[1265] = 8'd 5; long_chirp_lut[1266] = 8'd 25; long_chirp_lut[1267] = 8'd122; long_chirp_lut[1268] = 8'd223; long_chirp_lut[1269] = 8'd253; long_chirp_lut[1270] = 8'd189; long_chirp_lut[1271] = 8'd 80;
|
||||
long_chirp_lut[1272] = 8'd 6; long_chirp_lut[1273] = 8'd 23; long_chirp_lut[1274] = 8'd118; long_chirp_lut[1275] = 8'd220; long_chirp_lut[1276] = 8'd253; long_chirp_lut[1277] = 8'd192; long_chirp_lut[1278] = 8'd 83; long_chirp_lut[1279] = 8'd 7;
|
||||
long_chirp_lut[1280] = 8'd 21; long_chirp_lut[1281] = 8'd116; long_chirp_lut[1282] = 8'd219; long_chirp_lut[1283] = 8'd253; long_chirp_lut[1284] = 8'd193; long_chirp_lut[1285] = 8'd 84; long_chirp_lut[1286] = 8'd 7; long_chirp_lut[1287] = 8'd 21;
|
||||
long_chirp_lut[1288] = 8'd115; long_chirp_lut[1289] = 8'd219; long_chirp_lut[1290] = 8'd253; long_chirp_lut[1291] = 8'd193; long_chirp_lut[1292] = 8'd 83; long_chirp_lut[1293] = 8'd 7; long_chirp_lut[1294] = 8'd 22; long_chirp_lut[1295] = 8'd117;
|
||||
long_chirp_lut[1296] = 8'd220; long_chirp_lut[1297] = 8'd253; long_chirp_lut[1298] = 8'd191; long_chirp_lut[1299] = 8'd 81; long_chirp_lut[1300] = 8'd 6; long_chirp_lut[1301] = 8'd 23; long_chirp_lut[1302] = 8'd120; long_chirp_lut[1303] = 8'd222;
|
||||
long_chirp_lut[1304] = 8'd253; long_chirp_lut[1305] = 8'd187; long_chirp_lut[1306] = 8'd 77; long_chirp_lut[1307] = 8'd 5; long_chirp_lut[1308] = 8'd 26; long_chirp_lut[1309] = 8'd125; long_chirp_lut[1310] = 8'd226; long_chirp_lut[1311] = 8'd251;
|
||||
long_chirp_lut[1312] = 8'd182; long_chirp_lut[1313] = 8'd 71; long_chirp_lut[1314] = 8'd 3; long_chirp_lut[1315] = 8'd 31; long_chirp_lut[1316] = 8'd132; long_chirp_lut[1317] = 8'd230; long_chirp_lut[1318] = 8'd250; long_chirp_lut[1319] = 8'd175;
|
||||
long_chirp_lut[1320] = 8'd 64; long_chirp_lut[1321] = 8'd 2; long_chirp_lut[1322] = 8'd 36; long_chirp_lut[1323] = 8'd141; long_chirp_lut[1324] = 8'd235; long_chirp_lut[1325] = 8'd247; long_chirp_lut[1326] = 8'd166; long_chirp_lut[1327] = 8'd 56;
|
||||
long_chirp_lut[1328] = 8'd 1; long_chirp_lut[1329] = 8'd 44; long_chirp_lut[1330] = 8'd151; long_chirp_lut[1331] = 8'd241; long_chirp_lut[1332] = 8'd242; long_chirp_lut[1333] = 8'd155; long_chirp_lut[1334] = 8'd 46; long_chirp_lut[1335] = 8'd 1;
|
||||
long_chirp_lut[1336] = 8'd 53; long_chirp_lut[1337] = 8'd163; long_chirp_lut[1338] = 8'd246; long_chirp_lut[1339] = 8'd236; long_chirp_lut[1340] = 8'd142; long_chirp_lut[1341] = 8'd 37; long_chirp_lut[1342] = 8'd 2; long_chirp_lut[1343] = 8'd 65;
|
||||
long_chirp_lut[1344] = 8'd177; long_chirp_lut[1345] = 8'd250; long_chirp_lut[1346] = 8'd228; long_chirp_lut[1347] = 8'd127; long_chirp_lut[1348] = 8'd 27; long_chirp_lut[1349] = 8'd 5; long_chirp_lut[1350] = 8'd 79; long_chirp_lut[1351] = 8'd191;
|
||||
long_chirp_lut[1352] = 8'd253; long_chirp_lut[1353] = 8'd217; long_chirp_lut[1354] = 8'd111; long_chirp_lut[1355] = 8'd 17; long_chirp_lut[1356] = 8'd 10; long_chirp_lut[1357] = 8'd 96; long_chirp_lut[1358] = 8'd206; long_chirp_lut[1359] = 8'd254;
|
||||
long_chirp_lut[1360] = 8'd203; long_chirp_lut[1361] = 8'd 92; long_chirp_lut[1362] = 8'd 9; long_chirp_lut[1363] = 8'd 19; long_chirp_lut[1364] = 8'd115; long_chirp_lut[1365] = 8'd220; long_chirp_lut[1366] = 8'd253; long_chirp_lut[1367] = 8'd186;
|
||||
long_chirp_lut[1368] = 8'd 73; long_chirp_lut[1369] = 8'd 3; long_chirp_lut[1370] = 8'd 31; long_chirp_lut[1371] = 8'd136; long_chirp_lut[1372] = 8'd233; long_chirp_lut[1373] = 8'd247; long_chirp_lut[1374] = 8'd166; long_chirp_lut[1375] = 8'd 54;
|
||||
long_chirp_lut[1376] = 8'd 1; long_chirp_lut[1377] = 8'd 48; long_chirp_lut[1378] = 8'd158; long_chirp_lut[1379] = 8'd244; long_chirp_lut[1380] = 8'd237; long_chirp_lut[1381] = 8'd143; long_chirp_lut[1382] = 8'd 36; long_chirp_lut[1383] = 8'd 2;
|
||||
long_chirp_lut[1384] = 8'd 68; long_chirp_lut[1385] = 8'd182; long_chirp_lut[1386] = 8'd252; long_chirp_lut[1387] = 8'd223; long_chirp_lut[1388] = 8'd117; long_chirp_lut[1389] = 8'd 20; long_chirp_lut[1390] = 8'd 9; long_chirp_lut[1391] = 8'd 93;
|
||||
long_chirp_lut[1392] = 8'd204; long_chirp_lut[1393] = 8'd254; long_chirp_lut[1394] = 8'd203; long_chirp_lut[1395] = 8'd 91; long_chirp_lut[1396] = 8'd 8; long_chirp_lut[1397] = 8'd 21; long_chirp_lut[1398] = 8'd120; long_chirp_lut[1399] = 8'd225;
|
||||
long_chirp_lut[1400] = 8'd251; long_chirp_lut[1401] = 8'd178; long_chirp_lut[1402] = 8'd 64; long_chirp_lut[1403] = 8'd 1; long_chirp_lut[1404] = 8'd 41; long_chirp_lut[1405] = 8'd150; long_chirp_lut[1406] = 8'd241; long_chirp_lut[1407] = 8'd241;
|
||||
long_chirp_lut[1408] = 8'd148; long_chirp_lut[1409] = 8'd 39; long_chirp_lut[1410] = 8'd 2; long_chirp_lut[1411] = 8'd 66; long_chirp_lut[1412] = 8'd180; long_chirp_lut[1413] = 8'd252; long_chirp_lut[1414] = 8'd222; long_chirp_lut[1415] = 8'd116;
|
||||
long_chirp_lut[1416] = 8'd 19; long_chirp_lut[1417] = 8'd 10; long_chirp_lut[1418] = 8'd 97; long_chirp_lut[1419] = 8'd209; long_chirp_lut[1420] = 8'd254; long_chirp_lut[1421] = 8'd197; long_chirp_lut[1422] = 8'd 83; long_chirp_lut[1423] = 8'd 5;
|
||||
long_chirp_lut[1424] = 8'd 28; long_chirp_lut[1425] = 8'd132; long_chirp_lut[1426] = 8'd232; long_chirp_lut[1427] = 8'd247; long_chirp_lut[1428] = 8'd164; long_chirp_lut[1429] = 8'd 51; long_chirp_lut[1430] = 8'd 1; long_chirp_lut[1431] = 8'd 54;
|
||||
long_chirp_lut[1432] = 8'd168; long_chirp_lut[1433] = 8'd249; long_chirp_lut[1434] = 8'd230; long_chirp_lut[1435] = 8'd127; long_chirp_lut[1436] = 8'd 25; long_chirp_lut[1437] = 8'd 7; long_chirp_lut[1438] = 8'd 88; long_chirp_lut[1439] = 8'd202;
|
||||
long_chirp_lut[1440] = 8'd255; long_chirp_lut[1441] = 8'd202; long_chirp_lut[1442] = 8'd 88; long_chirp_lut[1443] = 8'd 7; long_chirp_lut[1444] = 8'd 25; long_chirp_lut[1445] = 8'd128; long_chirp_lut[1446] = 8'd231; long_chirp_lut[1447] = 8'd248;
|
||||
long_chirp_lut[1448] = 8'd166; long_chirp_lut[1449] = 8'd 52; long_chirp_lut[1450] = 8'd 1; long_chirp_lut[1451] = 8'd 55; long_chirp_lut[1452] = 8'd169; long_chirp_lut[1453] = 8'd249; long_chirp_lut[1454] = 8'd228; long_chirp_lut[1455] = 8'd123;
|
||||
long_chirp_lut[1456] = 8'd 22; long_chirp_lut[1457] = 8'd 8; long_chirp_lut[1458] = 8'd 94; long_chirp_lut[1459] = 8'd207; long_chirp_lut[1460] = 8'd254; long_chirp_lut[1461] = 8'd195; long_chirp_lut[1462] = 8'd 80; long_chirp_lut[1463] = 8'd 4;
|
||||
long_chirp_lut[1464] = 8'd 31; long_chirp_lut[1465] = 8'd139; long_chirp_lut[1466] = 8'd237; long_chirp_lut[1467] = 8'd243; long_chirp_lut[1468] = 8'd153; long_chirp_lut[1469] = 8'd 41; long_chirp_lut[1470] = 8'd 2; long_chirp_lut[1471] = 8'd 68;
|
||||
long_chirp_lut[1472] = 8'd184; long_chirp_lut[1473] = 8'd253; long_chirp_lut[1474] = 8'd216; long_chirp_lut[1475] = 8'd105; long_chirp_lut[1476] = 8'd 13; long_chirp_lut[1477] = 8'd 17; long_chirp_lut[1478] = 8'd114; long_chirp_lut[1479] = 8'd223;
|
||||
long_chirp_lut[1480] = 8'd251; long_chirp_lut[1481] = 8'd175; long_chirp_lut[1482] = 8'd 59; long_chirp_lut[1483] = 8'd 1; long_chirp_lut[1484] = 8'd 50; long_chirp_lut[1485] = 8'd164; long_chirp_lut[1486] = 8'd248; long_chirp_lut[1487] = 8'd230;
|
||||
long_chirp_lut[1488] = 8'd125; long_chirp_lut[1489] = 8'd 22; long_chirp_lut[1490] = 8'd 9; long_chirp_lut[1491] = 8'd 96; long_chirp_lut[1492] = 8'd210; long_chirp_lut[1493] = 8'd254; long_chirp_lut[1494] = 8'd190; long_chirp_lut[1495] = 8'd 73;
|
||||
long_chirp_lut[1496] = 8'd 2; long_chirp_lut[1497] = 8'd 38; long_chirp_lut[1498] = 8'd150; long_chirp_lut[1499] = 8'd243; long_chirp_lut[1500] = 8'd237; long_chirp_lut[1501] = 8'd139; long_chirp_lut[1502] = 8'd 30; long_chirp_lut[1503] = 8'd 5;
|
||||
long_chirp_lut[1504] = 8'd 84; long_chirp_lut[1505] = 8'd201; long_chirp_lut[1506] = 8'd254; long_chirp_lut[1507] = 8'd200; long_chirp_lut[1508] = 8'd 83; long_chirp_lut[1509] = 8'd 4; long_chirp_lut[1510] = 8'd 31; long_chirp_lut[1511] = 8'd141;
|
||||
long_chirp_lut[1512] = 8'd239; long_chirp_lut[1513] = 8'd241; long_chirp_lut[1514] = 8'd146; long_chirp_lut[1515] = 8'd 35; long_chirp_lut[1516] = 8'd 3; long_chirp_lut[1517] = 8'd 79; long_chirp_lut[1518] = 8'd196; long_chirp_lut[1519] = 8'd254;
|
||||
long_chirp_lut[1520] = 8'd203; long_chirp_lut[1521] = 8'd 87; long_chirp_lut[1522] = 8'd 5; long_chirp_lut[1523] = 8'd 29; long_chirp_lut[1524] = 8'd138; long_chirp_lut[1525] = 8'd238; long_chirp_lut[1526] = 8'd242; long_chirp_lut[1527] = 8'd147;
|
||||
long_chirp_lut[1528] = 8'd 35; long_chirp_lut[1529] = 8'd 3; long_chirp_lut[1530] = 8'd 79; long_chirp_lut[1531] = 8'd197; long_chirp_lut[1532] = 8'd254; long_chirp_lut[1533] = 8'd202; long_chirp_lut[1534] = 8'd 85; long_chirp_lut[1535] = 8'd 5;
|
||||
long_chirp_lut[1536] = 8'd 31; long_chirp_lut[1537] = 8'd142; long_chirp_lut[1538] = 8'd240; long_chirp_lut[1539] = 8'd240; long_chirp_lut[1540] = 8'd142; long_chirp_lut[1541] = 8'd 32; long_chirp_lut[1542] = 8'd 5; long_chirp_lut[1543] = 8'd 85;
|
||||
long_chirp_lut[1544] = 8'd202; long_chirp_lut[1545] = 8'd254; long_chirp_lut[1546] = 8'd195; long_chirp_lut[1547] = 8'd 77; long_chirp_lut[1548] = 8'd 3; long_chirp_lut[1549] = 8'd 38; long_chirp_lut[1550] = 8'd151; long_chirp_lut[1551] = 8'd244;
|
||||
long_chirp_lut[1552] = 8'd235; long_chirp_lut[1553] = 8'd131; long_chirp_lut[1554] = 8'd 24; long_chirp_lut[1555] = 8'd 8; long_chirp_lut[1556] = 8'd 97; long_chirp_lut[1557] = 8'd213; long_chirp_lut[1558] = 8'd253; long_chirp_lut[1559] = 8'd183;
|
||||
long_chirp_lut[1560] = 8'd 64; long_chirp_lut[1561] = 8'd 1; long_chirp_lut[1562] = 8'd 49; long_chirp_lut[1563] = 8'd167; long_chirp_lut[1564] = 8'd250; long_chirp_lut[1565] = 8'd224; long_chirp_lut[1566] = 8'd114; long_chirp_lut[1567] = 8'd 15;
|
||||
long_chirp_lut[1568] = 8'd 16; long_chirp_lut[1569] = 8'd116; long_chirp_lut[1570] = 8'd226; long_chirp_lut[1571] = 8'd249; long_chirp_lut[1572] = 8'd164; long_chirp_lut[1573] = 8'd 47; long_chirp_lut[1574] = 8'd 1; long_chirp_lut[1575] = 8'd 68;
|
||||
long_chirp_lut[1576] = 8'd187; long_chirp_lut[1577] = 8'd254; long_chirp_lut[1578] = 8'd208; long_chirp_lut[1579] = 8'd 90; long_chirp_lut[1580] = 8'd 6; long_chirp_lut[1581] = 8'd 30; long_chirp_lut[1582] = 8'd141; long_chirp_lut[1583] = 8'd240;
|
||||
long_chirp_lut[1584] = 8'd239; long_chirp_lut[1585] = 8'd138; long_chirp_lut[1586] = 8'd 28; long_chirp_lut[1587] = 8'd 7; long_chirp_lut[1588] = 8'd 94; long_chirp_lut[1589] = 8'd211; long_chirp_lut[1590] = 8'd253; long_chirp_lut[1591] = 8'd183;
|
||||
long_chirp_lut[1592] = 8'd 63; long_chirp_lut[1593] = 8'd 1; long_chirp_lut[1594] = 8'd 52; long_chirp_lut[1595] = 8'd171; long_chirp_lut[1596] = 8'd251; long_chirp_lut[1597] = 8'd220; long_chirp_lut[1598] = 8'd105; long_chirp_lut[1599] = 8'd 11;
|
||||
long_chirp_lut[1600] = 8'd 21; long_chirp_lut[1601] = 8'd128; long_chirp_lut[1602] = 8'd234; long_chirp_lut[1603] = 8'd244; long_chirp_lut[1604] = 8'd149; long_chirp_lut[1605] = 8'd 35; long_chirp_lut[1606] = 8'd 4; long_chirp_lut[1607] = 8'd 85;
|
||||
long_chirp_lut[1608] = 8'd204; long_chirp_lut[1609] = 8'd254; long_chirp_lut[1610] = 8'd189; long_chirp_lut[1611] = 8'd 69; long_chirp_lut[1612] = 8'd 1; long_chirp_lut[1613] = 8'd 48; long_chirp_lut[1614] = 8'd167; long_chirp_lut[1615] = 8'd250;
|
||||
long_chirp_lut[1616] = 8'd222; long_chirp_lut[1617] = 8'd107; long_chirp_lut[1618] = 8'd 11; long_chirp_lut[1619] = 8'd 21; long_chirp_lut[1620] = 8'd127; long_chirp_lut[1621] = 8'd234; long_chirp_lut[1622] = 8'd243; long_chirp_lut[1623] = 8'd147;
|
||||
long_chirp_lut[1624] = 8'd 33; long_chirp_lut[1625] = 8'd 5; long_chirp_lut[1626] = 8'd 89; long_chirp_lut[1627] = 8'd208; long_chirp_lut[1628] = 8'd254; long_chirp_lut[1629] = 8'd184; long_chirp_lut[1630] = 8'd 62; long_chirp_lut[1631] = 8'd 1;
|
||||
long_chirp_lut[1632] = 8'd 55; long_chirp_lut[1633] = 8'd176; long_chirp_lut[1634] = 8'd252; long_chirp_lut[1635] = 8'd214; long_chirp_lut[1636] = 8'd 96; long_chirp_lut[1637] = 8'd 7; long_chirp_lut[1638] = 8'd 28; long_chirp_lut[1639] = 8'd141;
|
||||
long_chirp_lut[1640] = 8'd241; long_chirp_lut[1641] = 8'd237; long_chirp_lut[1642] = 8'd132; long_chirp_lut[1643] = 8'd 23; long_chirp_lut[1644] = 8'd 10; long_chirp_lut[1645] = 8'd106; long_chirp_lut[1646] = 8'd221; long_chirp_lut[1647] = 8'd250;
|
||||
long_chirp_lut[1648] = 8'd166; long_chirp_lut[1649] = 8'd 46; long_chirp_lut[1650] = 8'd 2; long_chirp_lut[1651] = 8'd 74; long_chirp_lut[1652] = 8'd196; long_chirp_lut[1653] = 8'd254; long_chirp_lut[1654] = 8'd195; long_chirp_lut[1655] = 8'd 73;
|
||||
long_chirp_lut[1656] = 8'd 2; long_chirp_lut[1657] = 8'd 47; long_chirp_lut[1658] = 8'd167; long_chirp_lut[1659] = 8'd251; long_chirp_lut[1660] = 8'd220; long_chirp_lut[1661] = 8'd103; long_chirp_lut[1662] = 8'd 9; long_chirp_lut[1663] = 8'd 25;
|
||||
long_chirp_lut[1664] = 8'd137; long_chirp_lut[1665] = 8'd240; long_chirp_lut[1666] = 8'd238; long_chirp_lut[1667] = 8'd133; long_chirp_lut[1668] = 8'd 23; long_chirp_lut[1669] = 8'd 11; long_chirp_lut[1670] = 8'd107; long_chirp_lut[1671] = 8'd223;
|
||||
long_chirp_lut[1672] = 8'd249; long_chirp_lut[1673] = 8'd162; long_chirp_lut[1674] = 8'd 42; long_chirp_lut[1675] = 8'd 3; long_chirp_lut[1676] = 8'd 80; long_chirp_lut[1677] = 8'd202; long_chirp_lut[1678] = 8'd254; long_chirp_lut[1679] = 8'd187;
|
||||
long_chirp_lut[1680] = 8'd 64; long_chirp_lut[1681] = 8'd 1; long_chirp_lut[1682] = 8'd 57; long_chirp_lut[1683] = 8'd179; long_chirp_lut[1684] = 8'd253; long_chirp_lut[1685] = 8'd209; long_chirp_lut[1686] = 8'd 88; long_chirp_lut[1687] = 8'd 4;
|
||||
long_chirp_lut[1688] = 8'd 37; long_chirp_lut[1689] = 8'd155; long_chirp_lut[1690] = 8'd247; long_chirp_lut[1691] = 8'd226; long_chirp_lut[1692] = 8'd112; long_chirp_lut[1693] = 8'd 12; long_chirp_lut[1694] = 8'd 22; long_chirp_lut[1695] = 8'd132;
|
||||
long_chirp_lut[1696] = 8'd238; long_chirp_lut[1697] = 8'd239; long_chirp_lut[1698] = 8'd135; long_chirp_lut[1699] = 8'd 23; long_chirp_lut[1700] = 8'd 11; long_chirp_lut[1701] = 8'd109; long_chirp_lut[1702] = 8'd225; long_chirp_lut[1703] = 8'd248;
|
||||
long_chirp_lut[1704] = 8'd157; long_chirp_lut[1705] = 8'd 37; long_chirp_lut[1706] = 8'd 4; long_chirp_lut[1707] = 8'd 88; long_chirp_lut[1708] = 8'd210; long_chirp_lut[1709] = 8'd253; long_chirp_lut[1710] = 8'd176; long_chirp_lut[1711] = 8'd 53;
|
||||
long_chirp_lut[1712] = 8'd 1; long_chirp_lut[1713] = 8'd 70; long_chirp_lut[1714] = 8'd194; long_chirp_lut[1715] = 8'd254; long_chirp_lut[1716] = 8'd193; long_chirp_lut[1717] = 8'd 69; long_chirp_lut[1718] = 8'd 1; long_chirp_lut[1719] = 8'd 54;
|
||||
long_chirp_lut[1720] = 8'd178; long_chirp_lut[1721] = 8'd253; long_chirp_lut[1722] = 8'd208; long_chirp_lut[1723] = 8'd 85; long_chirp_lut[1724] = 8'd 3; long_chirp_lut[1725] = 8'd 41; long_chirp_lut[1726] = 8'd162; long_chirp_lut[1727] = 8'd250;
|
||||
long_chirp_lut[1728] = 8'd220; long_chirp_lut[1729] = 8'd101; long_chirp_lut[1730] = 8'd 8; long_chirp_lut[1731] = 8'd 30; long_chirp_lut[1732] = 8'd146; long_chirp_lut[1733] = 8'd245; long_chirp_lut[1734] = 8'd230; long_chirp_lut[1735] = 8'd116;
|
||||
long_chirp_lut[1736] = 8'd 13; long_chirp_lut[1737] = 8'd 21; long_chirp_lut[1738] = 8'd132; long_chirp_lut[1739] = 8'd239; long_chirp_lut[1740] = 8'd237; long_chirp_lut[1741] = 8'd130; long_chirp_lut[1742] = 8'd 20; long_chirp_lut[1743] = 8'd 14;
|
||||
long_chirp_lut[1744] = 8'd119; long_chirp_lut[1745] = 8'd232; long_chirp_lut[1746] = 8'd243; long_chirp_lut[1747] = 8'd142; long_chirp_lut[1748] = 8'd 27; long_chirp_lut[1749] = 8'd 9; long_chirp_lut[1750] = 8'd107; long_chirp_lut[1751] = 8'd225;
|
||||
long_chirp_lut[1752] = 8'd247; long_chirp_lut[1753] = 8'd153; long_chirp_lut[1754] = 8'd 34; long_chirp_lut[1755] = 8'd 6; long_chirp_lut[1756] = 8'd 97; long_chirp_lut[1757] = 8'd218; long_chirp_lut[1758] = 8'd250; long_chirp_lut[1759] = 8'd162;
|
||||
long_chirp_lut[1760] = 8'd 40; long_chirp_lut[1761] = 8'd 4; long_chirp_lut[1762] = 8'd 88; long_chirp_lut[1763] = 8'd212; long_chirp_lut[1764] = 8'd252; long_chirp_lut[1765] = 8'd171; long_chirp_lut[1766] = 8'd 46; long_chirp_lut[1767] = 8'd 2;
|
||||
long_chirp_lut[1768] = 8'd 81; long_chirp_lut[1769] = 8'd206; long_chirp_lut[1770] = 8'd253; long_chirp_lut[1771] = 8'd177; long_chirp_lut[1772] = 8'd 52; long_chirp_lut[1773] = 8'd 1; long_chirp_lut[1774] = 8'd 75; long_chirp_lut[1775] = 8'd201;
|
||||
long_chirp_lut[1776] = 8'd254; long_chirp_lut[1777] = 8'd182; long_chirp_lut[1778] = 8'd 56; long_chirp_lut[1779] = 8'd 1; long_chirp_lut[1780] = 8'd 71; long_chirp_lut[1781] = 8'd197; long_chirp_lut[1782] = 8'd254; long_chirp_lut[1783] = 8'd186;
|
||||
long_chirp_lut[1784] = 8'd 60; long_chirp_lut[1785] = 8'd 1; long_chirp_lut[1786] = 8'd 67; long_chirp_lut[1787] = 8'd194; long_chirp_lut[1788] = 8'd254; long_chirp_lut[1789] = 8'd189; long_chirp_lut[1790] = 8'd 62; long_chirp_lut[1791] = 8'd 1;
|
||||
long_chirp_lut[1792] = 8'd 65; long_chirp_lut[1793] = 8'd192; long_chirp_lut[1794] = 8'd254; long_chirp_lut[1795] = 8'd191; long_chirp_lut[1796] = 8'd 64; long_chirp_lut[1797] = 8'd 1; long_chirp_lut[1798] = 8'd 64; long_chirp_lut[1799] = 8'd191;
|
||||
long_chirp_lut[1800] = 8'd255; long_chirp_lut[1801] = 8'd191; long_chirp_lut[1802] = 8'd 64; long_chirp_lut[1803] = 8'd 1; long_chirp_lut[1804] = 8'd 64; long_chirp_lut[1805] = 8'd191; long_chirp_lut[1806] = 8'd254; long_chirp_lut[1807] = 8'd190;
|
||||
long_chirp_lut[1808] = 8'd 63; long_chirp_lut[1809] = 8'd 1; long_chirp_lut[1810] = 8'd 66; long_chirp_lut[1811] = 8'd193; long_chirp_lut[1812] = 8'd254; long_chirp_lut[1813] = 8'd188; long_chirp_lut[1814] = 8'd 61; long_chirp_lut[1815] = 8'd 1;
|
||||
long_chirp_lut[1816] = 8'd 68; long_chirp_lut[1817] = 8'd196; long_chirp_lut[1818] = 8'd254; long_chirp_lut[1819] = 8'd185; long_chirp_lut[1820] = 8'd 58; long_chirp_lut[1821] = 8'd 1; long_chirp_lut[1822] = 8'd 72; long_chirp_lut[1823] = 8'd199;
|
||||
long_chirp_lut[1824] = 8'd254; long_chirp_lut[1825] = 8'd181; long_chirp_lut[1826] = 8'd 54; long_chirp_lut[1827] = 8'd 1; long_chirp_lut[1828] = 8'd 77; long_chirp_lut[1829] = 8'd204; long_chirp_lut[1830] = 8'd253; long_chirp_lut[1831] = 8'd175;
|
||||
long_chirp_lut[1832] = 8'd 48; long_chirp_lut[1833] = 8'd 2; long_chirp_lut[1834] = 8'd 83; long_chirp_lut[1835] = 8'd209; long_chirp_lut[1836] = 8'd252; long_chirp_lut[1837] = 8'd168; long_chirp_lut[1838] = 8'd 42; long_chirp_lut[1839] = 8'd 4;
|
||||
long_chirp_lut[1840] = 8'd 91; long_chirp_lut[1841] = 8'd216; long_chirp_lut[1842] = 8'd250; long_chirp_lut[1843] = 8'd159; long_chirp_lut[1844] = 8'd 36; long_chirp_lut[1845] = 8'd 6; long_chirp_lut[1846] = 8'd100; long_chirp_lut[1847] = 8'd222;
|
||||
long_chirp_lut[1848] = 8'd247; long_chirp_lut[1849] = 8'd150; long_chirp_lut[1850] = 8'd 29; long_chirp_lut[1851] = 8'd 9; long_chirp_lut[1852] = 8'd111; long_chirp_lut[1853] = 8'd229; long_chirp_lut[1854] = 8'd243; long_chirp_lut[1855] = 8'd138;
|
||||
long_chirp_lut[1856] = 8'd 22; long_chirp_lut[1857] = 8'd 14; long_chirp_lut[1858] = 8'd123; long_chirp_lut[1859] = 8'd236; long_chirp_lut[1860] = 8'd237; long_chirp_lut[1861] = 8'd125; long_chirp_lut[1862] = 8'd 15; long_chirp_lut[1863] = 8'd 21;
|
||||
long_chirp_lut[1864] = 8'd137; long_chirp_lut[1865] = 8'd243; long_chirp_lut[1866] = 8'd230; long_chirp_lut[1867] = 8'd111; long_chirp_lut[1868] = 8'd 9; long_chirp_lut[1869] = 8'd 30; long_chirp_lut[1870] = 8'd151; long_chirp_lut[1871] = 8'd248;
|
||||
long_chirp_lut[1872] = 8'd220; long_chirp_lut[1873] = 8'd 96; long_chirp_lut[1874] = 8'd 4; long_chirp_lut[1875] = 8'd 41; long_chirp_lut[1876] = 8'd167; long_chirp_lut[1877] = 8'd252; long_chirp_lut[1878] = 8'd208; long_chirp_lut[1879] = 8'd 80;
|
||||
long_chirp_lut[1880] = 8'd 1; long_chirp_lut[1881] = 8'd 54; long_chirp_lut[1882] = 8'd183; long_chirp_lut[1883] = 8'd254; long_chirp_lut[1884] = 8'd193; long_chirp_lut[1885] = 8'd 64; long_chirp_lut[1886] = 8'd 1; long_chirp_lut[1887] = 8'd 70;
|
||||
long_chirp_lut[1888] = 8'd199; long_chirp_lut[1889] = 8'd254; long_chirp_lut[1890] = 8'd176; long_chirp_lut[1891] = 8'd 48; long_chirp_lut[1892] = 8'd 3; long_chirp_lut[1893] = 8'd 88; long_chirp_lut[1894] = 8'd215; long_chirp_lut[1895] = 8'd250;
|
||||
long_chirp_lut[1896] = 8'd157; long_chirp_lut[1897] = 8'd 33; long_chirp_lut[1898] = 8'd 8; long_chirp_lut[1899] = 8'd109; long_chirp_lut[1900] = 8'd229; long_chirp_lut[1901] = 8'd243; long_chirp_lut[1902] = 8'd135; long_chirp_lut[1903] = 8'd 19;
|
||||
long_chirp_lut[1904] = 8'd 18; long_chirp_lut[1905] = 8'd132; long_chirp_lut[1906] = 8'd241; long_chirp_lut[1907] = 8'd231; long_chirp_lut[1908] = 8'd112; long_chirp_lut[1909] = 8'd 9; long_chirp_lut[1910] = 8'd 31; long_chirp_lut[1911] = 8'd155;
|
||||
long_chirp_lut[1912] = 8'd250; long_chirp_lut[1913] = 8'd215; long_chirp_lut[1914] = 8'd 88; long_chirp_lut[1915] = 8'd 2; long_chirp_lut[1916] = 8'd 50; long_chirp_lut[1917] = 8'd179; long_chirp_lut[1918] = 8'd254; long_chirp_lut[1919] = 8'd195;
|
||||
long_chirp_lut[1920] = 8'd 64; long_chirp_lut[1921] = 8'd 1; long_chirp_lut[1922] = 8'd 72; long_chirp_lut[1923] = 8'd202; long_chirp_lut[1924] = 8'd253; long_chirp_lut[1925] = 8'd171; long_chirp_lut[1926] = 8'd 42; long_chirp_lut[1927] = 8'd 4;
|
||||
long_chirp_lut[1928] = 8'd 98; long_chirp_lut[1929] = 8'd223; long_chirp_lut[1930] = 8'd246; long_chirp_lut[1931] = 8'd143; long_chirp_lut[1932] = 8'd 23; long_chirp_lut[1933] = 8'd 15; long_chirp_lut[1934] = 8'd127; long_chirp_lut[1935] = 8'd240;
|
||||
long_chirp_lut[1936] = 8'd233; long_chirp_lut[1937] = 8'd113; long_chirp_lut[1938] = 8'd 9; long_chirp_lut[1939] = 8'd 32; long_chirp_lut[1940] = 8'd157; long_chirp_lut[1941] = 8'd251; long_chirp_lut[1942] = 8'd212; long_chirp_lut[1943] = 8'd 83;
|
||||
long_chirp_lut[1944] = 8'd 2; long_chirp_lut[1945] = 8'd 55; long_chirp_lut[1946] = 8'd186; long_chirp_lut[1947] = 8'd254; long_chirp_lut[1948] = 8'd186; long_chirp_lut[1949] = 8'd 55; long_chirp_lut[1950] = 8'd 2; long_chirp_lut[1951] = 8'd 84;
|
||||
long_chirp_lut[1952] = 8'd213; long_chirp_lut[1953] = 8'd250; long_chirp_lut[1954] = 8'd155; long_chirp_lut[1955] = 8'd 30; long_chirp_lut[1956] = 8'd 10; long_chirp_lut[1957] = 8'd117; long_chirp_lut[1958] = 8'd235; long_chirp_lut[1959] = 8'd237;
|
||||
long_chirp_lut[1960] = 8'd120; long_chirp_lut[1961] = 8'd 11; long_chirp_lut[1962] = 8'd 28; long_chirp_lut[1963] = 8'd153; long_chirp_lut[1964] = 8'd250; long_chirp_lut[1965] = 8'd214; long_chirp_lut[1966] = 8'd 85; long_chirp_lut[1967] = 8'd 2;
|
||||
long_chirp_lut[1968] = 8'd 55; long_chirp_lut[1969] = 8'd187; long_chirp_lut[1970] = 8'd254; long_chirp_lut[1971] = 8'd184; long_chirp_lut[1972] = 8'd 52; long_chirp_lut[1973] = 8'd 2; long_chirp_lut[1974] = 8'd 89; long_chirp_lut[1975] = 8'd218;
|
||||
long_chirp_lut[1976] = 8'd248; long_chirp_lut[1977] = 8'd147; long_chirp_lut[1978] = 8'd 25; long_chirp_lut[1979] = 8'd 14; long_chirp_lut[1980] = 8'd127; long_chirp_lut[1981] = 8'd241; long_chirp_lut[1982] = 8'd230; long_chirp_lut[1983] = 8'd107;
|
||||
long_chirp_lut[1984] = 8'd 7; long_chirp_lut[1985] = 8'd 38; long_chirp_lut[1986] = 8'd167; long_chirp_lut[1987] = 8'd253; long_chirp_lut[1988] = 8'd201; long_chirp_lut[1989] = 8'd 69; long_chirp_lut[1990] = 8'd 1; long_chirp_lut[1991] = 8'd 72;
|
||||
long_chirp_lut[1992] = 8'd204; long_chirp_lut[1993] = 8'd252; long_chirp_lut[1994] = 8'd163; long_chirp_lut[1995] = 8'd 35; long_chirp_lut[1996] = 8'd 8; long_chirp_lut[1997] = 8'd113; long_chirp_lut[1998] = 8'd234; long_chirp_lut[1999] = 8'd237;
|
||||
long_chirp_lut[2000] = 8'd120; long_chirp_lut[2001] = 8'd 11; long_chirp_lut[2002] = 8'd 30; long_chirp_lut[2003] = 8'd157; long_chirp_lut[2004] = 8'd251; long_chirp_lut[2005] = 8'd209; long_chirp_lut[2006] = 8'd 77; long_chirp_lut[2007] = 8'd 1;
|
||||
long_chirp_lut[2008] = 8'd 65; long_chirp_lut[2009] = 8'd199; long_chirp_lut[2010] = 8'd253; long_chirp_lut[2011] = 8'd169; long_chirp_lut[2012] = 8'd 38; long_chirp_lut[2013] = 8'd 7; long_chirp_lut[2014] = 8'd109; long_chirp_lut[2015] = 8'd232;
|
||||
long_chirp_lut[2016] = 8'd239; long_chirp_lut[2017] = 8'd122; long_chirp_lut[2018] = 8'd 11; long_chirp_lut[2019] = 8'd 30; long_chirp_lut[2020] = 8'd157; long_chirp_lut[2021] = 8'd251; long_chirp_lut[2022] = 8'd208; long_chirp_lut[2023] = 8'd 75;
|
||||
long_chirp_lut[2024] = 8'd 1; long_chirp_lut[2025] = 8'd 68; long_chirp_lut[2026] = 8'd201; long_chirp_lut[2027] = 8'd253; long_chirp_lut[2028] = 8'd164; long_chirp_lut[2029] = 8'd 35; long_chirp_lut[2030] = 8'd 9; long_chirp_lut[2031] = 8'd116;
|
||||
long_chirp_lut[2032] = 8'd236; long_chirp_lut[2033] = 8'd235; long_chirp_lut[2034] = 8'd114; long_chirp_lut[2035] = 8'd 8; long_chirp_lut[2036] = 8'd 36; long_chirp_lut[2037] = 8'd167; long_chirp_lut[2038] = 8'd253; long_chirp_lut[2039] = 8'd199;
|
||||
long_chirp_lut[2040] = 8'd 64; long_chirp_lut[2041] = 8'd 1; long_chirp_lut[2042] = 8'd 80; long_chirp_lut[2043] = 8'd213; long_chirp_lut[2044] = 8'd249; long_chirp_lut[2045] = 8'd149; long_chirp_lut[2046] = 8'd 24; long_chirp_lut[2047] = 8'd 16;
|
||||
long_chirp_lut[2048] = 8'd133; long_chirp_lut[2049] = 8'd244; long_chirp_lut[2050] = 8'd224; long_chirp_lut[2051] = 8'd 95; long_chirp_lut[2052] = 8'd 3; long_chirp_lut[2053] = 8'd 52; long_chirp_lut[2054] = 8'd186; long_chirp_lut[2055] = 8'd254;
|
||||
long_chirp_lut[2056] = 8'd179; long_chirp_lut[2057] = 8'd 45; long_chirp_lut[2058] = 8'd 5; long_chirp_lut[2059] = 8'd103; long_chirp_lut[2060] = 8'd229; long_chirp_lut[2061] = 8'd240; long_chirp_lut[2062] = 8'd123; long_chirp_lut[2063] = 8'd 11;
|
||||
long_chirp_lut[2064] = 8'd 31; long_chirp_lut[2065] = 8'd161; long_chirp_lut[2066] = 8'd252; long_chirp_lut[2067] = 8'd202; long_chirp_lut[2068] = 8'd 67; long_chirp_lut[2069] = 8'd 1; long_chirp_lut[2070] = 8'd 79; long_chirp_lut[2071] = 8'd212;
|
||||
long_chirp_lut[2072] = 8'd249; long_chirp_lut[2073] = 8'd147; long_chirp_lut[2074] = 8'd 23; long_chirp_lut[2075] = 8'd 18; long_chirp_lut[2076] = 8'd138; long_chirp_lut[2077] = 8'd246; long_chirp_lut[2078] = 8'd219; long_chirp_lut[2079] = 8'd 87;
|
||||
long_chirp_lut[2080] = 8'd 1; long_chirp_lut[2081] = 8'd 60; long_chirp_lut[2082] = 8'd196; long_chirp_lut[2083] = 8'd253; long_chirp_lut[2084] = 8'd166; long_chirp_lut[2085] = 8'd 35; long_chirp_lut[2086] = 8'd 9; long_chirp_lut[2087] = 8'd120;
|
||||
long_chirp_lut[2088] = 8'd239; long_chirp_lut[2089] = 8'd230; long_chirp_lut[2090] = 8'd104; long_chirp_lut[2091] = 8'd 4; long_chirp_lut[2092] = 8'd 47; long_chirp_lut[2093] = 8'd182; long_chirp_lut[2094] = 8'd254; long_chirp_lut[2095] = 8'd181;
|
||||
long_chirp_lut[2096] = 8'd 46; long_chirp_lut[2097] = 8'd 5; long_chirp_lut[2098] = 8'd106; long_chirp_lut[2099] = 8'd232; long_chirp_lut[2100] = 8'd237; long_chirp_lut[2101] = 8'd116; long_chirp_lut[2102] = 8'd 8; long_chirp_lut[2103] = 8'd 38;
|
||||
long_chirp_lut[2104] = 8'd171; long_chirp_lut[2105] = 8'd254; long_chirp_lut[2106] = 8'd190; long_chirp_lut[2107] = 8'd 54; long_chirp_lut[2108] = 8'd 3; long_chirp_lut[2109] = 8'd 96; long_chirp_lut[2110] = 8'd226; long_chirp_lut[2111] = 8'd242;
|
||||
long_chirp_lut[2112] = 8'd125; long_chirp_lut[2113] = 8'd 11; long_chirp_lut[2114] = 8'd 33; long_chirp_lut[2115] = 8'd164; long_chirp_lut[2116] = 8'd253; long_chirp_lut[2117] = 8'd196; long_chirp_lut[2118] = 8'd 59; long_chirp_lut[2119] = 8'd 2;
|
||||
long_chirp_lut[2120] = 8'd 91; long_chirp_lut[2121] = 8'd223; long_chirp_lut[2122] = 8'd243; long_chirp_lut[2123] = 8'd129; long_chirp_lut[2124] = 8'd 13; long_chirp_lut[2125] = 8'd 31; long_chirp_lut[2126] = 8'd162; long_chirp_lut[2127] = 8'd253;
|
||||
long_chirp_lut[2128] = 8'd198; long_chirp_lut[2129] = 8'd 60; long_chirp_lut[2130] = 8'd 2; long_chirp_lut[2131] = 8'd 90; long_chirp_lut[2132] = 8'd223; long_chirp_lut[2133] = 8'd243; long_chirp_lut[2134] = 8'd128; long_chirp_lut[2135] = 8'd 12;
|
||||
long_chirp_lut[2136] = 8'd 31; long_chirp_lut[2137] = 8'd163; long_chirp_lut[2138] = 8'd253; long_chirp_lut[2139] = 8'd195; long_chirp_lut[2140] = 8'd 58; long_chirp_lut[2141] = 8'd 2; long_chirp_lut[2142] = 8'd 94; long_chirp_lut[2143] = 8'd225;
|
||||
long_chirp_lut[2144] = 8'd242; long_chirp_lut[2145] = 8'd123; long_chirp_lut[2146] = 8'd 10; long_chirp_lut[2147] = 8'd 35; long_chirp_lut[2148] = 8'd169; long_chirp_lut[2149] = 8'd254; long_chirp_lut[2150] = 8'd189; long_chirp_lut[2151] = 8'd 52;
|
||||
long_chirp_lut[2152] = 8'd 4; long_chirp_lut[2153] = 8'd102; long_chirp_lut[2154] = 8'd231; long_chirp_lut[2155] = 8'd237; long_chirp_lut[2156] = 8'd114; long_chirp_lut[2157] = 8'd 7; long_chirp_lut[2158] = 8'd 43; long_chirp_lut[2159] = 8'd179;
|
||||
long_chirp_lut[2160] = 8'd255; long_chirp_lut[2161] = 8'd179; long_chirp_lut[2162] = 8'd 42; long_chirp_lut[2163] = 8'd 7; long_chirp_lut[2164] = 8'd115; long_chirp_lut[2165] = 8'd238; long_chirp_lut[2166] = 8'd230; long_chirp_lut[2167] = 8'd100;
|
||||
long_chirp_lut[2168] = 8'd 3; long_chirp_lut[2169] = 8'd 54; long_chirp_lut[2170] = 8'd193; long_chirp_lut[2171] = 8'd254; long_chirp_lut[2172] = 8'd164; long_chirp_lut[2173] = 8'd 31; long_chirp_lut[2174] = 8'd 13; long_chirp_lut[2175] = 8'd132;
|
||||
long_chirp_lut[2176] = 8'd245; long_chirp_lut[2177] = 8'd218; long_chirp_lut[2178] = 8'd 83; long_chirp_lut[2179] = 8'd 1; long_chirp_lut[2180] = 8'd 71; long_chirp_lut[2181] = 8'd209; long_chirp_lut[2182] = 8'd250; long_chirp_lut[2183] = 8'd144;
|
||||
long_chirp_lut[2184] = 8'd 19; long_chirp_lut[2185] = 8'd 24; long_chirp_lut[2186] = 8'd153; long_chirp_lut[2187] = 8'd252; long_chirp_lut[2188] = 8'd201; long_chirp_lut[2189] = 8'd 62; long_chirp_lut[2190] = 8'd 2; long_chirp_lut[2191] = 8'd 93;
|
||||
long_chirp_lut[2192] = 8'd226; long_chirp_lut[2193] = 8'd241; long_chirp_lut[2194] = 8'd119; long_chirp_lut[2195] = 8'd 8; long_chirp_lut[2196] = 8'd 41; long_chirp_lut[2197] = 8'd178; long_chirp_lut[2198] = 8'd254; long_chirp_lut[2199] = 8'd178;
|
||||
long_chirp_lut[2200] = 8'd 40; long_chirp_lut[2201] = 8'd 8; long_chirp_lut[2202] = 8'd120; long_chirp_lut[2203] = 8'd241; long_chirp_lut[2204] = 8'd225; long_chirp_lut[2205] = 8'd 91; long_chirp_lut[2206] = 8'd 1; long_chirp_lut[2207] = 8'd 65;
|
||||
long_chirp_lut[2208] = 8'd204; long_chirp_lut[2209] = 8'd251; long_chirp_lut[2210] = 8'd148; long_chirp_lut[2211] = 8'd 20; long_chirp_lut[2212] = 8'd 23; long_chirp_lut[2213] = 8'd153; long_chirp_lut[2214] = 8'd252; long_chirp_lut[2215] = 8'd200;
|
||||
long_chirp_lut[2216] = 8'd 60; long_chirp_lut[2217] = 8'd 2; long_chirp_lut[2218] = 8'd 97; long_chirp_lut[2219] = 8'd229; long_chirp_lut[2220] = 8'd237; long_chirp_lut[2221] = 8'd112; long_chirp_lut[2222] = 8'd 5; long_chirp_lut[2223] = 8'd 48;
|
||||
long_chirp_lut[2224] = 8'd187; long_chirp_lut[2225] = 8'd254; long_chirp_lut[2226] = 8'd166; long_chirp_lut[2227] = 8'd 31; long_chirp_lut[2228] = 8'd 14; long_chirp_lut[2229] = 8'd136; long_chirp_lut[2230] = 8'd247; long_chirp_lut[2231] = 8'd212;
|
||||
long_chirp_lut[2232] = 8'd 73; long_chirp_lut[2233] = 8'd 1; long_chirp_lut[2234] = 8'd 83; long_chirp_lut[2235] = 8'd220; long_chirp_lut[2236] = 8'd243; long_chirp_lut[2237] = 8'd124; long_chirp_lut[2238] = 8'd 9; long_chirp_lut[2239] = 8'd 39;
|
||||
long_chirp_lut[2240] = 8'd178; long_chirp_lut[2241] = 8'd254; long_chirp_lut[2242] = 8'd175; long_chirp_lut[2243] = 8'd 37; long_chirp_lut[2244] = 8'd 10; long_chirp_lut[2245] = 8'd128; long_chirp_lut[2246] = 8'd245; long_chirp_lut[2247] = 8'd217;
|
||||
long_chirp_lut[2248] = 8'd 79; long_chirp_lut[2249] = 8'd 1; long_chirp_lut[2250] = 8'd 79; long_chirp_lut[2251] = 8'd217; long_chirp_lut[2252] = 8'd245; long_chirp_lut[2253] = 8'd127; long_chirp_lut[2254] = 8'd 10; long_chirp_lut[2255] = 8'd 38;
|
||||
long_chirp_lut[2256] = 8'd177; long_chirp_lut[2257] = 8'd254; long_chirp_lut[2258] = 8'd175; long_chirp_lut[2259] = 8'd 37; long_chirp_lut[2260] = 8'd 11; long_chirp_lut[2261] = 8'd130; long_chirp_lut[2262] = 8'd246; long_chirp_lut[2263] = 8'd215;
|
||||
long_chirp_lut[2264] = 8'd 76; long_chirp_lut[2265] = 8'd 1; long_chirp_lut[2266] = 8'd 83; long_chirp_lut[2267] = 8'd221; long_chirp_lut[2268] = 8'd242; long_chirp_lut[2269] = 8'd121; long_chirp_lut[2270] = 8'd 8; long_chirp_lut[2271] = 8'd 44;
|
||||
long_chirp_lut[2272] = 8'd184; long_chirp_lut[2273] = 8'd254; long_chirp_lut[2274] = 8'd166; long_chirp_lut[2275] = 8'd 30; long_chirp_lut[2276] = 8'd 16; long_chirp_lut[2277] = 8'd141; long_chirp_lut[2278] = 8'd250; long_chirp_lut[2279] = 8'd206;
|
||||
long_chirp_lut[2280] = 8'd 64; long_chirp_lut[2281] = 8'd 2; long_chirp_lut[2282] = 8'd 97; long_chirp_lut[2283] = 8'd230; long_chirp_lut[2284] = 8'd235; long_chirp_lut[2285] = 8'd105; long_chirp_lut[2286] = 8'd 3; long_chirp_lut[2287] = 8'd 57;
|
||||
long_chirp_lut[2288] = 8'd199; long_chirp_lut[2289] = 8'd251; long_chirp_lut[2290] = 8'd148; long_chirp_lut[2291] = 8'd 19; long_chirp_lut[2292] = 8'd 26; long_chirp_lut[2293] = 8'd161; long_chirp_lut[2294] = 8'd254; long_chirp_lut[2295] = 8'd187;
|
||||
long_chirp_lut[2296] = 8'd 46; long_chirp_lut[2297] = 8'd 7; long_chirp_lut[2298] = 8'd120; long_chirp_lut[2299] = 8'd243; long_chirp_lut[2300] = 8'd220; long_chirp_lut[2301] = 8'd 81; long_chirp_lut[2302] = 8'd 1; long_chirp_lut[2303] = 8'd 81;
|
||||
long_chirp_lut[2304] = 8'd220; long_chirp_lut[2305] = 8'd242; long_chirp_lut[2306] = 8'd119; long_chirp_lut[2307] = 8'd 7; long_chirp_lut[2308] = 8'd 47; long_chirp_lut[2309] = 8'd189; long_chirp_lut[2310] = 8'd253; long_chirp_lut[2311] = 8'd158;
|
||||
long_chirp_lut[2312] = 8'd 24; long_chirp_lut[2313] = 8'd 21; long_chirp_lut[2314] = 8'd153; long_chirp_lut[2315] = 8'd253; long_chirp_lut[2316] = 8'd193; long_chirp_lut[2317] = 8'd 50; long_chirp_lut[2318] = 8'd 5; long_chirp_lut[2319] = 8'd116;
|
||||
long_chirp_lut[2320] = 8'd241; long_chirp_lut[2321] = 8'd222; long_chirp_lut[2322] = 8'd 83; long_chirp_lut[2323] = 8'd 1; long_chirp_lut[2324] = 8'd 80; long_chirp_lut[2325] = 8'd220; long_chirp_lut[2326] = 8'd242; long_chirp_lut[2327] = 8'd118;
|
||||
long_chirp_lut[2328] = 8'd 6; long_chirp_lut[2329] = 8'd 49; long_chirp_lut[2330] = 8'd193; long_chirp_lut[2331] = 8'd253; long_chirp_lut[2332] = 8'd153; long_chirp_lut[2333] = 8'd 20; long_chirp_lut[2334] = 8'd 25; long_chirp_lut[2335] = 8'd161;
|
||||
long_chirp_lut[2336] = 8'd254; long_chirp_lut[2337] = 8'd185; long_chirp_lut[2338] = 8'd 42; long_chirp_lut[2339] = 8'd 9; long_chirp_lut[2340] = 8'd127; long_chirp_lut[2341] = 8'd246; long_chirp_lut[2342] = 8'd212; long_chirp_lut[2343] = 8'd 70;
|
||||
long_chirp_lut[2344] = 8'd 1; long_chirp_lut[2345] = 8'd 95; long_chirp_lut[2346] = 8'd231; long_chirp_lut[2347] = 8'd234; long_chirp_lut[2348] = 8'd100; long_chirp_lut[2349] = 8'd 2; long_chirp_lut[2350] = 8'd 66; long_chirp_lut[2351] = 8'd209;
|
||||
long_chirp_lut[2352] = 8'd247; long_chirp_lut[2353] = 8'd131; long_chirp_lut[2354] = 8'd 10; long_chirp_lut[2355] = 8'd 41; long_chirp_lut[2356] = 8'd183; long_chirp_lut[2357] = 8'd254; long_chirp_lut[2358] = 8'd161; long_chirp_lut[2359] = 8'd 25;
|
||||
long_chirp_lut[2360] = 8'd 21; long_chirp_lut[2361] = 8'd155; long_chirp_lut[2362] = 8'd253; long_chirp_lut[2363] = 8'd188; long_chirp_lut[2364] = 8'd 45; long_chirp_lut[2365] = 8'd 8; long_chirp_lut[2366] = 8'd127; long_chirp_lut[2367] = 8'd246;
|
||||
long_chirp_lut[2368] = 8'd212; long_chirp_lut[2369] = 8'd 68; long_chirp_lut[2370] = 8'd 2; long_chirp_lut[2371] = 8'd 99; long_chirp_lut[2372] = 8'd233; long_chirp_lut[2373] = 8'd230; long_chirp_lut[2374] = 8'd 93; long_chirp_lut[2375] = 8'd 1;
|
||||
long_chirp_lut[2376] = 8'd 73; long_chirp_lut[2377] = 8'd216; long_chirp_lut[2378] = 8'd243; long_chirp_lut[2379] = 8'd119; long_chirp_lut[2380] = 8'd 6; long_chirp_lut[2381] = 8'd 51; long_chirp_lut[2382] = 8'd196; long_chirp_lut[2383] = 8'd252;
|
||||
long_chirp_lut[2384] = 8'd145; long_chirp_lut[2385] = 8'd 15; long_chirp_lut[2386] = 8'd 33; long_chirp_lut[2387] = 8'd174; long_chirp_lut[2388] = 8'd254; long_chirp_lut[2389] = 8'd169; long_chirp_lut[2390] = 8'd 29; long_chirp_lut[2391] = 8'd 18;
|
||||
long_chirp_lut[2392] = 8'd151; long_chirp_lut[2393] = 8'd253; long_chirp_lut[2394] = 8'd190; long_chirp_lut[2395] = 8'd 46; long_chirp_lut[2396] = 8'd 8; long_chirp_lut[2397] = 8'd128; long_chirp_lut[2398] = 8'd247; long_chirp_lut[2399] = 8'd209;
|
||||
long_chirp_lut[2400] = 8'd 64; long_chirp_lut[2401] = 8'd 2; long_chirp_lut[2402] = 8'd106; long_chirp_lut[2403] = 8'd238; long_chirp_lut[2404] = 8'd225; long_chirp_lut[2405] = 8'd 84; long_chirp_lut[2406] = 8'd 1; long_chirp_lut[2407] = 8'd 85;
|
||||
long_chirp_lut[2408] = 8'd226; long_chirp_lut[2409] = 8'd237; long_chirp_lut[2410] = 8'd104; long_chirp_lut[2411] = 8'd 2; long_chirp_lut[2412] = 8'd 66; long_chirp_lut[2413] = 8'd212; long_chirp_lut[2414] = 8'd246; long_chirp_lut[2415] = 8'd123;
|
||||
long_chirp_lut[2416] = 8'd 7; long_chirp_lut[2417] = 8'd 50; long_chirp_lut[2418] = 8'd196; long_chirp_lut[2419] = 8'd251; long_chirp_lut[2420] = 8'd142; long_chirp_lut[2421] = 8'd 14; long_chirp_lut[2422] = 8'd 36; long_chirp_lut[2423] = 8'd180;
|
||||
long_chirp_lut[2424] = 8'd254; long_chirp_lut[2425] = 8'd160; long_chirp_lut[2426] = 8'd 23; long_chirp_lut[2427] = 8'd 25; long_chirp_lut[2428] = 8'd164; long_chirp_lut[2429] = 8'd254; long_chirp_lut[2430] = 8'd176; long_chirp_lut[2431] = 8'd 33;
|
||||
long_chirp_lut[2432] = 8'd 16; long_chirp_lut[2433] = 8'd148; long_chirp_lut[2434] = 8'd252; long_chirp_lut[2435] = 8'd191; long_chirp_lut[2436] = 8'd 45; long_chirp_lut[2437] = 8'd 9; long_chirp_lut[2438] = 8'd132; long_chirp_lut[2439] = 8'd249;
|
||||
long_chirp_lut[2440] = 8'd203; long_chirp_lut[2441] = 8'd 56; long_chirp_lut[2442] = 8'd 5; long_chirp_lut[2443] = 8'd117; long_chirp_lut[2444] = 8'd244; long_chirp_lut[2445] = 8'd214; long_chirp_lut[2446] = 8'd 69; long_chirp_lut[2447] = 8'd 2;
|
||||
long_chirp_lut[2448] = 8'd104; long_chirp_lut[2449] = 8'd237; long_chirp_lut[2450] = 8'd224; long_chirp_lut[2451] = 8'd 81; long_chirp_lut[2452] = 8'd 1; long_chirp_lut[2453] = 8'd 91; long_chirp_lut[2454] = 8'd231; long_chirp_lut[2455] = 8'd231;
|
||||
long_chirp_lut[2456] = 8'd 92; long_chirp_lut[2457] = 8'd 1; long_chirp_lut[2458] = 8'd 80; long_chirp_lut[2459] = 8'd223; long_chirp_lut[2460] = 8'd237; long_chirp_lut[2461] = 8'd103; long_chirp_lut[2462] = 8'd 2; long_chirp_lut[2463] = 8'd 70;
|
||||
long_chirp_lut[2464] = 8'd216; long_chirp_lut[2465] = 8'd242; long_chirp_lut[2466] = 8'd114; long_chirp_lut[2467] = 8'd 4; long_chirp_lut[2468] = 8'd 61; long_chirp_lut[2469] = 8'd209; long_chirp_lut[2470] = 8'd246; long_chirp_lut[2471] = 8'd123;
|
||||
long_chirp_lut[2472] = 8'd 6; long_chirp_lut[2473] = 8'd 54; long_chirp_lut[2474] = 8'd201; long_chirp_lut[2475] = 8'd249; long_chirp_lut[2476] = 8'd132; long_chirp_lut[2477] = 8'd 9; long_chirp_lut[2478] = 8'd 47; long_chirp_lut[2479] = 8'd195;
|
||||
long_chirp_lut[2480] = 8'd251; long_chirp_lut[2481] = 8'd139; long_chirp_lut[2482] = 8'd 11; long_chirp_lut[2483] = 8'd 42; long_chirp_lut[2484] = 8'd189; long_chirp_lut[2485] = 8'd252; long_chirp_lut[2486] = 8'd146; long_chirp_lut[2487] = 8'd 14;
|
||||
long_chirp_lut[2488] = 8'd 37; long_chirp_lut[2489] = 8'd183; long_chirp_lut[2490] = 8'd253; long_chirp_lut[2491] = 8'd152; long_chirp_lut[2492] = 8'd 17; long_chirp_lut[2493] = 8'd 33; long_chirp_lut[2494] = 8'd178; long_chirp_lut[2495] = 8'd254;
|
||||
long_chirp_lut[2496] = 8'd157; long_chirp_lut[2497] = 8'd 19; long_chirp_lut[2498] = 8'd 30; long_chirp_lut[2499] = 8'd174; long_chirp_lut[2500] = 8'd254; long_chirp_lut[2501] = 8'd160; long_chirp_lut[2502] = 8'd 21; long_chirp_lut[2503] = 8'd 28;
|
||||
long_chirp_lut[2504] = 8'd171; long_chirp_lut[2505] = 8'd254; long_chirp_lut[2506] = 8'd163; long_chirp_lut[2507] = 8'd 23; long_chirp_lut[2508] = 8'd 26; long_chirp_lut[2509] = 8'd169; long_chirp_lut[2510] = 8'd254; long_chirp_lut[2511] = 8'd165;
|
||||
long_chirp_lut[2512] = 8'd 24; long_chirp_lut[2513] = 8'd 25; long_chirp_lut[2514] = 8'd167; long_chirp_lut[2515] = 8'd254; long_chirp_lut[2516] = 8'd166; long_chirp_lut[2517] = 8'd 25; long_chirp_lut[2518] = 8'd 25; long_chirp_lut[2519] = 8'd167;
|
||||
long_chirp_lut[2520] = 8'd255; long_chirp_lut[2521] = 8'd167; long_chirp_lut[2522] = 8'd 25; long_chirp_lut[2523] = 8'd 25; long_chirp_lut[2524] = 8'd167; long_chirp_lut[2525] = 8'd254; long_chirp_lut[2526] = 8'd166; long_chirp_lut[2527] = 8'd 24;
|
||||
long_chirp_lut[2528] = 8'd 25; long_chirp_lut[2529] = 8'd168; long_chirp_lut[2530] = 8'd254; long_chirp_lut[2531] = 8'd165; long_chirp_lut[2532] = 8'd 23; long_chirp_lut[2533] = 8'd 27; long_chirp_lut[2534] = 8'd170; long_chirp_lut[2535] = 8'd254;
|
||||
long_chirp_lut[2536] = 8'd162; long_chirp_lut[2537] = 8'd 22; long_chirp_lut[2538] = 8'd 28; long_chirp_lut[2539] = 8'd173; long_chirp_lut[2540] = 8'd254; long_chirp_lut[2541] = 8'd159; long_chirp_lut[2542] = 8'd 20; long_chirp_lut[2543] = 8'd 31;
|
||||
long_chirp_lut[2544] = 8'd177; long_chirp_lut[2545] = 8'd254; long_chirp_lut[2546] = 8'd155; long_chirp_lut[2547] = 8'd 17; long_chirp_lut[2548] = 8'd 34; long_chirp_lut[2549] = 8'd181; long_chirp_lut[2550] = 8'd253; long_chirp_lut[2551] = 8'd150;
|
||||
long_chirp_lut[2552] = 8'd 15; long_chirp_lut[2553] = 8'd 38; long_chirp_lut[2554] = 8'd186; long_chirp_lut[2555] = 8'd252; long_chirp_lut[2556] = 8'd143; long_chirp_lut[2557] = 8'd 12; long_chirp_lut[2558] = 8'd 43; long_chirp_lut[2559] = 8'd192;
|
||||
long_chirp_lut[2560] = 8'd251; long_chirp_lut[2561] = 8'd136; long_chirp_lut[2562] = 8'd 9; long_chirp_lut[2563] = 8'd 48; long_chirp_lut[2564] = 8'd199; long_chirp_lut[2565] = 8'd249; long_chirp_lut[2566] = 8'd128; long_chirp_lut[2567] = 8'd 6;
|
||||
long_chirp_lut[2568] = 8'd 55; long_chirp_lut[2569] = 8'd206; long_chirp_lut[2570] = 8'd246; long_chirp_lut[2571] = 8'd119; long_chirp_lut[2572] = 8'd 4; long_chirp_lut[2573] = 8'd 63; long_chirp_lut[2574] = 8'd213; long_chirp_lut[2575] = 8'd242;
|
||||
long_chirp_lut[2576] = 8'd110; long_chirp_lut[2577] = 8'd 2; long_chirp_lut[2578] = 8'd 72; long_chirp_lut[2579] = 8'd220; long_chirp_lut[2580] = 8'd237; long_chirp_lut[2581] = 8'd 99; long_chirp_lut[2582] = 8'd 1; long_chirp_lut[2583] = 8'd 82;
|
||||
long_chirp_lut[2584] = 8'd228; long_chirp_lut[2585] = 8'd231; long_chirp_lut[2586] = 8'd 88; long_chirp_lut[2587] = 8'd 1; long_chirp_lut[2588] = 8'd 94; long_chirp_lut[2589] = 8'd235; long_chirp_lut[2590] = 8'd224; long_chirp_lut[2591] = 8'd 76;
|
||||
long_chirp_lut[2592] = 8'd 2; long_chirp_lut[2593] = 8'd106; long_chirp_lut[2594] = 8'd241; long_chirp_lut[2595] = 8'd214; long_chirp_lut[2596] = 8'd 64; long_chirp_lut[2597] = 8'd 4; long_chirp_lut[2598] = 8'd120; long_chirp_lut[2599] = 8'd247;
|
||||
long_chirp_lut[2600] = 8'd203; long_chirp_lut[2601] = 8'd 52; long_chirp_lut[2602] = 8'd 8; long_chirp_lut[2603] = 8'd135; long_chirp_lut[2604] = 8'd251; long_chirp_lut[2605] = 8'd191; long_chirp_lut[2606] = 8'd 40; long_chirp_lut[2607] = 8'd 14;
|
||||
long_chirp_lut[2608] = 8'd151; long_chirp_lut[2609] = 8'd254; long_chirp_lut[2610] = 8'd176; long_chirp_lut[2611] = 8'd 29; long_chirp_lut[2612] = 8'd 23; long_chirp_lut[2613] = 8'd167; long_chirp_lut[2614] = 8'd254; long_chirp_lut[2615] = 8'd160;
|
||||
long_chirp_lut[2616] = 8'd 19; long_chirp_lut[2617] = 8'd 34; long_chirp_lut[2618] = 8'd183; long_chirp_lut[2619] = 8'd253; long_chirp_lut[2620] = 8'd142; long_chirp_lut[2621] = 8'd 11; long_chirp_lut[2622] = 8'd 47; long_chirp_lut[2623] = 8'd199;
|
||||
long_chirp_lut[2624] = 8'd248; long_chirp_lut[2625] = 8'd123; long_chirp_lut[2626] = 8'd 4; long_chirp_lut[2627] = 8'd 63; long_chirp_lut[2628] = 8'd214; long_chirp_lut[2629] = 8'd241; long_chirp_lut[2630] = 8'd104; long_chirp_lut[2631] = 8'd 1;
|
||||
long_chirp_lut[2632] = 8'd 81; long_chirp_lut[2633] = 8'd228; long_chirp_lut[2634] = 8'd230; long_chirp_lut[2635] = 8'd 84; long_chirp_lut[2636] = 8'd 1; long_chirp_lut[2637] = 8'd101; long_chirp_lut[2638] = 8'd240; long_chirp_lut[2639] = 8'd216;
|
||||
long_chirp_lut[2640] = 8'd 64; long_chirp_lut[2641] = 8'd 4; long_chirp_lut[2642] = 8'd123; long_chirp_lut[2643] = 8'd248; long_chirp_lut[2644] = 8'd198; long_chirp_lut[2645] = 8'd 46; long_chirp_lut[2646] = 8'd 12; long_chirp_lut[2647] = 8'd146;
|
||||
long_chirp_lut[2648] = 8'd253; long_chirp_lut[2649] = 8'd178; long_chirp_lut[2650] = 8'd 29; long_chirp_lut[2651] = 8'd 23; long_chirp_lut[2652] = 8'd169; long_chirp_lut[2653] = 8'd254; long_chirp_lut[2654] = 8'd155; long_chirp_lut[2655] = 8'd 15;
|
||||
long_chirp_lut[2656] = 8'd 39; long_chirp_lut[2657] = 8'd192; long_chirp_lut[2658] = 8'd250; long_chirp_lut[2659] = 8'd130; long_chirp_lut[2660] = 8'd 6; long_chirp_lut[2661] = 8'd 60; long_chirp_lut[2662] = 8'd213; long_chirp_lut[2663] = 8'd241;
|
||||
long_chirp_lut[2664] = 8'd104; long_chirp_lut[2665] = 8'd 1; long_chirp_lut[2666] = 8'd 83; long_chirp_lut[2667] = 8'd230; long_chirp_lut[2668] = 8'd227; long_chirp_lut[2669] = 8'd 78; long_chirp_lut[2670] = 8'd 2; long_chirp_lut[2671] = 8'd110;
|
||||
long_chirp_lut[2672] = 8'd244; long_chirp_lut[2673] = 8'd207; long_chirp_lut[2674] = 8'd 54; long_chirp_lut[2675] = 8'd 8; long_chirp_lut[2676] = 8'd138; long_chirp_lut[2677] = 8'd252; long_chirp_lut[2678] = 8'd183; long_chirp_lut[2679] = 8'd 32;
|
||||
long_chirp_lut[2680] = 8'd 21; long_chirp_lut[2681] = 8'd167; long_chirp_lut[2682] = 8'd254; long_chirp_lut[2683] = 8'd155; long_chirp_lut[2684] = 8'd 15; long_chirp_lut[2685] = 8'd 41; long_chirp_lut[2686] = 8'd194; long_chirp_lut[2687] = 8'd249;
|
||||
long_chirp_lut[2688] = 8'd125; long_chirp_lut[2689] = 8'd 4; long_chirp_lut[2690] = 8'd 66; long_chirp_lut[2691] = 8'd218; long_chirp_lut[2692] = 8'd237; long_chirp_lut[2693] = 8'd 94; long_chirp_lut[2694] = 8'd 1; long_chirp_lut[2695] = 8'd 95;
|
||||
long_chirp_lut[2696] = 8'd238; long_chirp_lut[2697] = 8'd217; long_chirp_lut[2698] = 8'd 64; long_chirp_lut[2699] = 8'd 5; long_chirp_lut[2700] = 8'd127; long_chirp_lut[2701] = 8'd250; long_chirp_lut[2702] = 8'd191; long_chirp_lut[2703] = 8'd 38;
|
||||
long_chirp_lut[2704] = 8'd 18; long_chirp_lut[2705] = 8'd161; long_chirp_lut[2706] = 8'd254; long_chirp_lut[2707] = 8'd159; long_chirp_lut[2708] = 8'd 17; long_chirp_lut[2709] = 8'd 39; long_chirp_lut[2710] = 8'd193; long_chirp_lut[2711] = 8'd250;
|
||||
long_chirp_lut[2712] = 8'd125; long_chirp_lut[2713] = 8'd 4; long_chirp_lut[2714] = 8'd 67; long_chirp_lut[2715] = 8'd220; long_chirp_lut[2716] = 8'd235; long_chirp_lut[2717] = 8'd 90; long_chirp_lut[2718] = 8'd 1; long_chirp_lut[2719] = 8'd101;
|
||||
long_chirp_lut[2720] = 8'd241; long_chirp_lut[2721] = 8'd211; long_chirp_lut[2722] = 8'd 56; long_chirp_lut[2723] = 8'd 8; long_chirp_lut[2724] = 8'd138; long_chirp_lut[2725] = 8'd253; long_chirp_lut[2726] = 8'd180; long_chirp_lut[2727] = 8'd 29;
|
||||
long_chirp_lut[2728] = 8'd 25; long_chirp_lut[2729] = 8'd175; long_chirp_lut[2730] = 8'd253; long_chirp_lut[2731] = 8'd143; long_chirp_lut[2732] = 8'd 9; long_chirp_lut[2733] = 8'd 53; long_chirp_lut[2734] = 8'd209; long_chirp_lut[2735] = 8'd242;
|
||||
long_chirp_lut[2736] = 8'd104; long_chirp_lut[2737] = 8'd 1; long_chirp_lut[2738] = 8'd 88; long_chirp_lut[2739] = 8'd235; long_chirp_lut[2740] = 8'd220; long_chirp_lut[2741] = 8'd 66; long_chirp_lut[2742] = 8'd 5; long_chirp_lut[2743] = 8'd128;
|
||||
long_chirp_lut[2744] = 8'd251; long_chirp_lut[2745] = 8'd187; long_chirp_lut[2746] = 8'd 34; long_chirp_lut[2747] = 8'd 21; long_chirp_lut[2748] = 8'd169; long_chirp_lut[2749] = 8'd254; long_chirp_lut[2750] = 8'd148; long_chirp_lut[2751] = 8'd 11;
|
||||
long_chirp_lut[2752] = 8'd 50; long_chirp_lut[2753] = 8'd206; long_chirp_lut[2754] = 8'd243; long_chirp_lut[2755] = 8'd105; long_chirp_lut[2756] = 8'd 1; long_chirp_lut[2757] = 8'd 88; long_chirp_lut[2758] = 8'd235; long_chirp_lut[2759] = 8'd219;
|
||||
long_chirp_lut[2760] = 8'd 64; long_chirp_lut[2761] = 8'd 5; long_chirp_lut[2762] = 8'd132; long_chirp_lut[2763] = 8'd252; long_chirp_lut[2764] = 8'd183; long_chirp_lut[2765] = 8'd 30; long_chirp_lut[2766] = 8'd 25; long_chirp_lut[2767] = 8'd176;
|
||||
long_chirp_lut[2768] = 8'd253; long_chirp_lut[2769] = 8'd139; long_chirp_lut[2770] = 8'd 8; long_chirp_lut[2771] = 8'd 58; long_chirp_lut[2772] = 8'd214; long_chirp_lut[2773] = 8'd238; long_chirp_lut[2774] = 8'd 93; long_chirp_lut[2775] = 8'd 1;
|
||||
long_chirp_lut[2776] = 8'd101; long_chirp_lut[2777] = 8'd242; long_chirp_lut[2778] = 8'd208; long_chirp_lut[2779] = 8'd 51; long_chirp_lut[2780] = 8'd 11; long_chirp_lut[2781] = 8'd149; long_chirp_lut[2782] = 8'd254; long_chirp_lut[2783] = 8'd166;
|
||||
long_chirp_lut[2784] = 8'd 19; long_chirp_lut[2785] = 8'd 38; long_chirp_lut[2786] = 8'd194; long_chirp_lut[2787] = 8'd248; long_chirp_lut[2788] = 8'd117; long_chirp_lut[2789] = 8'd 2; long_chirp_lut[2790] = 8'd 79; long_chirp_lut[2791] = 8'd230;
|
||||
long_chirp_lut[2792] = 8'd224; long_chirp_lut[2793] = 8'd 70; long_chirp_lut[2794] = 8'd 4; long_chirp_lut[2795] = 8'd128; long_chirp_lut[2796] = 8'd251; long_chirp_lut[2797] = 8'd184; long_chirp_lut[2798] = 8'd 30; long_chirp_lut[2799] = 8'd 26;
|
||||
long_chirp_lut[2800] = 8'd178; long_chirp_lut[2801] = 8'd253; long_chirp_lut[2802] = 8'd135; long_chirp_lut[2803] = 8'd 6; long_chirp_lut[2804] = 8'd 64; long_chirp_lut[2805] = 8'd220; long_chirp_lut[2806] = 8'd233; long_chirp_lut[2807] = 8'd 83;
|
||||
long_chirp_lut[2808] = 8'd 2; long_chirp_lut[2809] = 8'd114; long_chirp_lut[2810] = 8'd247; long_chirp_lut[2811] = 8'd195; long_chirp_lut[2812] = 8'd 38; long_chirp_lut[2813] = 8'd 19; long_chirp_lut[2814] = 8'd167; long_chirp_lut[2815] = 8'd254;
|
||||
long_chirp_lut[2816] = 8'd145; long_chirp_lut[2817] = 8'd 9; long_chirp_lut[2818] = 8'd 57; long_chirp_lut[2819] = 8'd214; long_chirp_lut[2820] = 8'd237; long_chirp_lut[2821] = 8'd 90; long_chirp_lut[2822] = 8'd 1; long_chirp_lut[2823] = 8'd108;
|
||||
long_chirp_lut[2824] = 8'd245; long_chirp_lut[2825] = 8'd200; long_chirp_lut[2826] = 8'd 42; long_chirp_lut[2827] = 8'd 17; long_chirp_lut[2828] = 8'd164; long_chirp_lut[2829] = 8'd254; long_chirp_lut[2830] = 8'd148; long_chirp_lut[2831] = 8'd 10;
|
||||
long_chirp_lut[2832] = 8'd 55; long_chirp_lut[2833] = 8'd213; long_chirp_lut[2834] = 8'd238; long_chirp_lut[2835] = 8'd 91; long_chirp_lut[2836] = 8'd 1; long_chirp_lut[2837] = 8'd109; long_chirp_lut[2838] = 8'd246; long_chirp_lut[2839] = 8'd199;
|
||||
long_chirp_lut[2840] = 8'd 40; long_chirp_lut[2841] = 8'd 18; long_chirp_lut[2842] = 8'd167; long_chirp_lut[2843] = 8'd254; long_chirp_lut[2844] = 8'd143; long_chirp_lut[2845] = 8'd 8; long_chirp_lut[2846] = 8'd 60; long_chirp_lut[2847] = 8'd217;
|
||||
long_chirp_lut[2848] = 8'd235; long_chirp_lut[2849] = 8'd 84; long_chirp_lut[2850] = 8'd 2; long_chirp_lut[2851] = 8'd116; long_chirp_lut[2852] = 8'd249; long_chirp_lut[2853] = 8'd191; long_chirp_lut[2854] = 8'd 34; long_chirp_lut[2855] = 8'd 24;
|
||||
long_chirp_lut[2856] = 8'd177; long_chirp_lut[2857] = 8'd252; long_chirp_lut[2858] = 8'd132; long_chirp_lut[2859] = 8'd 4; long_chirp_lut[2860] = 8'd 71; long_chirp_lut[2861] = 8'd226; long_chirp_lut[2862] = 8'd227; long_chirp_lut[2863] = 8'd 71;
|
||||
long_chirp_lut[2864] = 8'd 4; long_chirp_lut[2865] = 8'd132; long_chirp_lut[2866] = 8'd252; long_chirp_lut[2867] = 8'd176; long_chirp_lut[2868] = 8'd 23; long_chirp_lut[2869] = 8'd 35; long_chirp_lut[2870] = 8'd193; long_chirp_lut[2871] = 8'd248;
|
||||
long_chirp_lut[2872] = 8'd113; long_chirp_lut[2873] = 8'd 1; long_chirp_lut[2874] = 8'd 89; long_chirp_lut[2875] = 8'd238; long_chirp_lut[2876] = 8'd212; long_chirp_lut[2877] = 8'd 53; long_chirp_lut[2878] = 8'd 12; long_chirp_lut[2879] = 8'd154;
|
||||
long_chirp_lut[2880] = 8'd255; long_chirp_lut[2881] = 8'd154; long_chirp_lut[2882] = 8'd 11; long_chirp_lut[2883] = 8'd 53; long_chirp_lut[2884] = 8'd213; long_chirp_lut[2885] = 8'd237; long_chirp_lut[2886] = 8'd 88; long_chirp_lut[2887] = 8'd 1;
|
||||
long_chirp_lut[2888] = 8'd115; long_chirp_lut[2889] = 8'd249; long_chirp_lut[2890] = 8'd189; long_chirp_lut[2891] = 8'd 32; long_chirp_lut[2892] = 8'd 26; long_chirp_lut[2893] = 8'd182; long_chirp_lut[2894] = 8'd251; long_chirp_lut[2895] = 8'd123;
|
||||
long_chirp_lut[2896] = 8'd 2; long_chirp_lut[2897] = 8'd 81; long_chirp_lut[2898] = 8'd234; long_chirp_lut[2899] = 8'd217; long_chirp_lut[2900] = 8'd 58; long_chirp_lut[2901] = 8'd 9; long_chirp_lut[2902] = 8'd150; long_chirp_lut[2903] = 8'd254;
|
||||
long_chirp_lut[2904] = 8'd157; long_chirp_lut[2905] = 8'd 12; long_chirp_lut[2906] = 8'd 52; long_chirp_lut[2907] = 8'd213; long_chirp_lut[2908] = 8'd237; long_chirp_lut[2909] = 8'd 86; long_chirp_lut[2910] = 8'd 2; long_chirp_lut[2911] = 8'd119;
|
||||
long_chirp_lut[2912] = 8'd250; long_chirp_lut[2913] = 8'd185; long_chirp_lut[2914] = 8'd 28; long_chirp_lut[2915] = 8'd 31; long_chirp_lut[2916] = 8'd189; long_chirp_lut[2917] = 8'd249; long_chirp_lut[2918] = 8'd114; long_chirp_lut[2919] = 8'd 1;
|
||||
long_chirp_lut[2920] = 8'd 91; long_chirp_lut[2921] = 8'd240; long_chirp_lut[2922] = 8'd208; long_chirp_lut[2923] = 8'd 47; long_chirp_lut[2924] = 8'd 16; long_chirp_lut[2925] = 8'd164; long_chirp_lut[2926] = 8'd254; long_chirp_lut[2927] = 8'd140;
|
||||
long_chirp_lut[2928] = 8'd 6; long_chirp_lut[2929] = 8'd 68; long_chirp_lut[2930] = 8'd226; long_chirp_lut[2931] = 8'd225; long_chirp_lut[2932] = 8'd 67; long_chirp_lut[2933] = 8'd 6; long_chirp_lut[2934] = 8'd141; long_chirp_lut[2935] = 8'd254;
|
||||
long_chirp_lut[2936] = 8'd162; long_chirp_lut[2937] = 8'd 14; long_chirp_lut[2938] = 8'd 49; long_chirp_lut[2939] = 8'd211; long_chirp_lut[2940] = 8'd237; long_chirp_lut[2941] = 8'd 86; long_chirp_lut[2942] = 8'd 2; long_chirp_lut[2943] = 8'd121;
|
||||
long_chirp_lut[2944] = 8'd251; long_chirp_lut[2945] = 8'd181; long_chirp_lut[2946] = 8'd 24; long_chirp_lut[2947] = 8'd 35; long_chirp_lut[2948] = 8'd196; long_chirp_lut[2949] = 8'd246; long_chirp_lut[2950] = 8'd104; long_chirp_lut[2951] = 8'd 1;
|
||||
long_chirp_lut[2952] = 8'd104; long_chirp_lut[2953] = 8'd246; long_chirp_lut[2954] = 8'd195; long_chirp_lut[2955] = 8'd 35; long_chirp_lut[2956] = 8'd 25; long_chirp_lut[2957] = 8'd182; long_chirp_lut[2958] = 8'd250; long_chirp_lut[2959] = 8'd119;
|
||||
long_chirp_lut[2960] = 8'd 1; long_chirp_lut[2961] = 8'd 90; long_chirp_lut[2962] = 8'd240; long_chirp_lut[2963] = 8'd207; long_chirp_lut[2964] = 8'd 45; long_chirp_lut[2965] = 8'd 18; long_chirp_lut[2966] = 8'd170; long_chirp_lut[2967] = 8'd253;
|
||||
long_chirp_lut[2968] = 8'd131; long_chirp_lut[2969] = 8'd 3; long_chirp_lut[2970] = 8'd 79; long_chirp_lut[2971] = 8'd234; long_chirp_lut[2972] = 8'd215; long_chirp_lut[2973] = 8'd 53; long_chirp_lut[2974] = 8'd 13; long_chirp_lut[2975] = 8'd161;
|
||||
long_chirp_lut[2976] = 8'd254; long_chirp_lut[2977] = 8'd140; long_chirp_lut[2978] = 8'd 5; long_chirp_lut[2979] = 8'd 71; long_chirp_lut[2980] = 8'd229; long_chirp_lut[2981] = 8'd220; long_chirp_lut[2982] = 8'd 59; long_chirp_lut[2983] = 8'd 10;
|
||||
long_chirp_lut[2984] = 8'd154; long_chirp_lut[2985] = 8'd254; long_chirp_lut[2986] = 8'd146; long_chirp_lut[2987] = 8'd 7; long_chirp_lut[2988] = 8'd 66; long_chirp_lut[2989] = 8'd226; long_chirp_lut[2990] = 8'd224; long_chirp_lut[2991] = 8'd 63;
|
||||
long_chirp_lut[2992] = 8'd 9; long_chirp_lut[2993] = 8'd150; long_chirp_lut[2994] = 8'd254; long_chirp_lut[2995] = 8'd149; long_chirp_lut[2996] = 8'd 8; long_chirp_lut[2997] = 8'd 64; long_chirp_lut[2998] = 8'd225; long_chirp_lut[2999] = 8'd225;
|
||||
long_chirp_lut[3000] = 8'd 64; long_chirp_lut[3001] = 8'd 8; long_chirp_lut[3002] = 8'd150; long_chirp_lut[3003] = 8'd254; long_chirp_lut[3004] = 8'd149; long_chirp_lut[3005] = 8'd 8; long_chirp_lut[3006] = 8'd 65; long_chirp_lut[3007] = 8'd225;
|
||||
long_chirp_lut[3008] = 8'd224; long_chirp_lut[3009] = 8'd 63; long_chirp_lut[3010] = 8'd 9; long_chirp_lut[3011] = 8'd152; long_chirp_lut[3012] = 8'd254; long_chirp_lut[3013] = 8'd146; long_chirp_lut[3014] = 8'd 7; long_chirp_lut[3015] = 8'd 68;
|
||||
long_chirp_lut[3016] = 8'd228; long_chirp_lut[3017] = 8'd221; long_chirp_lut[3018] = 8'd 59; long_chirp_lut[3019] = 8'd 11; long_chirp_lut[3020] = 8'd157; long_chirp_lut[3021] = 8'd254; long_chirp_lut[3022] = 8'd141; long_chirp_lut[3023] = 8'd 5;
|
||||
long_chirp_lut[3024] = 8'd 73; long_chirp_lut[3025] = 8'd232; long_chirp_lut[3026] = 8'd216; long_chirp_lut[3027] = 8'd 53; long_chirp_lut[3028] = 8'd 14; long_chirp_lut[3029] = 8'd165; long_chirp_lut[3030] = 8'd253; long_chirp_lut[3031] = 8'd132;
|
||||
long_chirp_lut[3032] = 8'd 3; long_chirp_lut[3033] = 8'd 82; long_chirp_lut[3034] = 8'd237; long_chirp_lut[3035] = 8'd209; long_chirp_lut[3036] = 8'd 45; long_chirp_lut[3037] = 8'd 19; long_chirp_lut[3038] = 8'd175; long_chirp_lut[3039] = 8'd251;
|
||||
long_chirp_lut[3040] = 8'd120; long_chirp_lut[3041] = 8'd 1; long_chirp_lut[3042] = 8'd 94; long_chirp_lut[3043] = 8'd243; long_chirp_lut[3044] = 8'd198; long_chirp_lut[3045] = 8'd 35; long_chirp_lut[3046] = 8'd 27; long_chirp_lut[3047] = 8'd188;
|
||||
long_chirp_lut[3048] = 8'd247; long_chirp_lut[3049] = 8'd105; long_chirp_lut[3050] = 8'd 1; long_chirp_lut[3051] = 8'd109; long_chirp_lut[3052] = 8'd249; long_chirp_lut[3053] = 8'd184; long_chirp_lut[3054] = 8'd 24; long_chirp_lut[3055] = 8'd 38;
|
||||
long_chirp_lut[3056] = 8'd202; long_chirp_lut[3057] = 8'd241; long_chirp_lut[3058] = 8'd 88; long_chirp_lut[3059] = 8'd 2; long_chirp_lut[3060] = 8'd127; long_chirp_lut[3061] = 8'd253; long_chirp_lut[3062] = 8'd167; long_chirp_lut[3063] = 8'd 14;
|
||||
long_chirp_lut[3064] = 8'd 53; long_chirp_lut[3065] = 8'd218; long_chirp_lut[3066] = 8'd230; long_chirp_lut[3067] = 8'd 69; long_chirp_lut[3068] = 8'd 7; long_chirp_lut[3069] = 8'd149; long_chirp_lut[3070] = 8'd254; long_chirp_lut[3071] = 8'd145;
|
||||
long_chirp_lut[3072] = 8'd 6; long_chirp_lut[3073] = 8'd 73; long_chirp_lut[3074] = 8'd232; long_chirp_lut[3075] = 8'd214; long_chirp_lut[3076] = 8'd 49; long_chirp_lut[3077] = 8'd 17; long_chirp_lut[3078] = 8'd172; long_chirp_lut[3079] = 8'd252;
|
||||
long_chirp_lut[3080] = 8'd120; long_chirp_lut[3081] = 8'd 1; long_chirp_lut[3082] = 8'd 97; long_chirp_lut[3083] = 8'd245; long_chirp_lut[3084] = 8'd193; long_chirp_lut[3085] = 8'd 30; long_chirp_lut[3086] = 8'd 33; long_chirp_lut[3087] = 8'd197;
|
||||
long_chirp_lut[3088] = 8'd243; long_chirp_lut[3089] = 8'd 92; long_chirp_lut[3090] = 8'd 2; long_chirp_lut[3091] = 8'd125; long_chirp_lut[3092] = 8'd253; long_chirp_lut[3093] = 8'd167; long_chirp_lut[3094] = 8'd 14; long_chirp_lut[3095] = 8'd 55;
|
||||
long_chirp_lut[3096] = 8'd220; long_chirp_lut[3097] = 8'd227; long_chirp_lut[3098] = 8'd 64; long_chirp_lut[3099] = 8'd 9; long_chirp_lut[3100] = 8'd157; long_chirp_lut[3101] = 8'd254; long_chirp_lut[3102] = 8'd135; long_chirp_lut[3103] = 8'd 3;
|
||||
long_chirp_lut[3104] = 8'd 84; long_chirp_lut[3105] = 8'd240; long_chirp_lut[3106] = 8'd203; long_chirp_lut[3107] = 8'd 37; long_chirp_lut[3108] = 8'd 26; long_chirp_lut[3109] = 8'd189; long_chirp_lut[3110] = 8'd246; long_chirp_lut[3111] = 8'd100;
|
||||
long_chirp_lut[3112] = 8'd 1; long_chirp_lut[3113] = 8'd120; long_chirp_lut[3114] = 8'd252; long_chirp_lut[3115] = 8'd171; long_chirp_lut[3116] = 8'd 15; long_chirp_lut[3117] = 8'd 53; long_chirp_lut[3118] = 8'd219; long_chirp_lut[3119] = 8'd228;
|
||||
long_chirp_lut[3120] = 8'd 64; long_chirp_lut[3121] = 8'd 10; long_chirp_lut[3122] = 8'd158; long_chirp_lut[3123] = 8'd254; long_chirp_lut[3124] = 8'd132; long_chirp_lut[3125] = 8'd 2; long_chirp_lut[3126] = 8'd 89; long_chirp_lut[3127] = 8'd242;
|
||||
long_chirp_lut[3128] = 8'd198; long_chirp_lut[3129] = 8'd 32; long_chirp_lut[3130] = 8'd 31; long_chirp_lut[3131] = 8'd197; long_chirp_lut[3132] = 8'd242; long_chirp_lut[3133] = 8'd 90; long_chirp_lut[3134] = 8'd 2; long_chirp_lut[3135] = 8'd132;
|
||||
long_chirp_lut[3136] = 8'd254; long_chirp_lut[3137] = 8'd157; long_chirp_lut[3138] = 8'd 9; long_chirp_lut[3139] = 8'd 66; long_chirp_lut[3140] = 8'd229; long_chirp_lut[3141] = 8'd216; long_chirp_lut[3142] = 8'd 49; long_chirp_lut[3143] = 8'd 18;
|
||||
long_chirp_lut[3144] = 8'd177; long_chirp_lut[3145] = 8'd250; long_chirp_lut[3146] = 8'd111; long_chirp_lut[3147] = 8'd 1; long_chirp_lut[3148] = 8'd111; long_chirp_lut[3149] = 8'd250; long_chirp_lut[3150] = 8'd176; long_chirp_lut[3151] = 8'd 18;
|
||||
long_chirp_lut[3152] = 8'd 50; long_chirp_lut[3153] = 8'd217; long_chirp_lut[3154] = 8'd228; long_chirp_lut[3155] = 8'd 64; long_chirp_lut[3156] = 8'd 10; long_chirp_lut[3157] = 8'd161; long_chirp_lut[3158] = 8'd253; long_chirp_lut[3159] = 8'd126;
|
||||
long_chirp_lut[3160] = 8'd 1; long_chirp_lut[3161] = 8'd 97; long_chirp_lut[3162] = 8'd246; long_chirp_lut[3163] = 8'd188; long_chirp_lut[3164] = 8'd 25; long_chirp_lut[3165] = 8'd 41; long_chirp_lut[3166] = 8'd209; long_chirp_lut[3167] = 8'd235;
|
||||
long_chirp_lut[3168] = 8'd 73; long_chirp_lut[3169] = 8'd 7; long_chirp_lut[3170] = 8'd151; long_chirp_lut[3171] = 8'd254; long_chirp_lut[3172] = 8'd135; long_chirp_lut[3173] = 8'd 3; long_chirp_lut[3174] = 8'd 89; long_chirp_lut[3175] = 8'd243;
|
||||
long_chirp_lut[3176] = 8'd195; long_chirp_lut[3177] = 8'd 29; long_chirp_lut[3178] = 8'd 36; long_chirp_lut[3179] = 8'd204; long_chirp_lut[3180] = 8'd237; long_chirp_lut[3181] = 8'd 78; long_chirp_lut[3182] = 8'd 5; long_chirp_lut[3183] = 8'd148;
|
||||
long_chirp_lut[3184] = 8'd254; long_chirp_lut[3185] = 8'd138; long_chirp_lut[3186] = 8'd 3; long_chirp_lut[3187] = 8'd 87; long_chirp_lut[3188] = 8'd242; long_chirp_lut[3189] = 8'd195; long_chirp_lut[3190] = 8'd 29; long_chirp_lut[3191] = 8'd 36;
|
||||
long_chirp_lut[3192] = 8'd204; long_chirp_lut[3193] = 8'd237; long_chirp_lut[3194] = 8'd 77; long_chirp_lut[3195] = 8'd 6; long_chirp_lut[3196] = 8'd150; long_chirp_lut[3197] = 8'd254; long_chirp_lut[3198] = 8'd135; long_chirp_lut[3199] = 8'd 2;
|
||||
long_chirp_lut[3200] = 8'd 91; long_chirp_lut[3201] = 8'd244; long_chirp_lut[3202] = 8'd191; long_chirp_lut[3203] = 8'd 26; long_chirp_lut[3204] = 8'd 41; long_chirp_lut[3205] = 8'd209; long_chirp_lut[3206] = 8'd233; long_chirp_lut[3207] = 8'd 70;
|
||||
long_chirp_lut[3208] = 8'd 9; long_chirp_lut[3209] = 8'd158; long_chirp_lut[3210] = 8'd253; long_chirp_lut[3211] = 8'd125; long_chirp_lut[3212] = 8'd 1; long_chirp_lut[3213] = 8'd101; long_chirp_lut[3214] = 8'd248; long_chirp_lut[3215] = 8'd181;
|
||||
long_chirp_lut[3216] = 8'd 19; long_chirp_lut[3217] = 8'd 50; long_chirp_lut[3218] = 8'd219; long_chirp_lut[3219] = 8'd225; long_chirp_lut[3220] = 8'd 58; long_chirp_lut[3221] = 8'd 14; long_chirp_lut[3222] = 8'd172; long_chirp_lut[3223] = 8'd251;
|
||||
long_chirp_lut[3224] = 8'd110; long_chirp_lut[3225] = 8'd 1; long_chirp_lut[3226] = 8'd118; long_chirp_lut[3227] = 8'd252; long_chirp_lut[3228] = 8'd164; long_chirp_lut[3229] = 8'd 11; long_chirp_lut[3230] = 8'd 66; long_chirp_lut[3231] = 8'd231;
|
||||
long_chirp_lut[3232] = 8'd212; long_chirp_lut[3233] = 8'd 42; long_chirp_lut[3234] = 8'd 25; long_chirp_lut[3235] = 8'd191; long_chirp_lut[3236] = 8'd243; long_chirp_lut[3237] = 8'd 88; long_chirp_lut[3238] = 8'd 3; long_chirp_lut[3239] = 8'd141;
|
||||
long_chirp_lut[3240] = 8'd255; long_chirp_lut[3241] = 8'd141; long_chirp_lut[3242] = 8'd 3; long_chirp_lut[3243] = 8'd 88; long_chirp_lut[3244] = 8'd244; long_chirp_lut[3245] = 8'd191; long_chirp_lut[3246] = 8'd 24; long_chirp_lut[3247] = 8'd 43;
|
||||
long_chirp_lut[3248] = 8'd213; long_chirp_lut[3249] = 8'd229; long_chirp_lut[3250] = 8'd 62; long_chirp_lut[3251] = 8'd 12; long_chirp_lut[3252] = 8'd169; long_chirp_lut[3253] = 8'd251; long_chirp_lut[3254] = 8'd111; long_chirp_lut[3255] = 8'd 1;
|
||||
long_chirp_lut[3256] = 8'd119; long_chirp_lut[3257] = 8'd253; long_chirp_lut[3258] = 8'd161; long_chirp_lut[3259] = 8'd 9; long_chirp_lut[3260] = 8'd 71; long_chirp_lut[3261] = 8'd235; long_chirp_lut[3262] = 8'd206; long_chirp_lut[3263] = 8'd 36;
|
||||
long_chirp_lut[3264] = 8'd 31; long_chirp_lut[3265] = 8'd201; long_chirp_lut[3266] = 8'd238; long_chirp_lut[3267] = 8'd 76; long_chirp_lut[3268] = 8'd 7; long_chirp_lut[3269] = 8'd156; long_chirp_lut[3270] = 8'd253; long_chirp_lut[3271] = 8'd123;
|
||||
long_chirp_lut[3272] = 8'd 1; long_chirp_lut[3273] = 8'd108; long_chirp_lut[3274] = 8'd251; long_chirp_lut[3275] = 8'd171; long_chirp_lut[3276] = 8'd 13; long_chirp_lut[3277] = 8'd 63; long_chirp_lut[3278] = 8'd230; long_chirp_lut[3279] = 8'd211;
|
||||
long_chirp_lut[3280] = 8'd 40; long_chirp_lut[3281] = 8'd 27; long_chirp_lut[3282] = 8'd196; long_chirp_lut[3283] = 8'd240; long_chirp_lut[3284] = 8'd 80; long_chirp_lut[3285] = 8'd 6; long_chirp_lut[3286] = 8'd153; long_chirp_lut[3287] = 8'd254;
|
||||
long_chirp_lut[3288] = 8'd125; long_chirp_lut[3289] = 8'd 1; long_chirp_lut[3290] = 8'd107; long_chirp_lut[3291] = 8'd251; long_chirp_lut[3292] = 8'd170; long_chirp_lut[3293] = 8'd 12; long_chirp_lut[3294] = 8'd 65; long_chirp_lut[3295] = 8'd232;
|
||||
long_chirp_lut[3296] = 8'd209; long_chirp_lut[3297] = 8'd 38; long_chirp_lut[3298] = 8'd 30; long_chirp_lut[3299] = 8'd200; long_chirp_lut[3300] = 8'd237; long_chirp_lut[3301] = 8'd 74; long_chirp_lut[3302] = 8'd 8; long_chirp_lut[3303] = 8'd161;
|
||||
long_chirp_lut[3304] = 8'd253; long_chirp_lut[3305] = 8'd116; long_chirp_lut[3306] = 8'd 1; long_chirp_lut[3307] = 8'd117; long_chirp_lut[3308] = 8'd253; long_chirp_lut[3309] = 8'd159; long_chirp_lut[3310] = 8'd 8; long_chirp_lut[3311] = 8'd 76;
|
||||
long_chirp_lut[3312] = 8'd239; long_chirp_lut[3313] = 8'd198; long_chirp_lut[3314] = 8'd 28; long_chirp_lut[3315] = 8'd 41; long_chirp_lut[3316] = 8'd213; long_chirp_lut[3317] = 8'd228; long_chirp_lut[3318] = 8'd 59; long_chirp_lut[3319] = 8'd 15;
|
||||
long_chirp_lut[3320] = 8'd178; long_chirp_lut[3321] = 8'd248; long_chirp_lut[3322] = 8'd 97; long_chirp_lut[3323] = 8'd 2; long_chirp_lut[3324] = 8'd138; long_chirp_lut[3325] = 8'd254; long_chirp_lut[3326] = 8'd137; long_chirp_lut[3327] = 8'd 2;
|
||||
long_chirp_lut[3328] = 8'd 98; long_chirp_lut[3329] = 8'd248; long_chirp_lut[3330] = 8'd176; long_chirp_lut[3331] = 8'd 14; long_chirp_lut[3332] = 8'd 61; long_chirp_lut[3333] = 8'd230; long_chirp_lut[3334] = 8'd210; long_chirp_lut[3335] = 8'd 37;
|
||||
long_chirp_lut[3336] = 8'd 31; long_chirp_lut[3337] = 8'd203; long_chirp_lut[3338] = 8'd235; long_chirp_lut[3339] = 8'd 69; long_chirp_lut[3340] = 8'd 11; long_chirp_lut[3341] = 8'd169; long_chirp_lut[3342] = 8'd250; long_chirp_lut[3343] = 8'd105;
|
||||
long_chirp_lut[3344] = 8'd 1; long_chirp_lut[3345] = 8'd132; long_chirp_lut[3346] = 8'd254; long_chirp_lut[3347] = 8'd142; long_chirp_lut[3348] = 8'd 3; long_chirp_lut[3349] = 8'd 95; long_chirp_lut[3350] = 8'd247; long_chirp_lut[3351] = 8'd178;
|
||||
long_chirp_lut[3352] = 8'd 15; long_chirp_lut[3353] = 8'd 61; long_chirp_lut[3354] = 8'd231; long_chirp_lut[3355] = 8'd209; long_chirp_lut[3356] = 8'd 36; long_chirp_lut[3357] = 8'd 33; long_chirp_lut[3358] = 8'd206; long_chirp_lut[3359] = 8'd233;
|
||||
long_chirp_lut[3360] = 8'd 64; long_chirp_lut[3361] = 8'd 13; long_chirp_lut[3362] = 8'd175; long_chirp_lut[3363] = 8'd248; long_chirp_lut[3364] = 8'd 96; long_chirp_lut[3365] = 8'd 3; long_chirp_lut[3366] = 8'd141; long_chirp_lut[3367] = 8'd254;
|
||||
long_chirp_lut[3368] = 8'd131; long_chirp_lut[3369] = 8'd 1; long_chirp_lut[3370] = 8'd107; long_chirp_lut[3371] = 8'd251; long_chirp_lut[3372] = 8'd164; long_chirp_lut[3373] = 8'd 9; long_chirp_lut[3374] = 8'd 75; long_chirp_lut[3375] = 8'd240;
|
||||
long_chirp_lut[3376] = 8'd195; long_chirp_lut[3377] = 8'd 24; long_chirp_lut[3378] = 8'd 47; long_chirp_lut[3379] = 8'd220; long_chirp_lut[3380] = 8'd220; long_chirp_lut[3381] = 8'd 46; long_chirp_lut[3382] = 8'd 25; long_chirp_lut[3383] = 8'd196;
|
||||
long_chirp_lut[3384] = 8'd239; long_chirp_lut[3385] = 8'd 73; long_chirp_lut[3386] = 8'd 9; long_chirp_lut[3387] = 8'd167; long_chirp_lut[3388] = 8'd250; long_chirp_lut[3389] = 8'd103; long_chirp_lut[3390] = 8'd 2; long_chirp_lut[3391] = 8'd136;
|
||||
long_chirp_lut[3392] = 8'd254; long_chirp_lut[3393] = 8'd134; long_chirp_lut[3394] = 8'd 1; long_chirp_lut[3395] = 8'd106; long_chirp_lut[3396] = 8'd251; long_chirp_lut[3397] = 8'd164; long_chirp_lut[3398] = 8'd 8; long_chirp_lut[3399] = 8'd 77;
|
||||
long_chirp_lut[3400] = 8'd241; long_chirp_lut[3401] = 8'd191; long_chirp_lut[3402] = 8'd 21; long_chirp_lut[3403] = 8'd 52; long_chirp_lut[3404] = 8'd225; long_chirp_lut[3405] = 8'd214; long_chirp_lut[3406] = 8'd 40; long_chirp_lut[3407] = 8'd 31;
|
||||
long_chirp_lut[3408] = 8'd204; long_chirp_lut[3409] = 8'd233; long_chirp_lut[3410] = 8'd 62; long_chirp_lut[3411] = 8'd 15; long_chirp_lut[3412] = 8'd180; long_chirp_lut[3413] = 8'd246; long_chirp_lut[3414] = 8'd 88; long_chirp_lut[3415] = 8'd 5;
|
||||
long_chirp_lut[3416] = 8'd154; long_chirp_lut[3417] = 8'd253; long_chirp_lut[3418] = 8'd114; long_chirp_lut[3419] = 8'd 1; long_chirp_lut[3420] = 8'd127; long_chirp_lut[3421] = 8'd254; long_chirp_lut[3422] = 8'd141; long_chirp_lut[3423] = 8'd 2;
|
||||
long_chirp_lut[3424] = 8'd101; long_chirp_lut[3425] = 8'd250; long_chirp_lut[3426] = 8'd166; long_chirp_lut[3427] = 8'd 9; long_chirp_lut[3428] = 8'd 77; long_chirp_lut[3429] = 8'd241; long_chirp_lut[3430] = 8'd189; long_chirp_lut[3431] = 8'd 20;
|
||||
long_chirp_lut[3432] = 8'd 55; long_chirp_lut[3433] = 8'd228; long_chirp_lut[3434] = 8'd210; long_chirp_lut[3435] = 8'd 35; long_chirp_lut[3436] = 8'd 36; long_chirp_lut[3437] = 8'd212; long_chirp_lut[3438] = 8'd227; long_chirp_lut[3439] = 8'd 53;
|
||||
long_chirp_lut[3440] = 8'd 21; long_chirp_lut[3441] = 8'd192; long_chirp_lut[3442] = 8'd240; long_chirp_lut[3443] = 8'd 73; long_chirp_lut[3444] = 8'd 10; long_chirp_lut[3445] = 8'd171; long_chirp_lut[3446] = 8'd249; long_chirp_lut[3447] = 8'd 94;
|
||||
long_chirp_lut[3448] = 8'd 4; long_chirp_lut[3449] = 8'd150; long_chirp_lut[3450] = 8'd253; long_chirp_lut[3451] = 8'd116; long_chirp_lut[3452] = 8'd 1; long_chirp_lut[3453] = 8'd128; long_chirp_lut[3454] = 8'd254; long_chirp_lut[3455] = 8'd138;
|
||||
long_chirp_lut[3456] = 8'd 2; long_chirp_lut[3457] = 8'd106; long_chirp_lut[3458] = 8'd252; long_chirp_lut[3459] = 8'd159; long_chirp_lut[3460] = 8'd 6; long_chirp_lut[3461] = 8'd 86; long_chirp_lut[3462] = 8'd246; long_chirp_lut[3463] = 8'd178;
|
||||
long_chirp_lut[3464] = 8'd 13; long_chirp_lut[3465] = 8'd 68; long_chirp_lut[3466] = 8'd237; long_chirp_lut[3467] = 8'd196; long_chirp_lut[3468] = 8'd 23; long_chirp_lut[3469] = 8'd 51; long_chirp_lut[3470] = 8'd226; long_chirp_lut[3471] = 8'd211;
|
||||
long_chirp_lut[3472] = 8'd 35; long_chirp_lut[3473] = 8'd 37; long_chirp_lut[3474] = 8'd213; long_chirp_lut[3475] = 8'd224; long_chirp_lut[3476] = 8'd 49; long_chirp_lut[3477] = 8'd 25; long_chirp_lut[3478] = 8'd199; long_chirp_lut[3479] = 8'd235;
|
||||
long_chirp_lut[3480] = 8'd 64; long_chirp_lut[3481] = 8'd 15; long_chirp_lut[3482] = 8'd183; long_chirp_lut[3483] = 8'd243; long_chirp_lut[3484] = 8'd 80; long_chirp_lut[3485] = 8'd 8; long_chirp_lut[3486] = 8'd167; long_chirp_lut[3487] = 8'd249;
|
||||
long_chirp_lut[3488] = 8'd 96; long_chirp_lut[3489] = 8'd 4; long_chirp_lut[3490] = 8'd151; long_chirp_lut[3491] = 8'd253; long_chirp_lut[3492] = 8'd112; long_chirp_lut[3493] = 8'd 1; long_chirp_lut[3494] = 8'd136; long_chirp_lut[3495] = 8'd254;
|
||||
long_chirp_lut[3496] = 8'd127; long_chirp_lut[3497] = 8'd 1; long_chirp_lut[3498] = 8'd120; long_chirp_lut[3499] = 8'd254; long_chirp_lut[3500] = 8'd142; long_chirp_lut[3501] = 8'd 2; long_chirp_lut[3502] = 8'd106; long_chirp_lut[3503] = 8'd252;
|
||||
long_chirp_lut[3504] = 8'd157; long_chirp_lut[3505] = 8'd 5; long_chirp_lut[3506] = 8'd 92; long_chirp_lut[3507] = 8'd248; long_chirp_lut[3508] = 8'd170; long_chirp_lut[3509] = 8'd 9; long_chirp_lut[3510] = 8'd 79; long_chirp_lut[3511] = 8'd244;
|
||||
long_chirp_lut[3512] = 8'd182; long_chirp_lut[3513] = 8'd 14; long_chirp_lut[3514] = 8'd 67; long_chirp_lut[3515] = 8'd238; long_chirp_lut[3516] = 8'd193; long_chirp_lut[3517] = 8'd 20; long_chirp_lut[3518] = 8'd 57; long_chirp_lut[3519] = 8'd231;
|
||||
long_chirp_lut[3520] = 8'd203; long_chirp_lut[3521] = 8'd 27; long_chirp_lut[3522] = 8'd 47; long_chirp_lut[3523] = 8'd224; long_chirp_lut[3524] = 8'd212; long_chirp_lut[3525] = 8'd 35; long_chirp_lut[3526] = 8'd 39; long_chirp_lut[3527] = 8'd216;
|
||||
long_chirp_lut[3528] = 8'd220; long_chirp_lut[3529] = 8'd 43; long_chirp_lut[3530] = 8'd 31; long_chirp_lut[3531] = 8'd209; long_chirp_lut[3532] = 8'd227; long_chirp_lut[3533] = 8'd 50; long_chirp_lut[3534] = 8'd 25; long_chirp_lut[3535] = 8'd201;
|
||||
long_chirp_lut[3536] = 8'd233; long_chirp_lut[3537] = 8'd 58; long_chirp_lut[3538] = 8'd 20; long_chirp_lut[3539] = 8'd193; long_chirp_lut[3540] = 8'd237; long_chirp_lut[3541] = 8'd 66; long_chirp_lut[3542] = 8'd 15; long_chirp_lut[3543] = 8'd185;
|
||||
long_chirp_lut[3544] = 8'd242; long_chirp_lut[3545] = 8'd 73; long_chirp_lut[3546] = 8'd 12; long_chirp_lut[3547] = 8'd178; long_chirp_lut[3548] = 8'd245; long_chirp_lut[3549] = 8'd 81; long_chirp_lut[3550] = 8'd 9; long_chirp_lut[3551] = 8'd171;
|
||||
long_chirp_lut[3552] = 8'd247; long_chirp_lut[3553] = 8'd 87; long_chirp_lut[3554] = 8'd 6; long_chirp_lut[3555] = 8'd164; long_chirp_lut[3556] = 8'd249; long_chirp_lut[3557] = 8'd 94; long_chirp_lut[3558] = 8'd 5; long_chirp_lut[3559] = 8'd158;
|
||||
long_chirp_lut[3560] = 8'd251; long_chirp_lut[3561] = 8'd100; long_chirp_lut[3562] = 8'd 3; long_chirp_lut[3563] = 8'd153; long_chirp_lut[3564] = 8'd252; long_chirp_lut[3565] = 8'd105; long_chirp_lut[3566] = 8'd 2; long_chirp_lut[3567] = 8'd148;
|
||||
long_chirp_lut[3568] = 8'd253; long_chirp_lut[3569] = 8'd110; long_chirp_lut[3570] = 8'd 2; long_chirp_lut[3571] = 8'd143; long_chirp_lut[3572] = 8'd254; long_chirp_lut[3573] = 8'd114; long_chirp_lut[3574] = 8'd 1; long_chirp_lut[3575] = 8'd139;
|
||||
long_chirp_lut[3576] = 8'd254; long_chirp_lut[3577] = 8'd118; long_chirp_lut[3578] = 8'd 1; long_chirp_lut[3579] = 8'd136; long_chirp_lut[3580] = 8'd254; long_chirp_lut[3581] = 8'd121; long_chirp_lut[3582] = 8'd 1; long_chirp_lut[3583] = 8'd133;
|
||||
long_chirp_lut[3584] = 8'd254; long_chirp_lut[3585] = 8'd123; long_chirp_lut[3586] = 8'd 1; long_chirp_lut[3587] = 8'd131; long_chirp_lut[3588] = 8'd254; long_chirp_lut[3589] = 8'd125; long_chirp_lut[3590] = 8'd 1; long_chirp_lut[3591] = 8'd129;
|
||||
long_chirp_lut[3592] = 8'd254; long_chirp_lut[3593] = 8'd127; long_chirp_lut[3594] = 8'd 1; long_chirp_lut[3595] = 8'd128; long_chirp_lut[3596] = 8'd254; long_chirp_lut[3597] = 8'd127; long_chirp_lut[3598] = 8'd 1; long_chirp_lut[3599] = 8'd128;
|
||||
|
||||
// Complete Short PLFM chirp LUT (0.5us, 30MHz to 10MHz)
|
||||
short_chirp_lut[ 0] = 8'd255; short_chirp_lut[ 1] = 8'd237; short_chirp_lut[ 2] = 8'd187; short_chirp_lut[ 3] = 8'd118; short_chirp_lut[ 4] = 8'd 49; short_chirp_lut[ 5] = 8'd 6; short_chirp_lut[ 6] = 8'd 7; short_chirp_lut[ 7] = 8'd 54;
|
||||
short_chirp_lut[ 8] = 8'd132; short_chirp_lut[ 9] = 8'd210; short_chirp_lut[10] = 8'd253; short_chirp_lut[11] = 8'd237; short_chirp_lut[12] = 8'd167; short_chirp_lut[13] = 8'd 75; short_chirp_lut[14] = 8'd 10; short_chirp_lut[15] = 8'd 10;
|
||||
short_chirp_lut[16] = 8'd 80; short_chirp_lut[17] = 8'd180; short_chirp_lut[18] = 8'd248; short_chirp_lut[19] = 8'd237; short_chirp_lut[20] = 8'd150; short_chirp_lut[21] = 8'd 45; short_chirp_lut[22] = 8'd 1; short_chirp_lut[23] = 8'd 54;
|
||||
short_chirp_lut[24] = 8'd167; short_chirp_lut[25] = 8'd249; short_chirp_lut[26] = 8'd228; short_chirp_lut[27] = 8'd118; short_chirp_lut[28] = 8'd 15; short_chirp_lut[29] = 8'd 18; short_chirp_lut[30] = 8'd127; short_chirp_lut[31] = 8'd238;
|
||||
short_chirp_lut[32] = 8'd235; short_chirp_lut[33] = 8'd118; short_chirp_lut[34] = 8'd 10; short_chirp_lut[35] = 8'd 34; short_chirp_lut[36] = 8'd167; short_chirp_lut[37] = 8'd254; short_chirp_lut[38] = 8'd187; short_chirp_lut[39] = 8'd 45;
|
||||
short_chirp_lut[40] = 8'd 8; short_chirp_lut[41] = 8'd129; short_chirp_lut[42] = 8'd248; short_chirp_lut[43] = 8'd201; short_chirp_lut[44] = 8'd 49; short_chirp_lut[45] = 8'd 10; short_chirp_lut[46] = 8'd145; short_chirp_lut[47] = 8'd254;
|
||||
short_chirp_lut[48] = 8'd167; short_chirp_lut[49] = 8'd 17; short_chirp_lut[50] = 8'd 46; short_chirp_lut[51] = 8'd210; short_chirp_lut[52] = 8'd235; short_chirp_lut[53] = 8'd 75; short_chirp_lut[54] = 8'd 7; short_chirp_lut[55] = 8'd155;
|
||||
short_chirp_lut[56] = 8'd253; short_chirp_lut[57] = 8'd118; short_chirp_lut[58] = 8'd 1; short_chirp_lut[59] = 8'd129;
|
||||
end
|
||||
|
||||
//chirp counter
|
||||
|
||||
always @(posedge clk_100m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
chirp_counter <= 6'd1;
|
||||
end else begin
|
||||
if (chirp__toggling) begin
|
||||
if (chirp_counter == CHIRP_MAX) begin
|
||||
chirp_counter <= 6'd1;
|
||||
end else begin
|
||||
chirp_counter <= chirp_counter + 6'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Elevation counter
|
||||
|
||||
always @(posedge clk_100m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
elevation_counter <= 6'b1;
|
||||
end else begin
|
||||
if (elevation__toggling) begin
|
||||
if (elevation_counter == ELEVATION_MAX) begin
|
||||
elevation_counter <= 6'b1;
|
||||
end else begin
|
||||
elevation_counter <= elevation_counter + 6'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Azimuth counter
|
||||
|
||||
always @(posedge clk_100m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
azimuth_counter <= 6'd1;
|
||||
end else begin
|
||||
if (azimuth__toggling) begin
|
||||
if (azimuth_counter == AZIMUTH_MAX) begin
|
||||
azimuth_counter <= 6'd1;
|
||||
end else begin
|
||||
azimuth_counter <= azimuth_counter + 6'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// State register
|
||||
always @(posedge clk_120m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
current_state <= IDLE;
|
||||
end else begin
|
||||
current_state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
// Next state logic
|
||||
always @(*) begin
|
||||
case (current_state)
|
||||
IDLE: begin
|
||||
if (chirp__toggling && mixers_enable)
|
||||
next_state = LONG_CHIRP;
|
||||
else
|
||||
next_state = IDLE;
|
||||
end
|
||||
|
||||
LONG_CHIRP: begin
|
||||
if (sample_counter == T1_SAMPLES-1)
|
||||
next_state = LONG_LISTEN;
|
||||
else
|
||||
next_state = LONG_CHIRP;
|
||||
end
|
||||
|
||||
LONG_LISTEN: begin
|
||||
if (sample_counter == T1_RADAR_LISTENING-1) begin
|
||||
if (chirp_counter == (CHIRP_MAX/2)-1)
|
||||
next_state = GUARD_TIME;
|
||||
else
|
||||
next_state = LONG_CHIRP;
|
||||
end else begin
|
||||
next_state = LONG_LISTEN;
|
||||
end
|
||||
end
|
||||
|
||||
GUARD_TIME: begin
|
||||
if (sample_counter == GUARD_SAMPLES-1)
|
||||
next_state = SHORT_CHIRP;
|
||||
else
|
||||
next_state = GUARD_TIME;
|
||||
end
|
||||
|
||||
SHORT_CHIRP: begin
|
||||
if (sample_counter == T2_SAMPLES-1)
|
||||
next_state = SHORT_LISTEN;
|
||||
else
|
||||
next_state = SHORT_CHIRP;
|
||||
end
|
||||
|
||||
SHORT_LISTEN: begin
|
||||
if (sample_counter == T2_RADAR_LISTENING-1) begin
|
||||
if (chirp_counter == CHIRP_MAX-1)
|
||||
next_state = DONE;
|
||||
else
|
||||
next_state = SHORT_CHIRP;
|
||||
end else begin
|
||||
next_state = SHORT_LISTEN;
|
||||
end
|
||||
end
|
||||
|
||||
DONE: begin
|
||||
next_state = IDLE;
|
||||
end
|
||||
|
||||
default: begin
|
||||
next_state = IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk_120m or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
sample_counter <= 0;
|
||||
chirp_counter <= 0;
|
||||
chirp_valid <= 0;
|
||||
chirp_done <= 0;
|
||||
chirp_data <= 8'd128;
|
||||
rf_switch_ctrl <= 1'b0;
|
||||
adar_tr_1 <= 1'b0;
|
||||
adar_tr_2 <= 1'b0;
|
||||
adar_tr_3 <= 1'b0;
|
||||
adar_tr_4 <= 1'b0;
|
||||
end else if (mixers_enable) begin
|
||||
// Default outputs
|
||||
chirp_valid <= 0;
|
||||
chirp_done <= 0;
|
||||
rf_switch_ctrl <= 0;
|
||||
{adar_tr_1, adar_tr_2, adar_tr_3, adar_tr_4} <= 4'b0000;
|
||||
|
||||
// Sample counter increment logic
|
||||
if (current_state == LONG_CHIRP || current_state == LONG_LISTEN ||
|
||||
current_state == GUARD_TIME || current_state == SHORT_CHIRP ||
|
||||
current_state == SHORT_LISTEN) begin
|
||||
if (sample_counter == get_max_counter(current_state) - 1) begin
|
||||
sample_counter <= 0;
|
||||
// Increment chirp counter at end of listen states
|
||||
if (current_state == LONG_LISTEN || current_state == SHORT_LISTEN) begin
|
||||
chirp_counter <= chirp_counter + 1;
|
||||
end
|
||||
end else begin
|
||||
sample_counter <= sample_counter + 1;
|
||||
end
|
||||
end else begin
|
||||
sample_counter <= 0;
|
||||
end
|
||||
|
||||
// State-specific outputs
|
||||
case (current_state)
|
||||
IDLE: begin
|
||||
chirp_data <= 8'd128;
|
||||
end
|
||||
|
||||
LONG_CHIRP: begin
|
||||
rf_switch_ctrl <= 1'b1;
|
||||
{adar_tr_1, adar_tr_2, adar_tr_3, adar_tr_4} <= 4'b1111;
|
||||
|
||||
// CRITICAL FIX: Generate valid signal
|
||||
if (sample_counter < T1_SAMPLES) begin
|
||||
chirp_data <= long_chirp_lut[sample_counter];
|
||||
chirp_valid <= 1'b1; // Valid during entire chirp
|
||||
end else begin
|
||||
chirp_data <= 8'd128;
|
||||
end
|
||||
end
|
||||
|
||||
LONG_LISTEN: begin
|
||||
chirp_data <= 8'd128;
|
||||
rf_switch_ctrl <= 1'b0;
|
||||
end
|
||||
|
||||
GUARD_TIME: begin
|
||||
chirp_data <= 8'd128;
|
||||
rf_switch_ctrl <= 1'b0;
|
||||
end
|
||||
|
||||
SHORT_CHIRP: begin
|
||||
rf_switch_ctrl <= 1'b1;
|
||||
{adar_tr_1, adar_tr_2, adar_tr_3, adar_tr_4} <= 4'b1111;
|
||||
|
||||
// CRITICAL FIX: Generate valid signal for short chirp
|
||||
if (sample_counter < T2_SAMPLES) begin
|
||||
chirp_data <= short_chirp_lut[sample_counter];
|
||||
chirp_valid <= 1'b1; // Valid during entire chirp
|
||||
end else begin
|
||||
chirp_data <= 8'd128;
|
||||
end
|
||||
end
|
||||
|
||||
SHORT_LISTEN: begin
|
||||
chirp_data <= 8'd128;
|
||||
rf_switch_ctrl <= 1'b0;
|
||||
end
|
||||
|
||||
DONE: begin
|
||||
chirp_done <= 1'b1;
|
||||
chirp_data <= 8'd128;
|
||||
end
|
||||
|
||||
default: begin
|
||||
chirp_data <= 8'd128;
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
// Mixers disabled
|
||||
chirp_data <= 8'd128;
|
||||
chirp_valid <= 0;
|
||||
chirp_done <= 0;
|
||||
rf_switch_ctrl <= 0;
|
||||
{adar_tr_1, adar_tr_2, adar_tr_3, adar_tr_4} <= 4'b0000;
|
||||
sample_counter <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// Helper function to get max counter for each state
|
||||
function [15:0] get_max_counter;
|
||||
input [2:0] state;
|
||||
begin
|
||||
case (state)
|
||||
LONG_CHIRP: get_max_counter = T1_SAMPLES;
|
||||
LONG_LISTEN: get_max_counter = T1_RADAR_LISTENING;
|
||||
GUARD_TIME: get_max_counter = GUARD_SAMPLES;
|
||||
SHORT_CHIRP: get_max_counter = T2_SAMPLES;
|
||||
SHORT_LISTEN: get_max_counter = T2_RADAR_LISTENING;
|
||||
default: get_max_counter = 0;
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
|
||||
endmodule
|
||||
353
9_Firmware/9_2_FPGA/radar_receiver_final.v
Normal file
353
9_Firmware/9_2_FPGA/radar_receiver_final.v
Normal file
@@ -0,0 +1,353 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module radar_receiver_final (
|
||||
input wire clk, // 100MHz
|
||||
input wire reset_n,
|
||||
|
||||
// ADC Physical Interface (LVDS Inputs)
|
||||
input wire [7:0] adc_d_p, // ADC Data P (LVDS)
|
||||
input wire [7:0] adc_d_n, // ADC Data N (LVDS)
|
||||
input wire adc_dco_p, // Data Clock Output P (400MHz LVDS)
|
||||
input wire adc_dco_n, // Data Clock Output N (400MHz LVDS)
|
||||
output wire adc_pwdn,
|
||||
|
||||
output reg [31:0] doppler_output,
|
||||
output reg doppler_valid,
|
||||
output reg [4:0] doppler_bin,
|
||||
output reg [5:0] range_bin
|
||||
);
|
||||
|
||||
// ========== INTERNAL SIGNALS ==========
|
||||
wire use_long_chirp;
|
||||
wire [5:0] chirp_counter;
|
||||
wire chirp_start;
|
||||
wire azimuth_change;
|
||||
wire elevation_change;
|
||||
|
||||
wire [1:0] segment_request;
|
||||
wire mem_request;
|
||||
wire [15:0] ref_i, ref_q;
|
||||
wire mem_ready;
|
||||
|
||||
wire [15:0] adc_i_scaled, adc_q_scaled;
|
||||
wire adc_valid_sync;
|
||||
|
||||
// Reference signals for the processing chain
|
||||
wire [15:0] long_chirp_real, long_chirp_imag;
|
||||
wire [15:0] short_chirp_real, short_chirp_imag;
|
||||
|
||||
// ========== DOPPLER PROCESSING SIGNALS ==========
|
||||
wire [31:0] range_data_32bit;
|
||||
wire range_data_valid;
|
||||
wire new_chirp_frame;
|
||||
|
||||
// Doppler processor outputs
|
||||
wire [31:0] doppler_spectrum;
|
||||
wire doppler_spectrum_valid;
|
||||
wire [4:0] doppler_bin_out;
|
||||
wire [5:0] doppler_range_bin_out;
|
||||
wire doppler_processing;
|
||||
wire doppler_frame_done;
|
||||
|
||||
// ========== RANGE BIN DECIMATOR SIGNALS ==========
|
||||
wire signed [15:0] decimated_range_i;
|
||||
wire signed [15:0] decimated_range_q;
|
||||
wire decimated_range_valid;
|
||||
wire [5:0] decimated_range_bin;
|
||||
|
||||
// ========== MODULE INSTANTIATIONS ==========
|
||||
reg clk_400m;
|
||||
|
||||
lvds_to_cmos_400m clk_400m_inst(
|
||||
// ADC Physical Interface (LVDS Inputs)
|
||||
.clk_400m_p(adc_dco_p), // Data Clock Output P (400MHz LVDS, 2.5V)
|
||||
.clk_400m_n(adc_dco_n), // Data Clock Output N (400MHz LVDS, 2.5V)
|
||||
.reset_n(reset_n), // Active-low reset
|
||||
|
||||
// CMOS Output Interface (400MHz Domain)
|
||||
.clk_400m_cmos(clk_400m) // ADC data clock (CMOS, 3.3V)
|
||||
);
|
||||
|
||||
// 1. ADC + CDC + AGC
|
||||
|
||||
// CMOS Output Interface (400MHz Domain)
|
||||
wire [7:0] adc_data_cmos; // 8-bit ADC data (CMOS)
|
||||
wire adc_dco_cmos; // ADC data clock (CMOS, 400MHz)
|
||||
wire adc_valid; // Data valid signal
|
||||
|
||||
wire [7:0] cdc_data_cmos; // 8-bit ADC data (CMOS)
|
||||
wire cdc_valid; // Data valid signal
|
||||
|
||||
|
||||
ad9484_lvds_to_cmos_400m adc (
|
||||
.adc_d_p(adc_d_p),
|
||||
.adc_d_n(adc_d_n),
|
||||
.adc_dco_p(adc_dco_p),
|
||||
.adc_dco_n(adc_dco_n),
|
||||
.reset_n(reset_n),
|
||||
.adc_data_cmos(adc_data_cmos),
|
||||
.adc_dco_cmos(adc_dco_cmos),
|
||||
.adc_valid(adc_valid),
|
||||
.adc_pwdn(adc_pwdn)
|
||||
);
|
||||
|
||||
cdc_adc_to_processing #(
|
||||
.WIDTH(8),
|
||||
.STAGES(3)
|
||||
)cdc(
|
||||
.src_clk(adc_dco_cmos),
|
||||
.dst_clk(clk_400m),
|
||||
.reset_n(reset_n),
|
||||
.src_data(adc_data_cmos),
|
||||
.src_valid(adc_valid),
|
||||
.dst_data(cdc_data_cmos),
|
||||
.dst_valid(cdc_valid)
|
||||
);
|
||||
|
||||
// 2. DDC Input Interface
|
||||
wire signed [17:0] ddc_out_i;
|
||||
wire signed [17:0] ddc_out_q;
|
||||
|
||||
wire ddc_valid_i;
|
||||
wire ddc_valid_q;
|
||||
|
||||
ddc_400m_enhanced ddc(
|
||||
.clk_400m(clk_400m), // 400MHz clock from ADC DCO
|
||||
.clk_100m(clk), // 100MHz system clock //used by the 2 FIR
|
||||
.reset_n(reset_n),
|
||||
.adc_data(cdc_data_cmos), // ADC data at 400MHz (unsigned 0-255)
|
||||
.adc_data_valid_i(cdc_valid), // Valid at 400MHz
|
||||
.adc_data_valid_q(cdc_valid), // Valid at 400MHz
|
||||
.baseband_i(ddc_out_i), // I output at 100MHz
|
||||
.baseband_q(ddc_out_q), // Q output at 100MHz
|
||||
.baseband_valid_i(ddc_valid_i), // Valid at 100MHz
|
||||
.baseband_valid_q(ddc_valid_q),
|
||||
.mixers_enable(1'b1),
|
||||
.bypass_mode(1'b1)
|
||||
);
|
||||
|
||||
ddc_input_interface ddc_if (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.ddc_i(ddc_out_i),
|
||||
.ddc_q(ddc_out_q),
|
||||
.valid_i(ddc_valid_i),
|
||||
.valid_q(ddc_valid_q),
|
||||
.adc_i(adc_i_scaled),
|
||||
.adc_q(adc_q_scaled),
|
||||
.adc_valid(adc_valid_sync),
|
||||
.data_sync_error()
|
||||
);
|
||||
|
||||
// 3. Dual Chirp Memory Loader
|
||||
|
||||
chirp_memory_loader_param chirp_mem (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.segment_select(segment_request),
|
||||
.mem_request(mem_request),
|
||||
.use_long_chirp(use_long_chirp),
|
||||
.sample_addr(sample_addr_from_chain),
|
||||
.ref_i(ref_i),
|
||||
.ref_q(ref_q),
|
||||
.mem_ready(mem_ready)
|
||||
);
|
||||
|
||||
// Sample address generator
|
||||
reg [9:0] sample_addr_reg;
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
sample_addr_reg <= 0;
|
||||
end else if (mem_request) begin
|
||||
sample_addr_reg <= sample_addr_reg + 1;
|
||||
if (sample_addr_reg == 1023) sample_addr_reg <= 0;
|
||||
end
|
||||
end
|
||||
assign sample_addr_wire = sample_addr_reg;
|
||||
|
||||
// 4. CRITICAL: Reference Chirp Latency Buffer
|
||||
// This aligns reference data with FFT output (2159 cycle delay)
|
||||
wire [15:0] delayed_ref_i, delayed_ref_q;
|
||||
wire mem_ready_delayed;
|
||||
|
||||
latency_buffer_2159 #(
|
||||
.DATA_WIDTH(32), // 16-bit I + 16-bit Q
|
||||
.LATENCY(3187)
|
||||
) ref_latency_buffer (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.data_in({ref_i, ref_q}),
|
||||
.valid_in(mem_request),
|
||||
.data_out({delayed_ref_i, delayed_ref_q}),
|
||||
.valid_out(mem_ready_delayed)
|
||||
);
|
||||
|
||||
// Assign delayed reference signals
|
||||
assign long_chirp_real = delayed_ref_i;
|
||||
assign long_chirp_imag = delayed_ref_q;
|
||||
assign short_chirp_real = delayed_ref_i;
|
||||
assign short_chirp_imag = delayed_ref_q;
|
||||
|
||||
// 5. Dual Chirp Matched Filter
|
||||
wire [9:0] sample_addr_from_chain;
|
||||
|
||||
wire signed [15:0] range_profile_i;
|
||||
wire signed [15:0] range_profile_q;
|
||||
wire range_valid;
|
||||
|
||||
matched_filter_multi_segment mf_dual (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.ddc_i({{2{adc_i_scaled[15]}}, adc_i_scaled}),
|
||||
.ddc_q({{2{adc_q_scaled[15]}}, adc_q_scaled}),
|
||||
.ddc_valid(adc_valid_sync),
|
||||
.use_long_chirp(use_long_chirp),
|
||||
.chirp_counter(chirp_counter),
|
||||
.mc_new_chirp(mc_new_chirp),
|
||||
.mc_new_elevation(mc_new_elevation),
|
||||
.mc_new_azimuth(mc_new_azimuth),
|
||||
.long_chirp_real(delayed_ref_i), // From latency buffer
|
||||
.long_chirp_imag(delayed_ref_q),
|
||||
.short_chirp_real(delayed_ref_i), // Same for short chirp
|
||||
.short_chirp_imag(delayed_ref_q),
|
||||
.segment_request(segment_request),
|
||||
.mem_request(mem_request),
|
||||
.sample_addr_out(sample_addr_from_chain),
|
||||
.ref_i(16'd0), // Direct ref to multi_seg
|
||||
.ref_q(16'd0),
|
||||
.mem_ready(mem_ready),
|
||||
.pc_i_w(range_profile_i),
|
||||
.pc_q_w(range_profile_q),
|
||||
.pc_valid_w(range_valid)
|
||||
);
|
||||
|
||||
// ========== CRITICAL: RANGE BIN DECIMATOR ==========
|
||||
// Convert 1024 range bins to 64 bins for Doppler
|
||||
range_bin_decimator #(
|
||||
.INPUT_BINS(1024),
|
||||
.OUTPUT_BINS(64),
|
||||
.DECIMATION_FACTOR(16)
|
||||
) range_decim (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.range_i_in(range_profile_i),
|
||||
.range_q_in(range_profile_q),
|
||||
.range_valid_in(range_valid),
|
||||
.range_i_out(decimated_range_i),
|
||||
.range_q_out(decimated_range_q),
|
||||
.range_valid_out(decimated_range_valid),
|
||||
.range_bin_index(decimated_range_bin),
|
||||
.decimation_mode(2'b01), // Peak detection mode
|
||||
.start_bin(10'd0)
|
||||
);
|
||||
|
||||
// ========== FRAME SYNC USING chirp_counter ==========
|
||||
reg [5:0] chirp_counter_prev;
|
||||
reg new_frame_pulse;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
chirp_counter_prev <= 6'd0;
|
||||
new_frame_pulse <= 1'b0;
|
||||
end else begin
|
||||
// Default: no pulse
|
||||
new_frame_pulse <= 1'b0;
|
||||
|
||||
// ===== CHOOSE ONE FRAME DETECTION METHOD =====
|
||||
|
||||
// METHOD A: Detect frame start at chirp_counter = 0
|
||||
// (Assumes frames are 64 chirps: 0-63)
|
||||
//if (chirp_counter == 6'd0 && chirp_counter_prev != 6'd0) begin
|
||||
// new_frame_pulse <= 1'b1;
|
||||
//end
|
||||
|
||||
// METHOD B: Detect frame start at chirp_counter = 0 AND 32
|
||||
// (For 32-chirp frames in a 64-chirp sequence)
|
||||
if ((chirp_counter == 6'd0 || chirp_counter == 6'd32) &&
|
||||
(chirp_counter_prev != chirp_counter)) begin
|
||||
new_frame_pulse <= 1'b1;
|
||||
end
|
||||
|
||||
// METHOD C: Programmable frame start
|
||||
// localparam FRAME_START_CHIRP = 6'd0; // Set based on your sequence
|
||||
// if (chirp_counter == FRAME_START_CHIRP &&
|
||||
// chirp_counter_prev != FRAME_START_CHIRP) begin
|
||||
// new_frame_pulse <= 1'b1;
|
||||
// end
|
||||
|
||||
// Store previous value
|
||||
chirp_counter_prev <= chirp_counter;
|
||||
end
|
||||
end
|
||||
|
||||
assign new_chirp_frame = new_frame_pulse;
|
||||
|
||||
// ========== DATA PACKING FOR DOPPLER ==========
|
||||
assign range_data_32bit = {decimated_range_q, decimated_range_i};
|
||||
assign range_data_valid = decimated_range_valid;
|
||||
|
||||
// ========== DOPPLER PROCESSOR ==========
|
||||
doppler_processor_optimized #(
|
||||
.DOPPLER_FFT_SIZE(32),
|
||||
.RANGE_BINS(64),
|
||||
.CHIRPS_PER_FRAME(32) // MUST MATCH YOUR ACTUAL FRAME SIZE!
|
||||
) doppler_proc (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.range_data(range_data_32bit),
|
||||
.data_valid(range_data_valid),
|
||||
.new_chirp_frame(new_chirp_frame),
|
||||
|
||||
// Outputs
|
||||
.doppler_output(doppler_output),
|
||||
.doppler_valid(doppler_valid),
|
||||
.doppler_bin(doppler_bin),
|
||||
.range_bin(doppler_range_bin_out),
|
||||
|
||||
// Status
|
||||
.processing_active(doppler_processing),
|
||||
.frame_complete(doppler_frame_done),
|
||||
.status()
|
||||
);
|
||||
|
||||
// ========== OUTPUT CONNECTIONS ==========
|
||||
assign doppler_range_bin = doppler_range_bin_out;
|
||||
assign doppler_processing_active = doppler_processing;
|
||||
assign doppler_frame_complete = doppler_frame_done;
|
||||
|
||||
// ========== STATUS ==========
|
||||
|
||||
// ========== DEBUG AND VERIFICATION ==========
|
||||
reg [31:0] frame_counter;
|
||||
reg [5:0] chirps_in_current_frame;
|
||||
|
||||
always @(posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
frame_counter <= 0;
|
||||
chirps_in_current_frame <= 0;
|
||||
end else begin
|
||||
// Count chirps in current frame
|
||||
if (range_data_valid && decimated_range_bin == 0) begin
|
||||
// First range bin of a chirp
|
||||
chirps_in_current_frame <= chirps_in_current_frame + 1;
|
||||
end
|
||||
|
||||
// Detect frame completion
|
||||
if (new_chirp_frame) begin
|
||||
frame_counter <= frame_counter + 1;
|
||||
$display("[TOP] Frame %0d started. Previous frame had %0d chirps",
|
||||
frame_counter, chirps_in_current_frame);
|
||||
chirps_in_current_frame <= 0;
|
||||
end
|
||||
|
||||
// Monitor chirp counter pattern
|
||||
if (chirp_counter != chirp_counter_prev) begin
|
||||
$display("[TOP] chirp_counter: %0d ? %0d",
|
||||
chirp_counter_prev, chirp_counter);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
157
9_Firmware/9_2_FPGA/radar_transmitter.v
Normal file
157
9_Firmware/9_2_FPGA/radar_transmitter.v
Normal file
@@ -0,0 +1,157 @@
|
||||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Company:
|
||||
// Engineer:
|
||||
//
|
||||
// Create Date: 19:04:35 12/14/2025
|
||||
// Design Name:
|
||||
// Module Name: radar_transmitter
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module radar_transmitter(
|
||||
// System Clocks
|
||||
input wire clk_100m, // System clock
|
||||
input wire clk_120m_dac, // 120MHz DAC clock
|
||||
input wire reset_n,
|
||||
|
||||
// DAC Interface
|
||||
output wire [7:0] dac_data,
|
||||
output wire dac_clk,
|
||||
output wire dac_sleep,
|
||||
output wire rx_mixer_en,
|
||||
output wire tx_mixer_en,
|
||||
|
||||
// STM32 Control Interface
|
||||
input wire stm32_new_chirp,
|
||||
input wire stm32_new_elevation,
|
||||
input wire stm32_new_azimuth,
|
||||
input wire stm32_mixers_enable,
|
||||
|
||||
output wire fpga_rf_switch,
|
||||
|
||||
// ADAR1000 Control Interface
|
||||
output wire adar_tx_load_1,
|
||||
output wire adar_rx_load_1,
|
||||
output wire adar_tx_load_2,
|
||||
output wire adar_rx_load_2,
|
||||
output wire adar_tx_load_3,
|
||||
output wire adar_rx_load_3,
|
||||
output wire adar_tx_load_4,
|
||||
output wire adar_rx_load_4,
|
||||
output wire adar_tr_1,
|
||||
output wire adar_tr_2,
|
||||
output wire adar_tr_3,
|
||||
output wire adar_tr_4,
|
||||
|
||||
// Level Shifter SPI Interface (STM32F7 to ADAR1000)
|
||||
input wire stm32_sclk_3v3,
|
||||
input wire stm32_mosi_3v3,
|
||||
output wire stm32_miso_3v3,
|
||||
input wire stm32_cs_adar1_3v3,
|
||||
input wire stm32_cs_adar2_3v3,
|
||||
input wire stm32_cs_adar3_3v3,
|
||||
input wire stm32_cs_adar4_3v3,
|
||||
|
||||
output wire stm32_sclk_1v8,
|
||||
output wire stm32_mosi_1v8,
|
||||
input wire stm32_miso_1v8,
|
||||
output wire stm32_cs_adar1_1v8,
|
||||
output wire stm32_cs_adar2_1v8,
|
||||
output wire stm32_cs_adar3_1v8,
|
||||
output wire stm32_cs_adar4_1v8,
|
||||
|
||||
// Beam Position Tracking
|
||||
output wire [5:0] current_elevation,
|
||||
output wire [5:0] current_azimuth,
|
||||
output wire [5:0] current_chirp,
|
||||
output wire new_chirp_frame
|
||||
|
||||
|
||||
);
|
||||
|
||||
// Edge Detection Signals
|
||||
wire new_chirp_pulse;
|
||||
wire new_elevation_pulse;
|
||||
wire new_azimuth_pulse;
|
||||
|
||||
// Chirp Control Signals
|
||||
wire [7:0] chirp_data;
|
||||
wire chirp_valid;
|
||||
wire chirp_sequence_done;
|
||||
|
||||
// Enhanced STM32 Input Edge Detection with Debouncing
|
||||
edge_detector_enhanced chirp_edge (
|
||||
.clk(clk_100m),
|
||||
.reset_n(reset_n),
|
||||
.signal_in(stm32_new_chirp),
|
||||
.rising_falling_edge(new_chirp_pulse)
|
||||
);
|
||||
|
||||
edge_detector_enhanced elevation_edge (
|
||||
.clk(clk_100m),
|
||||
.reset_n(reset_n),
|
||||
.signal_in(stm32_new_elevation),
|
||||
.rising_falling_edge(new_elevation_pulse)
|
||||
);
|
||||
|
||||
edge_detector_enhanced azimuth_edge (
|
||||
.clk(clk_100m),
|
||||
.reset_n(reset_n),
|
||||
.signal_in(stm32_new_azimuth),
|
||||
.rising_falling_edge(new_azimuth_pulse)
|
||||
);
|
||||
|
||||
// Enhanced PLFM Chirp Generation
|
||||
plfm_chirp_controller_enhanced plfm_chirp_inst (
|
||||
.clk_120m(clk_120m_dac),
|
||||
.clk_100m(clk_100m),
|
||||
.reset_n(reset_n),
|
||||
.new_chirp(new_chirp_pulse),
|
||||
.new_elevation(new_elevation_pulse),
|
||||
.new_azimuth(new_azimuth_pulse),
|
||||
.new_chirp_frame(new_chirp_frame),
|
||||
.mixers_enable(stm32_mixers_enable),
|
||||
.chirp_data(chirp_data),
|
||||
.chirp_valid(chirp_valid),
|
||||
.chirp_done(chirp_sequence_done),
|
||||
.rf_switch_ctrl(fpga_rf_switch),
|
||||
.rx_mixer_en(rx_mixer_en),
|
||||
.tx_mixer_en(tx_mixer_en),
|
||||
.adar_tx_load_1(adar_tx_load_1),
|
||||
.adar_rx_load_1(adar_rx_load_1),
|
||||
.adar_tx_load_2(adar_tx_load_2),
|
||||
.adar_rx_load_2(adar_rx_load_2),
|
||||
.adar_tx_load_3(adar_tx_load_3),
|
||||
.adar_rx_load_3(adar_rx_load_3),
|
||||
.adar_tx_load_4(adar_tx_load_4),
|
||||
.adar_rx_load_4(adar_rx_load_4),
|
||||
.adar_tr_1(adar_tr_1),
|
||||
.adar_tr_2(adar_tr_2),
|
||||
.adar_tr_3(adar_tr_3),
|
||||
.adar_tr_4(adar_tr_4),
|
||||
.elevation_counter(current_elevation),
|
||||
.azimuth_counter(current_azimuth),
|
||||
.chirp_counter(current_chirp)
|
||||
);
|
||||
|
||||
// Enhanced DAC Interface
|
||||
dac_interface_enhanced dac_interface_inst (
|
||||
.clk_120m(clk_120m_dac),
|
||||
.reset_n(reset_n),
|
||||
.chirp_data(chirp_data),
|
||||
.chirp_valid(chirp_valid),
|
||||
.dac_data(dac_data),
|
||||
.dac_clk(dac_clk),
|
||||
.dac_sleep(dac_sleep)
|
||||
);
|
||||
endmodule
|
||||
50
9_Firmware/9_2_FPGA/short_chirp_i.mem
Normal file
50
9_Firmware/9_2_FPGA/short_chirp_i.mem
Normal file
@@ -0,0 +1,50 @@
|
||||
0095
|
||||
000d
|
||||
ffdd
|
||||
0007
|
||||
008c
|
||||
015e
|
||||
026b
|
||||
039c
|
||||
04d4
|
||||
05f9
|
||||
06ef
|
||||
07a1
|
||||
07fd
|
||||
07fd
|
||||
07a0
|
||||
06ef
|
||||
05fa
|
||||
04d8
|
||||
03a5
|
||||
027d
|
||||
017c
|
||||
00bc
|
||||
004d
|
||||
003d
|
||||
008f
|
||||
013b
|
||||
0234
|
||||
0364
|
||||
04b2
|
||||
05ff
|
||||
072e
|
||||
0825
|
||||
08ce
|
||||
091a
|
||||
0904
|
||||
088d
|
||||
07c3
|
||||
06b9
|
||||
0589
|
||||
0450
|
||||
032d
|
||||
023c
|
||||
0197
|
||||
014e
|
||||
016c
|
||||
01f1
|
||||
02d3
|
||||
0402
|
||||
0563
|
||||
06db
|
||||
50
9_Firmware/9_2_FPGA/short_chirp_q.mem
Normal file
50
9_Firmware/9_2_FPGA/short_chirp_q.mem
Normal file
@@ -0,0 +1,50 @@
|
||||
f8b6
|
||||
f791
|
||||
f64d
|
||||
f505
|
||||
f3d6
|
||||
f2d8
|
||||
f221
|
||||
f1c0
|
||||
f1bb
|
||||
f210
|
||||
f2b6
|
||||
f39b
|
||||
f4a8
|
||||
f5c1
|
||||
f6c9
|
||||
f7a6
|
||||
f840
|
||||
f886
|
||||
f86d
|
||||
f7f5
|
||||
f724
|
||||
f60b
|
||||
f4bf
|
||||
f35b
|
||||
f1fc
|
||||
f0bf
|
||||
efbe
|
||||
ef0d
|
||||
eeb8
|
||||
eec5
|
||||
ef2e
|
||||
efe7
|
||||
f0db
|
||||
f1f0
|
||||
f308
|
||||
f405
|
||||
f4cc
|
||||
f545
|
||||
f560
|
||||
f516
|
||||
f467
|
||||
f35f
|
||||
f210
|
||||
f094
|
||||
ef07
|
||||
ed88
|
||||
ec36
|
||||
eb2a
|
||||
ea78
|
||||
ea29
|
||||
41
9_Firmware/9_3_GUI/GUI_V1.py
Normal file
41
9_Firmware/9_3_GUI/GUI_V1.py
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
def update_gps_display(self):
|
||||
"""Step 18: Update GPS display and center map"""
|
||||
try:
|
||||
while not self.gps_data_queue.empty():
|
||||
gps_data = self.gps_data_queue.get_nowait()
|
||||
self.current_gps = gps_data
|
||||
|
||||
# Update GPS label
|
||||
self.gps_label.config(
|
||||
text=f"GPS: Lat {gps_data.latitude:.6f}, Lon {gps_data.longitude:.6f}, Alt {gps_data.altitude:.1f}m")
|
||||
|
||||
# Update map
|
||||
self.update_map_display(gps_data)
|
||||
|
||||
except queue.Empty:
|
||||
pass
|
||||
|
||||
def update_map_display(self, gps_data):
|
||||
"""Step 18: Update map display with current GPS position"""
|
||||
try:
|
||||
self.map_label.config(text=f"Radar Position: {gps_data.latitude:.6f}, {gps_data.longitude:.6f}\n"
|
||||
f"Altitude: {gps_data.altitude:.1f}m\n"
|
||||
f"Coverage: 50km radius\n"
|
||||
f"Map centered on GPS coordinates")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error updating map display: {e}")
|
||||
|
||||
def main():
|
||||
"""Main application entry point"""
|
||||
try:
|
||||
root = tk.Tk()
|
||||
app = RadarGUI(root)
|
||||
root.mainloop()
|
||||
except Exception as e:
|
||||
logging.error(f"Application error: {e}")
|
||||
messagebox.showerror("Fatal Error", f"Application failed to start: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1059
9_Firmware/9_3_GUI/GUI_V2.py
Normal file
1059
9_Firmware/9_3_GUI/GUI_V2.py
Normal file
File diff suppressed because it is too large
Load Diff
1146
9_Firmware/9_3_GUI/GUI_V3.py
Normal file
1146
9_Firmware/9_3_GUI/GUI_V3.py
Normal file
File diff suppressed because it is too large
Load Diff
1427
9_Firmware/9_3_GUI/GUI_V4.py
Normal file
1427
9_Firmware/9_3_GUI/GUI_V4.py
Normal file
File diff suppressed because it is too large
Load Diff
678
9_Firmware/9_3_GUI/GUI_V4_2_CSV.py
Normal file
678
9_Firmware/9_3_GUI/GUI_V4_2_CSV.py
Normal file
@@ -0,0 +1,678 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, filedialog, messagebox
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
from matplotlib.figure import Figure
|
||||
import matplotlib.patches as patches
|
||||
from scipy import signal
|
||||
from scipy.fft import fft, fftshift
|
||||
from scipy.signal import butter, filtfilt
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Dict, Tuple
|
||||
import threading
|
||||
import queue
|
||||
import time
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
@dataclass
|
||||
class RadarTarget:
|
||||
range: float
|
||||
velocity: float
|
||||
azimuth: int
|
||||
elevation: int
|
||||
snr: float
|
||||
chirp_type: str
|
||||
timestamp: float
|
||||
|
||||
class SignalProcessor:
|
||||
def __init__(self):
|
||||
self.range_resolution = 1.0 # meters
|
||||
self.velocity_resolution = 0.1 # m/s
|
||||
self.cfar_threshold = 15.0 # dB
|
||||
|
||||
def doppler_fft(self, iq_data: np.ndarray, fs: float = 100e6) -> Tuple[np.ndarray, np.ndarray]:
|
||||
"""
|
||||
Perform Doppler FFT on IQ data
|
||||
Returns Doppler frequencies and spectrum
|
||||
"""
|
||||
# Window function for FFT
|
||||
window = np.hanning(len(iq_data))
|
||||
windowed_data = (iq_data['I_value'].values + 1j * iq_data['Q_value'].values) * window
|
||||
|
||||
# Perform FFT
|
||||
doppler_fft = fft(windowed_data)
|
||||
doppler_fft = fftshift(doppler_fft)
|
||||
|
||||
# Frequency axis
|
||||
N = len(iq_data)
|
||||
freq_axis = np.linspace(-fs/2, fs/2, N)
|
||||
|
||||
# Convert to velocity (assuming radar frequency = 10 GHz)
|
||||
radar_freq = 10e9
|
||||
wavelength = 3e8 / radar_freq
|
||||
velocity_axis = freq_axis * wavelength / 2
|
||||
|
||||
return velocity_axis, np.abs(doppler_fft)
|
||||
|
||||
def mti_filter(self, iq_data: np.ndarray, filter_type: str = 'single_canceler') -> np.ndarray:
|
||||
"""
|
||||
Moving Target Indicator filter
|
||||
Removes stationary clutter with better shape handling
|
||||
"""
|
||||
if iq_data is None or len(iq_data) < 2:
|
||||
return np.array([], dtype=complex)
|
||||
|
||||
try:
|
||||
# Ensure we're working with complex data
|
||||
complex_data = iq_data.astype(complex)
|
||||
|
||||
if filter_type == 'single_canceler':
|
||||
# Single delay line canceler
|
||||
if len(complex_data) < 2:
|
||||
return np.array([], dtype=complex)
|
||||
filtered = np.zeros(len(complex_data) - 1, dtype=complex)
|
||||
for i in range(1, len(complex_data)):
|
||||
filtered[i-1] = complex_data[i] - complex_data[i-1]
|
||||
return filtered
|
||||
|
||||
elif filter_type == 'double_canceler':
|
||||
# Double delay line canceler
|
||||
if len(complex_data) < 3:
|
||||
return np.array([], dtype=complex)
|
||||
filtered = np.zeros(len(complex_data) - 2, dtype=complex)
|
||||
for i in range(2, len(complex_data)):
|
||||
filtered[i-2] = complex_data[i] - 2*complex_data[i-1] + complex_data[i-2]
|
||||
return filtered
|
||||
|
||||
else:
|
||||
return complex_data
|
||||
except Exception as e:
|
||||
logging.error(f"MTI filter error: {e}")
|
||||
return np.array([], dtype=complex)
|
||||
|
||||
|
||||
def cfar_detection(self, range_profile: np.ndarray, guard_cells: int = 2,
|
||||
training_cells: int = 10, threshold_factor: float = 3.0) -> List[Tuple[int, float]]:
|
||||
detections = []
|
||||
N = len(range_profile)
|
||||
|
||||
# Ensure guard_cells and training_cells are integers
|
||||
guard_cells = int(guard_cells)
|
||||
training_cells = int(training_cells)
|
||||
|
||||
for i in range(N):
|
||||
# Convert to integer indices
|
||||
i_int = int(i)
|
||||
if i_int < guard_cells + training_cells or i_int >= N - guard_cells - training_cells:
|
||||
continue
|
||||
|
||||
# Leading window - ensure integer indices
|
||||
lead_start = i_int - guard_cells - training_cells
|
||||
lead_end = i_int - guard_cells
|
||||
lead_cells = range_profile[lead_start:lead_end]
|
||||
|
||||
# Lagging window - ensure integer indices
|
||||
lag_start = i_int + guard_cells + 1
|
||||
lag_end = i_int + guard_cells + training_cells + 1
|
||||
lag_cells = range_profile[lag_start:lag_end]
|
||||
|
||||
# Combine training cells
|
||||
training_cells_combined = np.concatenate([lead_cells, lag_cells])
|
||||
|
||||
# Calculate noise floor (mean of training cells)
|
||||
if len(training_cells_combined) > 0:
|
||||
noise_floor = np.mean(training_cells_combined)
|
||||
|
||||
# Apply threshold
|
||||
threshold = noise_floor * threshold_factor
|
||||
|
||||
if range_profile[i_int] > threshold:
|
||||
detections.append((i_int, float(range_profile[i_int]))) # Ensure float magnitude
|
||||
|
||||
return detections
|
||||
|
||||
def range_fft(self, iq_data: np.ndarray, fs: float = 100e6, bw: float = 20e6) -> Tuple[np.ndarray, np.ndarray]:
|
||||
"""
|
||||
Perform range FFT on IQ data
|
||||
Returns range profile
|
||||
"""
|
||||
# Window function
|
||||
window = np.hanning(len(iq_data))
|
||||
windowed_data = np.abs(iq_data) * window
|
||||
|
||||
# Perform FFT
|
||||
range_fft = fft(windowed_data)
|
||||
|
||||
# Range calculation
|
||||
N = len(iq_data)
|
||||
range_max = (3e8 * N) / (2 * bw)
|
||||
range_axis = np.linspace(0, range_max, N)
|
||||
|
||||
return range_axis, np.abs(range_fft)
|
||||
|
||||
def process_chirp_sequence(self, df: pd.DataFrame, chirp_type: str = 'LONG') -> Dict:
|
||||
try:
|
||||
# Filter data by chirp type
|
||||
chirp_data = df[df['chirp_type'] == chirp_type]
|
||||
|
||||
if len(chirp_data) == 0:
|
||||
return {}
|
||||
|
||||
# Group by chirp number
|
||||
chirp_numbers = chirp_data['chirp_number'].unique()
|
||||
num_chirps = len(chirp_numbers)
|
||||
|
||||
if num_chirps == 0:
|
||||
return {}
|
||||
|
||||
# Get samples per chirp and ensure consistency
|
||||
samples_per_chirp_list = [len(chirp_data[chirp_data['chirp_number'] == num])
|
||||
for num in chirp_numbers]
|
||||
|
||||
# Use minimum samples to ensure consistent shape
|
||||
samples_per_chirp = min(samples_per_chirp_list)
|
||||
|
||||
# Create range-Doppler matrix with consistent shape
|
||||
range_doppler_matrix = np.zeros((samples_per_chirp, num_chirps), dtype=complex)
|
||||
|
||||
for i, chirp_num in enumerate(chirp_numbers):
|
||||
chirp_samples = chirp_data[chirp_data['chirp_number'] == chirp_num]
|
||||
# Take only the first samples_per_chirp samples to ensure consistent shape
|
||||
chirp_samples = chirp_samples.head(samples_per_chirp)
|
||||
|
||||
# Create complex IQ data
|
||||
iq_data = chirp_samples['I_value'].values + 1j * chirp_samples['Q_value'].values
|
||||
|
||||
# Ensure the shape matches
|
||||
if len(iq_data) == samples_per_chirp:
|
||||
range_doppler_matrix[:, i] = iq_data
|
||||
|
||||
# Apply MTI filter along slow-time (chirp-to-chirp)
|
||||
mti_filtered = np.zeros_like(range_doppler_matrix)
|
||||
for i in range(samples_per_chirp):
|
||||
slow_time_data = range_doppler_matrix[i, :]
|
||||
filtered = self.mti_filter(slow_time_data)
|
||||
# Ensure filtered data matches expected shape
|
||||
if len(filtered) == num_chirps:
|
||||
mti_filtered[i, :] = filtered
|
||||
else:
|
||||
# Handle shape mismatch by padding or truncating
|
||||
if len(filtered) < num_chirps:
|
||||
padded = np.zeros(num_chirps, dtype=complex)
|
||||
padded[:len(filtered)] = filtered
|
||||
mti_filtered[i, :] = padded
|
||||
else:
|
||||
mti_filtered[i, :] = filtered[:num_chirps]
|
||||
|
||||
# Perform Doppler FFT along slow-time dimension
|
||||
doppler_fft_result = np.zeros((samples_per_chirp, num_chirps), dtype=complex)
|
||||
for i in range(samples_per_chirp):
|
||||
doppler_fft_result[i, :] = fft(mti_filtered[i, :])
|
||||
|
||||
return {
|
||||
'range_doppler_matrix': np.abs(doppler_fft_result),
|
||||
'chirp_type': chirp_type,
|
||||
'num_chirps': num_chirps,
|
||||
'samples_per_chirp': samples_per_chirp
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error in process_chirp_sequence: {e}")
|
||||
return {}
|
||||
|
||||
class RadarGUI:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("Radar Signal Processor - CSV Analysis")
|
||||
self.root.geometry("1400x900")
|
||||
|
||||
# Initialize processor
|
||||
self.processor = SignalProcessor()
|
||||
|
||||
# Data storage
|
||||
self.df = None
|
||||
self.processed_data = {}
|
||||
self.detected_targets = []
|
||||
|
||||
# Create GUI
|
||||
self.create_gui()
|
||||
|
||||
# Start background processing
|
||||
self.processing_queue = queue.Queue()
|
||||
self.processing_thread = threading.Thread(target=self.background_processing, daemon=True)
|
||||
self.processing_thread.start()
|
||||
|
||||
# Update GUI periodically
|
||||
self.root.after(100, self.update_gui)
|
||||
|
||||
def create_gui(self):
|
||||
"""Create the main GUI layout"""
|
||||
# Main frame
|
||||
main_frame = ttk.Frame(self.root)
|
||||
main_frame.pack(fill='both', expand=True, padx=10, pady=10)
|
||||
|
||||
# Control panel
|
||||
control_frame = ttk.LabelFrame(main_frame, text="File Controls")
|
||||
control_frame.pack(fill='x', pady=5)
|
||||
|
||||
# File selection
|
||||
ttk.Button(control_frame, text="Load CSV File",
|
||||
command=self.load_csv_file).pack(side='left', padx=5, pady=5)
|
||||
|
||||
self.file_label = ttk.Label(control_frame, text="No file loaded")
|
||||
self.file_label.pack(side='left', padx=10, pady=5)
|
||||
|
||||
# Processing controls
|
||||
ttk.Button(control_frame, text="Process Data",
|
||||
command=self.process_data).pack(side='left', padx=5, pady=5)
|
||||
|
||||
ttk.Button(control_frame, text="Run CFAR Detection",
|
||||
command=self.run_cfar_detection).pack(side='left', padx=5, pady=5)
|
||||
|
||||
# Status
|
||||
self.status_label = ttk.Label(control_frame, text="Status: Ready")
|
||||
self.status_label.pack(side='right', padx=10, pady=5)
|
||||
|
||||
# Display area
|
||||
display_frame = ttk.Frame(main_frame)
|
||||
display_frame.pack(fill='both', expand=True, pady=5)
|
||||
|
||||
# Create matplotlib figures
|
||||
self.create_plots(display_frame)
|
||||
|
||||
# Targets list
|
||||
targets_frame = ttk.LabelFrame(main_frame, text="Detected Targets")
|
||||
targets_frame.pack(fill='x', pady=5)
|
||||
|
||||
self.targets_tree = ttk.Treeview(targets_frame,
|
||||
columns=('Range', 'Velocity', 'Azimuth', 'Elevation', 'SNR', 'Chirp Type'),
|
||||
show='headings', height=8)
|
||||
|
||||
self.targets_tree.heading('Range', text='Range (m)')
|
||||
self.targets_tree.heading('Velocity', text='Velocity (m/s)')
|
||||
self.targets_tree.heading('Azimuth', text='Azimuth (°)')
|
||||
self.targets_tree.heading('Elevation', text='Elevation (°)')
|
||||
self.targets_tree.heading('SNR', text='SNR (dB)')
|
||||
self.targets_tree.heading('Chirp Type', text='Chirp Type')
|
||||
|
||||
self.targets_tree.column('Range', width=100)
|
||||
self.targets_tree.column('Velocity', width=100)
|
||||
self.targets_tree.column('Azimuth', width=80)
|
||||
self.targets_tree.column('Elevation', width=80)
|
||||
self.targets_tree.column('SNR', width=80)
|
||||
self.targets_tree.column('Chirp Type', width=100)
|
||||
|
||||
self.targets_tree.pack(fill='x', padx=5, pady=5)
|
||||
|
||||
def create_plots(self, parent):
|
||||
"""Create matplotlib plots"""
|
||||
# Create figure with subplots
|
||||
self.fig = Figure(figsize=(12, 8))
|
||||
self.canvas = FigureCanvasTkAgg(self.fig, parent)
|
||||
self.canvas.get_tk_widget().pack(fill='both', expand=True)
|
||||
|
||||
# Create subplots
|
||||
self.ax1 = self.fig.add_subplot(221) # Range profile
|
||||
self.ax2 = self.fig.add_subplot(222) # Doppler spectrum
|
||||
self.ax3 = self.fig.add_subplot(223) # Range-Doppler map
|
||||
self.ax4 = self.fig.add_subplot(224) # MTI filtered data
|
||||
|
||||
# Set titles
|
||||
self.ax1.set_title('Range Profile')
|
||||
self.ax1.set_xlabel('Range (m)')
|
||||
self.ax1.set_ylabel('Magnitude')
|
||||
self.ax1.grid(True)
|
||||
|
||||
self.ax2.set_title('Doppler Spectrum')
|
||||
self.ax2.set_xlabel('Velocity (m/s)')
|
||||
self.ax2.set_ylabel('Magnitude')
|
||||
self.ax2.grid(True)
|
||||
|
||||
self.ax3.set_title('Range-Doppler Map')
|
||||
self.ax3.set_xlabel('Doppler Bin')
|
||||
self.ax3.set_ylabel('Range Bin')
|
||||
|
||||
self.ax4.set_title('MTI Filtered Data')
|
||||
self.ax4.set_xlabel('Sample')
|
||||
self.ax4.set_ylabel('Magnitude')
|
||||
self.ax4.grid(True)
|
||||
|
||||
self.fig.tight_layout()
|
||||
|
||||
def load_csv_file(self):
|
||||
"""Load CSV file generated by testbench"""
|
||||
filename = filedialog.askopenfilename(
|
||||
title="Select CSV file",
|
||||
filetypes=[("CSV files", "*.csv"), ("All files", "*.*")]
|
||||
)
|
||||
|
||||
# Add magnitude and phase calculations after loading CSV
|
||||
if self.df is not None:
|
||||
# Calculate magnitude from I/Q values
|
||||
self.df['magnitude'] = np.sqrt(self.df['I_value']**2 + self.df['Q_value']**2)
|
||||
|
||||
# Calculate phase from I/Q values
|
||||
self.df['phase_rad'] = np.arctan2(self.df['Q_value'], self.df['I_value'])
|
||||
|
||||
# If you used magnitude_squared in CSV, calculate actual magnitude
|
||||
if 'magnitude_squared' in self.df.columns:
|
||||
self.df['magnitude'] = np.sqrt(self.df['magnitude_squared'])
|
||||
if filename:
|
||||
try:
|
||||
self.status_label.config(text="Status: Loading CSV file...")
|
||||
self.df = pd.read_csv(filename)
|
||||
self.file_label.config(text=f"Loaded: {filename.split('/')[-1]}")
|
||||
self.status_label.config(text=f"Status: Loaded {len(self.df)} samples")
|
||||
|
||||
# Show basic info
|
||||
self.show_file_info()
|
||||
|
||||
except Exception as e:
|
||||
messagebox.showerror("Error", f"Failed to load CSV file: {e}")
|
||||
self.status_label.config(text="Status: Error loading file")
|
||||
|
||||
def show_file_info(self):
|
||||
"""Display basic information about loaded data"""
|
||||
if self.df is not None:
|
||||
info_text = f"Samples: {len(self.df)} | "
|
||||
info_text += f"Chirps: {self.df['chirp_number'].nunique()} | "
|
||||
info_text += f"Long: {len(self.df[self.df['chirp_type'] == 'LONG'])} | "
|
||||
info_text += f"Short: {len(self.df[self.df['chirp_type'] == 'SHORT'])}"
|
||||
|
||||
self.file_label.config(text=info_text)
|
||||
|
||||
def process_data(self):
|
||||
"""Process loaded CSV data"""
|
||||
if self.df is None:
|
||||
messagebox.showwarning("Warning", "Please load a CSV file first")
|
||||
return
|
||||
|
||||
self.status_label.config(text="Status: Processing data...")
|
||||
|
||||
# Add to processing queue
|
||||
self.processing_queue.put(('process', self.df))
|
||||
|
||||
def run_cfar_detection(self):
|
||||
"""Run CFAR detection on processed data"""
|
||||
if self.df is None:
|
||||
messagebox.showwarning("Warning", "Please load and process data first")
|
||||
return
|
||||
|
||||
self.status_label.config(text="Status: Running CFAR detection...")
|
||||
self.processing_queue.put(('cfar', self.df))
|
||||
|
||||
def background_processing(self):
|
||||
|
||||
while True:
|
||||
try:
|
||||
task_type, data = self.processing_queue.get(timeout=1.0)
|
||||
|
||||
if task_type == 'process':
|
||||
self._process_data_background(data)
|
||||
elif task_type == 'cfar':
|
||||
self._run_cfar_background(data)
|
||||
else:
|
||||
logging.warning(f"Unknown task type: {task_type}")
|
||||
|
||||
self.processing_queue.task_done()
|
||||
|
||||
except queue.Empty:
|
||||
continue
|
||||
except Exception as e:
|
||||
logging.error(f"Background processing error: {e}")
|
||||
# Update GUI to show error state
|
||||
self.root.after(0, lambda: self.status_label.config(
|
||||
text=f"Status: Processing error - {e}"
|
||||
))
|
||||
|
||||
def _process_data_background(self, df):
|
||||
try:
|
||||
# Process long chirps
|
||||
long_chirp_data = self.processor.process_chirp_sequence(df, 'LONG')
|
||||
|
||||
# Process short chirps
|
||||
short_chirp_data = self.processor.process_chirp_sequence(df, 'SHORT')
|
||||
|
||||
# Store results
|
||||
self.processed_data = {
|
||||
'long': long_chirp_data,
|
||||
'short': short_chirp_data
|
||||
}
|
||||
|
||||
# Update GUI in main thread
|
||||
self.root.after(0, self._update_plots_after_processing)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Processing error: {e}")
|
||||
error_msg = str(e)
|
||||
self.root.after(0, lambda msg=error_msg: self.status_label.config(
|
||||
text=f"Status: Processing error - {msg}"
|
||||
))
|
||||
|
||||
def _run_cfar_background(self, df):
|
||||
try:
|
||||
# Get first chirp for CFAR demonstration
|
||||
first_chirp = df[df['chirp_number'] == df['chirp_number'].min()]
|
||||
|
||||
if len(first_chirp) == 0:
|
||||
return
|
||||
|
||||
# Create IQ data - FIXED TYPO: first_chirp not first_chip
|
||||
iq_data = first_chirp['I_value'].values + 1j * first_chirp['Q_value'].values
|
||||
|
||||
# Perform range FFT
|
||||
range_axis, range_profile = self.processor.range_fft(iq_data)
|
||||
|
||||
# Run CFAR detection
|
||||
detections = self.processor.cfar_detection(range_profile)
|
||||
|
||||
# Convert to target objects
|
||||
self.detected_targets = []
|
||||
for range_bin, magnitude in detections:
|
||||
target = RadarTarget(
|
||||
range=range_axis[range_bin],
|
||||
velocity=0, # Would need Doppler processing for velocity
|
||||
azimuth=0, # From actual data
|
||||
elevation=0, # From actual data
|
||||
snr=20 * np.log10(magnitude + 1e-9), # Convert to dB
|
||||
chirp_type='LONG',
|
||||
timestamp=time.time()
|
||||
)
|
||||
self.detected_targets.append(target)
|
||||
|
||||
# Update GUI in main thread
|
||||
self.root.after(0, lambda: self._update_cfar_results(range_axis, range_profile, detections))
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"CFAR detection error: {e}")
|
||||
error_msg = str(e)
|
||||
self.root.after(0, lambda msg=error_msg: self.status_label.config(
|
||||
text=f"Status: CFAR error - {msg}"
|
||||
))
|
||||
|
||||
def _update_plots_after_processing(self):
|
||||
try:
|
||||
# Clear all plots
|
||||
for ax in [self.ax1, self.ax2, self.ax3, self.ax4]:
|
||||
ax.clear()
|
||||
|
||||
# Plot 1: Range profile from first chirp
|
||||
if self.df is not None and len(self.df) > 0:
|
||||
try:
|
||||
first_chirp_num = self.df['chirp_number'].min()
|
||||
first_chirp = self.df[self.df['chirp_number'] == first_chirp_num]
|
||||
|
||||
if len(first_chirp) > 0:
|
||||
iq_data = first_chirp['I_value'].values + 1j * first_chirp['Q_value'].values
|
||||
range_axis, range_profile = self.processor.range_fft(iq_data)
|
||||
|
||||
if len(range_axis) > 0 and len(range_profile) > 0:
|
||||
self.ax1.plot(range_axis, range_profile, 'b-')
|
||||
self.ax1.set_title('Range Profile - First Chirp')
|
||||
self.ax1.set_xlabel('Range (m)')
|
||||
self.ax1.set_ylabel('Magnitude')
|
||||
self.ax1.grid(True)
|
||||
except Exception as e:
|
||||
logging.warning(f"Range profile plot error: {e}")
|
||||
self.ax1.set_title('Range Profile - Error')
|
||||
|
||||
# Plot 2: Doppler spectrum
|
||||
if self.df is not None and len(self.df) > 0:
|
||||
try:
|
||||
sample_data = self.df.head(1024)
|
||||
if len(sample_data) > 10:
|
||||
iq_data = sample_data['I_value'].values + 1j * sample_data['Q_value'].values
|
||||
velocity_axis, doppler_spectrum = self.processor.doppler_fft(iq_data)
|
||||
|
||||
if len(velocity_axis) > 0 and len(doppler_spectrum) > 0:
|
||||
self.ax2.plot(velocity_axis, doppler_spectrum, 'g-')
|
||||
self.ax2.set_title('Doppler Spectrum')
|
||||
self.ax2.set_xlabel('Velocity (m/s)')
|
||||
self.ax2.set_ylabel('Magnitude')
|
||||
self.ax2.grid(True)
|
||||
except Exception as e:
|
||||
logging.warning(f"Doppler spectrum plot error: {e}")
|
||||
self.ax2.set_title('Doppler Spectrum - Error')
|
||||
|
||||
# Plot 3: Range-Doppler map
|
||||
if (self.processed_data.get('long') and
|
||||
'range_doppler_matrix' in self.processed_data['long'] and
|
||||
self.processed_data['long']['range_doppler_matrix'].size > 0):
|
||||
|
||||
try:
|
||||
rd_matrix = self.processed_data['long']['range_doppler_matrix']
|
||||
# Use integer indices for extent
|
||||
extent = [0, int(rd_matrix.shape[1]), 0, int(rd_matrix.shape[0])]
|
||||
|
||||
im = self.ax3.imshow(10 * np.log10(rd_matrix + 1e-9),
|
||||
aspect='auto', cmap='hot',
|
||||
extent=extent)
|
||||
self.ax3.set_title('Range-Doppler Map (Long Chirps)')
|
||||
self.ax3.set_xlabel('Doppler Bin')
|
||||
self.ax3.set_ylabel('Range Bin')
|
||||
self.fig.colorbar(im, ax=self.ax3, label='dB')
|
||||
except Exception as e:
|
||||
logging.warning(f"Range-Doppler map plot error: {e}")
|
||||
self.ax3.set_title('Range-Doppler Map - Error')
|
||||
|
||||
# Plot 4: MTI filtered data
|
||||
if self.df is not None and len(self.df) > 0:
|
||||
try:
|
||||
sample_data = self.df.head(100)
|
||||
if len(sample_data) > 10:
|
||||
iq_data = sample_data['I_value'].values + 1j * sample_data['Q_value'].values
|
||||
|
||||
# Original data
|
||||
original_mag = np.abs(iq_data)
|
||||
|
||||
# MTI filtered
|
||||
mti_filtered = self.processor.mti_filter(iq_data)
|
||||
|
||||
if mti_filtered is not None and len(mti_filtered) > 0:
|
||||
mti_mag = np.abs(mti_filtered)
|
||||
|
||||
# Use integer indices for plotting
|
||||
x_original = np.arange(len(original_mag))
|
||||
x_mti = np.arange(len(mti_mag))
|
||||
|
||||
self.ax4.plot(x_original, original_mag, 'b-', label='Original', alpha=0.7)
|
||||
self.ax4.plot(x_mti, mti_mag, 'r-', label='MTI Filtered', alpha=0.7)
|
||||
self.ax4.set_title('MTI Filter Comparison')
|
||||
self.ax4.set_xlabel('Sample Index')
|
||||
self.ax4.set_ylabel('Magnitude')
|
||||
self.ax4.legend()
|
||||
self.ax4.grid(True)
|
||||
except Exception as e:
|
||||
logging.warning(f"MTI filter plot error: {e}")
|
||||
self.ax4.set_title('MTI Filter - Error')
|
||||
|
||||
# Adjust layout and draw
|
||||
self.fig.tight_layout()
|
||||
self.canvas.draw()
|
||||
self.status_label.config(text="Status: Processing complete")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Plot update error: {e}")
|
||||
error_msg = str(e)
|
||||
self.status_label.config(text=f"Status: Plot error - {error_msg}")
|
||||
|
||||
def _update_cfar_results(self, range_axis, range_profile, detections):
|
||||
try:
|
||||
# Clear the plot
|
||||
self.ax1.clear()
|
||||
|
||||
# Plot range profile
|
||||
self.ax1.plot(range_axis, range_profile, 'b-', label='Range Profile')
|
||||
|
||||
# Plot detections - ensure we use integer indices
|
||||
if detections and len(range_axis) > 0:
|
||||
detection_ranges = []
|
||||
detection_mags = []
|
||||
|
||||
for bin_idx, mag in detections:
|
||||
# Convert bin_idx to integer and ensure it's within bounds
|
||||
bin_idx_int = int(bin_idx)
|
||||
if 0 <= bin_idx_int < len(range_axis):
|
||||
detection_ranges.append(range_axis[bin_idx_int])
|
||||
detection_mags.append(mag)
|
||||
|
||||
if detection_ranges: # Only plot if we have valid detections
|
||||
self.ax1.plot(detection_ranges, detection_mags, 'ro',
|
||||
markersize=8, label='CFAR Detections')
|
||||
|
||||
self.ax1.set_title('Range Profile with CFAR Detections')
|
||||
self.ax1.set_xlabel('Range (m)')
|
||||
self.ax1.set_ylabel('Magnitude')
|
||||
self.ax1.legend()
|
||||
self.ax1.grid(True)
|
||||
|
||||
# Update targets list
|
||||
self.update_targets_list()
|
||||
|
||||
self.canvas.draw()
|
||||
self.status_label.config(text=f"Status: CFAR complete - {len(detections)} targets detected")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"CFAR results update error: {e}")
|
||||
error_msg = str(e)
|
||||
self.status_label.config(text=f"Status: CFAR results error - {error_msg}")
|
||||
|
||||
def update_targets_list(self):
|
||||
"""Update the targets list display"""
|
||||
# Clear current list
|
||||
for item in self.targets_tree.get_children():
|
||||
self.targets_tree.delete(item)
|
||||
|
||||
# Add detected targets
|
||||
for i, target in enumerate(self.detected_targets):
|
||||
self.targets_tree.insert('', 'end', values=(
|
||||
f"{target.range:.1f}",
|
||||
f"{target.velocity:.1f}",
|
||||
f"{target.azimuth}",
|
||||
f"{target.elevation}",
|
||||
f"{target.snr:.1f}",
|
||||
target.chirp_type
|
||||
))
|
||||
|
||||
def update_gui(self):
|
||||
"""Periodic GUI update"""
|
||||
# You can add any periodic updates here
|
||||
self.root.after(100, self.update_gui)
|
||||
|
||||
def main():
|
||||
"""Main application entry point"""
|
||||
try:
|
||||
root = tk.Tk()
|
||||
app = RadarGUI(root)
|
||||
root.mainloop()
|
||||
except Exception as e:
|
||||
logging.error(f"Application error: {e}")
|
||||
messagebox.showerror("Fatal Error", f"Application failed to start: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1542
9_Firmware/9_3_GUI/GUI_V5.py
Normal file
1542
9_Firmware/9_3_GUI/GUI_V5.py
Normal file
File diff suppressed because it is too large
Load Diff
1356
9_Firmware/9_3_GUI/GUI_V5_Demo.py
Normal file
1356
9_Firmware/9_3_GUI/GUI_V5_Demo.py
Normal file
File diff suppressed because it is too large
Load Diff
6
9_Firmware/9_3_GUI/GUI_versions.txt
Normal file
6
9_Firmware/9_3_GUI/GUI_versions.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
GUI_V1 ==>
|
||||
GUI_V2 ==> added STM32 USB CDC
|
||||
GUI_V3 ==> added Pitch to STM32 USB Packet and pitch correction to the Elevation
|
||||
GUI_V3 ==> Added Google_Map, real time target plot, Chirp duration_2
|
||||
GUI_V4 ==> Added pitch correction
|
||||
GUI_V5 ==> Added Mercury Color
|
||||
16385
9_Firmware/9_3_GUI/test_radar_data.csv
Normal file
16385
9_Firmware/9_3_GUI/test_radar_data.csv
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user