diff --git a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adar1000.c b/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adar1000.c deleted file mode 100644 index eeac0a4..0000000 --- a/9_Firmware/9_1_Microcontroller/9_1_1_C_Cpp_Libraries/adar1000.c +++ /dev/null @@ -1,693 +0,0 @@ -/** - * 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< -#include -#include - -#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_ */ - diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp b/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp index 497378b..e8db4bc 100644 --- a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp +++ b/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp @@ -21,7 +21,6 @@ #include "usb_device.h" #include "USBHandler.h" #include "usbd_cdc_if.h" -#include "adar1000.h" #include "ADAR1000_Manager.h" #include "ADAR1000_AGC.h" extern "C" {