3D Low Frequency Wakeup Receiver
Diff: AS3933.cpp
- Revision:
- 2:c3435a136e50
- Parent:
- 0:19b363e50103
- Child:
- 3:2de552c4ffbc
--- a/AS3933.cpp Wed Mar 07 13:56:26 2018 +0000 +++ b/AS3933.cpp Wed Mar 07 15:04:16 2018 +0000 @@ -0,0 +1,1358 @@ +/** + * @brief AS3933.cpp + * @details 3D Low Frequency Wakeup Receiver. + * Function file. + * + * + * @return N/A + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A + * @pre This code belongs to Nimbus Centre ( http://unbarquero.blogspot.com ). + */ + +#include "AS3933.h" + + +AS3933::AS3933 ( PinName mosi, PinName miso, PinName sclk, PinName cs, uint32_t freq ) + : _spi ( mosi, miso, sclk ) + , _cs ( cs ) +{ + _spi.frequency( freq ); + _spi.format ( 8, 1 ); // 8-bits, mode1: CPOL = 0 | CPHA = 1 +} + + +AS3933::~AS3933() +{ +} + + + +/** + * @brief AS3933_SetLowPowerMode ( AS3933_channels_enable_t , AS3933_scanning_mode_t , AS3933_r4_t_off_value_t ) + * + * @details It configures the low power mode. + * + * @param[in] myEnabledChannels: Number of channels enabled. + * @param[in] myLowPowerMode: Low power mode. + * @param[in] myT_Off: Period only if ON/OFF mode is selected ( in myLowPowerMode ), it is ignored otherwise. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetLowPowerMode. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A + * @warning Data-sheet p.14 8.1.1 Listening Mode. It is NOT clear which channels have to be enabled according to the + * low power mode: '...If the three dimensional detection is not required, then it is possible to deactivate one + * or more channels. In case only two channels are required, then the deactivated channel must be the number + * three; while in case only one channel is needed, then the active channel must be the number one'. + * + * Data-sheet p.37 8.10 Channel Selection in Scanning Mode and ON/OFF Mode: 'In case only 2 channels are active and + * one of the Low Power modes is enabled, then the channels 1 and 3 have to be active. If the chip works in On-Off + * mode and only one channel is active then the active channel has to be the channel 1.'. + * + * This function follows the methodology in: Low Power Modes/Channels enabled: Data-sheet p.37 8.10 Channel + * Selection in Scanning Mode and ON/OFF Mode. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetLowPowerMode ( AS3933_channels_enable_t myEnabledChannels, AS3933_scanning_mode_t myLowPowerMode, AS3933_r4_t_off_value_t myT_Off ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R0 register + cmd[0] = ( AS3933_READ | AS3933_R0 ); + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + + // Mask Channels 1:3 + cmd[1] &= ~( EN_A1_MASK | EN_A2_MASK | EN_A3_MASK ); + + // Mask Scanning Mode + cmd[1] &= ~( MUX_123_MASK | ON_OFF_MASK ); + + + + // Set the channels enabled + switch ( myEnabledChannels ) + { + case AS3933_CH1_OFF_CH2_OFF_CH3_OFF: + cmd[1] &= ( EN_A1_DISABLED | EN_A2_DISABLED | EN_A3_DISABLED ); + break; + + case AS3933_CH1_ON_CH2_OFF_CH3_OFF: + cmd[1] |= ( EN_A1_ENABLED ); + break; + + case AS3933_CH1_OFF_CH2_ON_CH3_OFF: + cmd[1] |= ( EN_A2_ENABLED ); + break; + + case AS3933_CH1_ON_CH2_ON_CH3_OFF: + cmd[1] |= ( EN_A1_ENABLED | EN_A2_ENABLED ); + break; + + case AS3933_CH1_OFF_CH2_OFF_CH3_ON: + cmd[1] |= ( EN_A3_ENABLED ); + break; + + case AS3933_CH1_ON_CH2_OFF_CH3_ON: + cmd[1] |= ( EN_A1_ENABLED | EN_A3_ENABLED ); + break; + + case AS3933_CH1_OFF_CH2_ON_CH3_ON: + cmd[1] |= ( EN_A2_ENABLED | EN_A3_ENABLED ); + break; + + default: + case AS3933_CH1_ON_CH2_ON_CH3_ON: + cmd[1] |= ( EN_A1_ENABLED | EN_A2_ENABLED | EN_A3_ENABLED ); + break; + } + + + // Set Scanning mode + switch ( myLowPowerMode ) + { + default: + case AS3933_STANDARD_LISTENING_MODE: + break; + + case AS3933_SCANNING_MODE: + if ( ( myEnabledChannels == AS3933_CH1_ON_CH2_OFF_CH3_ON ) || ( myEnabledChannels == AS3933_CH1_ON_CH2_ON_CH3_ON ) || ( myEnabledChannels == AS3933_CH1_ON_CH2_OFF_CH3_OFF ) || + ( myEnabledChannels == AS3933_CH1_OFF_CH2_ON_CH3_OFF ) || ( myEnabledChannels == AS3933_CH1_OFF_CH2_OFF_CH3_ON ) ) + cmd[1] |= ( MUX_123_ENABLED ); + else + return AS3933_FAILURE; + + break; + + case AS3933_ON_OFF_MODE: + if ( ( myEnabledChannels == AS3933_CH1_ON_CH2_OFF_CH3_ON ) || ( myEnabledChannels == AS3933_CH1_ON_CH2_ON_CH3_ON ) || ( myEnabledChannels == AS3933_CH1_ON_CH2_OFF_CH3_OFF ) ) + cmd[1] |= ( ON_OFF_ENABLED ); + else + return AS3933_FAILURE; + break; + } + + // Update power mode and active channels + cmd[0] = ( AS3933_WRITE | AS3933_R0 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + if ( myLowPowerMode == AS3933_ON_OFF_MODE ) + { + // Read R4 register + cmd[0] = ( AS3933_READ | AS3933_R4 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask T_OFF + cmd[1] &= ~( T_OFF_MASK ); + + // Update Off time in ON/OFF operation mode + cmd[1] |= ( myT_Off ); + + cmd[0] = ( AS3933_WRITE | AS3933_R4 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + } + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetArtificialWakeUp ( AS3933_r8_t_auto_value_t ) + * + * @details It configures the artificial wakeup. + * + * @param[in] myArtificialWakeUp: Period only if ON/OFF mode is selected ( in myLowPowerMode ), it is ignored otherwise. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetArtificialWakeUp. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetArtificialWakeUp ( AS3933_r8_t_auto_value_t myArtificialWakeUp ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R8 register + cmd[0] = ( AS3933_READ | AS3933_R8 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Artificial wakeup + cmd[1] &= ~( T_AUTO_MASK ); + + // Update the value + cmd[1] |= myArtificialWakeUp; + + + // Update artificial wakeup + cmd[0] = ( AS3933_WRITE | AS3933_R8 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_ReadFalseWakeUpRegister ( AS3933_data_t* ) + * + * @details It gets feedback on the surrounding environment reading the false wakeup register. + * + * @param[in] N/A + * + * @param[out] myF_WAKE: F_WAKE register. + * + * + * @return Status of AS3933_ReadFalseWakeUpRegister. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_ReadFalseWakeUpRegister ( AS3933_data_t* myF_WAKE ) +{ + char cmd = ( AS3933_READ | AS3933_R13 ); + int mySPI_status; + + + // Read R13 register + _cs = 1; + mySPI_status = _spi.write ( &cmd, 1, (char*)( &myF_WAKE->f_wake ), 1 ); + _cs = 0; + + + + + if ( mySPI_status == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetClockGenerator ( AS3933_r1_en_xtal_value_t, AS3933_r16_clock_gen_dis_value_t ) + * + * @details It configures the clock generator. + * + * @param[in] myClockGenerator: Enable/Disable external crystal oscillator. + * @param[in] myClockGeneratorOutputMode: Enable/Disable the clock generator output signal displayed on CL_DAT pin. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetClockGenerator. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetClockGenerator ( AS3933_r1_en_xtal_value_t myClockGenerator, AS3933_r16_clock_gen_dis_value_t myClockGeneratorOutputMode ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Configure the Crystal oscillator + // Read R1 register + cmd[0] = ( AS3933_READ | AS3933_R1 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Crystal oscillator + cmd[1] &= ~( EN_XTAL_MASK ); + + // Update the value + cmd[1] |= myClockGenerator; + + + // Update Crystal oscillator + cmd[0] = ( AS3933_WRITE | AS3933_R1 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + // Configure the Clock Generator Output + // Read R16 register + cmd[0] = ( AS3933_READ | AS3933_R16 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Clock Generator output signal + cmd[1] &= ~( CLOCK_GEN_DIS_MASK ); + + // Update the value + cmd[1] |= myClockGeneratorOutputMode; + + + // Update Clock Generator output signal + cmd[0] = ( AS3933_WRITE | AS3933_R16 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_CalibrateRC_Oscillator ( AS3933_r1_en_xtal_value_t, AS3933_r16_clock_gen_dis_value_t ) + * + * @details It calibrates RC oscillator. + * + * @param[in] N/A + * + * @param[out] N/A. + * + * + * @return Status of AS3933_CalibrateRC_Oscillator. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre RC-Oscillator: Self Calibration is ONLY available. + * @warning In case the pattern detection and the Manchester decoder are not enabled ( R1<1>=0 and R1<3>=1 ) the calibration on the RC-oscillator + * is not needed. Should this not be the case, the RC-oscillator has to be calibrated. + */ +AS3933::AS3933_status_t AS3933::AS3933_CalibrateRC_Oscillator ( void ) +{ + char cmd = 0; + uint32_t myTimeout = 0; + int mySPI_status; + + + // Start the calibration + cmd = ( AS3933_DIRECT_COMMAND | CALIB_RCO_LC ); + _cs = 1; + mySPI_status = _spi.write ( &cmd, 1, &cmd, 0 ); + _cs = 0; + + + // RC oscillator will be calibrated when RC_CAL_OK = '1' ( R14<6> ) + myTimeout = 23232323; + do{ + cmd = ( AS3933_READ | AS3933_R14 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd, 1, &cmd, 1 ); + _cs = 0; + myTimeout--; + } while ( ( ( cmd & RC_CAL_OK_MASK ) != RC_CAL_OK_HIGH ) && ( myTimeout > 0 ) ); + + + + if ( ( mySPI_status == SPI_SUCCESS ) && ( myTimeout > 0 ) ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetAntennaDamper ( AS3933_r1_att_on_value_t, AS3933_r4_d_res_value_t ) + * + * @details It configures the antenna damper and its shunt resistor. + * + * @param[in] myAntennaDamperMode: Enable/Disable antenna dumper. + * @param[in] myShuntResistor: Configure antenna dumping resistor. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetAntennaDamper. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetAntennaDamper ( AS3933_r1_att_on_value_t myAntennaDamperMode, AS3933_r4_d_res_value_t myShuntResistor ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Configure Antenna dumper + // Read R1 register + cmd[0] = ( AS3933_READ | AS3933_R1 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Antenna dumper + cmd[1] &= ~( ATT_ON_MASK ); + + // Update Antenna dumper + cmd[0] = ( AS3933_WRITE | AS3933_R1 ); + cmd[1] |= ( myAntennaDamperMode ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + // Configure Antenna dumper resistor + // Read R4 register + cmd[0] = ( AS3933_READ | AS3933_R4 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Antenna dumper resistor + cmd[1] &= ~( D_RES_MASK ); + + // Update Antenna dumper resistor + cmd[0] = ( AS3933_WRITE | AS3933_R4 ); + cmd[1] |= ( myShuntResistor ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetEnvelopDetector ( AS3933_r3_fs_env_value_t ) + * + * @details It configures the envelop detector for different symbol rates. + * + * @param[in] mySymbolRates: Envelop detector time constant. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetEnvelopDetector. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetEnvelopDetector ( AS3933_r3_fs_env_value_t mySymbolRates ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R3 register + cmd[0] = ( AS3933_READ | AS3933_R3 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Symbol rate + cmd[1] &= ~( FS_ENV_MASK ); + + // Update symbol rate + cmd[0] = ( AS3933_WRITE | AS3933_R3 ); + cmd[1] |= ( mySymbolRates ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetDataSlicer ( AS3933_r1_abs_hy_value_t , AS3933_r3_fs_scl_value_t ) + * + * @details It configures the data slicer for different preamble length. + * + * @param[in] myAbsoluteThresholdMode: Enable Data slicer absolute reference. + * @param[in] myMinimumPreambleLength: Data slices time constant. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetDataSlicer. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetDataSlicer ( AS3933_r1_abs_hy_value_t myAbsoluteThresholdMode, AS3933_r3_fs_scl_value_t myMinimumPreambleLength ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Configure Data slicer absolute reference + // Read R1 register + cmd[0] = ( AS3933_READ | AS3933_R1 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Data slicer absolute reference + cmd[1] &= ~( ABS_HY_MASK ); + + // Update symbol rate + cmd[0] = ( AS3933_WRITE | AS3933_R1 ); + cmd[1] |= ( myAbsoluteThresholdMode ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + // Configure Data slices time constant + // Read R3 register + cmd[0] = ( AS3933_READ | AS3933_R3 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Data slices time constant + cmd[1] &= ~( FS_SCL_MASK ); + + // Update Data slices time constant + cmd[0] = ( AS3933_WRITE | AS3933_R3 ); + cmd[1] |= ( myMinimumPreambleLength ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetComparatorHysteresis ( AS3933_r3_hy_pos_value_t , AS3933_r3_hy_20m_value_t ) + * + * @details It configures the hysteresis on the data slicer comparator. + * + * @param[in] myHysteresisMode: Data slicer hysteresis, edge. + * @param[in] myHysteresisRange: Data slicer hysteresis, comparator. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetComparatorHysteresis. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetComparatorHysteresis ( AS3933_r3_hy_pos_value_t myHysteresisMode, AS3933_r3_hy_20m_value_t myHysteresisRange ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R3 register + cmd[0] = ( AS3933_READ | AS3933_R3 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask both hysteresis edge and comparator + cmd[1] &= ~( HY_POS_MASK | HY_20M_MASK ); + + // Update hysteresis on the data slicer comparator + cmd[0] = ( AS3933_WRITE | AS3933_R3 ); + cmd[1] |= ( myHysteresisMode | myHysteresisRange ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetGainReduction ( AS3933_r4_gr_value_t ) + * + * @details It configures the gain reduction. + * + * @param[in] myGainReductionValue: Gain reduction. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetGainReduction. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetGainReduction ( AS3933_r4_gr_value_t myGainReductionValue ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R4 register + cmd[0] = ( AS3933_READ | AS3933_R4 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Gain reduction + cmd[1] &= ~( GR_MASK ); + + // Update Gain reduction + cmd[0] = ( AS3933_WRITE | AS3933_R4 ); + cmd[1] |= ( myGainReductionValue ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetOperatingFrequencyRange ( AS3933_r8_band_sel_value_t ) + * + * @details It configures the operating frequency range. + * + * @param[in] myOperatingFrequencyRange: Band selection. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetOperatingFrequencyRange. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetOperatingFrequencyRange ( AS3933_r8_band_sel_value_t myOperatingFrequencyRange ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R8 register + cmd[0] = ( AS3933_READ | AS3933_R8 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Band selection + cmd[1] &= ~( BAND_SEL_MASK ); + + // Update Band selection + cmd[0] = ( AS3933_WRITE | AS3933_R8 ); + cmd[1] |= ( myOperatingFrequencyRange ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetFrequencyDetectionTolerance ( AS3933_tolerance_settings_t ) + * + * @details It configures the frequency detection tolerance. + * + * @param[in] myTolerance: Tolerance band. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetFrequencyDetectionTolerance. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetFrequencyDetectionTolerance ( AS3933_tolerance_settings_t myTolerance ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R2 register + cmd[0] = ( AS3933_READ | AS3933_R2 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Tolerance band + cmd[1] &= ~( AS3933_TOLERANCE_MASK ); + + // Update Tolerance band + cmd[0] = ( AS3933_WRITE | AS3933_R2 ); + cmd[1] |= ( myTolerance ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetGainBoost ( AS3933_r2_g_boost_value_t ) + * + * @details It configures the +3dB gain boost. + * + * @param[in] myGainBoostMode: Enable/Disable +3dB Amplifier Gain Boost. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetGainBoost. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetGainBoost ( AS3933_r2_g_boost_value_t myGainBoostMode ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R2 register + cmd[0] = ( AS3933_READ | AS3933_R2 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Gain boost + cmd[1] &= ~( G_BOOST_MASK ); + + // Update Gain boost + cmd[0] = ( AS3933_WRITE | AS3933_R2 ); + cmd[1] |= ( myGainBoostMode ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetAGC ( AS3933_r1_agc_tlim_value_t , AS3933_r1_agc_ud_value_t ) + * + * @details It configures the Automatic Gain Control ( AGC ). + * + * @param[in] myAGC_CarrierBurstMode: Enable/Disable AGC acting only on the first carrier burst. + * @param[in] myAGC_OperatingDirection: Configure AGC direction operating. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetAGC. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetAGC ( AS3933_r1_agc_tlim_value_t myAGC_CarrierBurstMode, AS3933_r1_agc_ud_value_t myAGC_OperatingDirection ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R1 register + cmd[0] = ( AS3933_READ | AS3933_R1 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask both AGC acting only on the first carrier burst and AGC direction operating + cmd[1] &= ~( AGC_TLIM_MASK | AGC_UD_MASK ); + + // Update both AGC acting only on the first carrier burst and AGC direction operating + cmd[0] = ( AS3933_WRITE | AS3933_R1 ); + cmd[1] |= ( myAGC_CarrierBurstMode | myAGC_OperatingDirection ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetDataMask ( AS3933_r0_dat_mask_value_t ) + * + * @details It configures the mask data before wakeup. + * + * @param[in] myDataMaskMode: Mask data on DAT pin before wakeup happens. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetDataMask. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetDataMask ( AS3933_r0_dat_mask_value_t myDataMaskMode ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R0 register + cmd[0] = ( AS3933_READ | AS3933_R0 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Mask data on DAT pin before wakeup happens + cmd[1] &= ~( DAT_MASK_MASK ); + + // Update Mask data on DAT pin before wakeup happens + cmd[0] = ( AS3933_WRITE | AS3933_R0 ); + cmd[1] |= ( myDataMaskMode ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetCorrelator ( AS3933_r1_en_wpat_value_t , AS3933_r0_patt32_value_t , AS3933_r7_t_hbit_value_t , AS3933_r1_en_manch_value_t ) + * + * @details It configures the correlator and the Manchester Decoder. + * + * @param[in] myCorrelatorMode: Enable/Disable Correlator. + * @param[in] mySymbolPattern: Pattern extended. + * @param[in] myRate: Bit rate definition. + * @param[in] myManchesterDecoderMode: Enable/Disable Manchester decoder. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetCorrelator. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetCorrelator ( AS3933_r1_en_wpat_value_t myCorrelatorMode, AS3933_r0_patt32_value_t mySymbolPattern, AS3933_r7_t_hbit_value_t myRate, + AS3933_r1_en_manch_value_t myManchesterDecoderMode ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Configure Correlator mode and Manchester decoder mode + // Read R1 register + cmd[0] = ( AS3933_READ | AS3933_R1 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask both Correlator mode and Manchester decoder mode + cmd[1] &= ~( EN_WPAT_MASK | EN_MANCH_MASK ); + + // Update both Correlator mode and Manchester decoder mode + cmd[0] = ( AS3933_WRITE | AS3933_R1 ); + cmd[1] |= ( myCorrelatorMode | myManchesterDecoderMode ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + // Configure Pattern extended + // Read R0 register + cmd[0] = ( AS3933_READ | AS3933_R0 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Pattern extended + cmd[1] &= ~( PATT32_MASK ); + + // Update Pattern extended + cmd[0] = ( AS3933_WRITE | AS3933_R0 ); + cmd[1] |= ( mySymbolPattern ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + // Configure Bit rate definition + // Read R7 register + cmd[0] = ( AS3933_READ | AS3933_R7 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Bit rate definition + cmd[1] &= ~( T_HBIT_MASK ); + + // Update Bit rate definition + cmd[0] = ( AS3933_WRITE | AS3933_R7 ); + cmd[1] |= ( myRate ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetWakeUpPattern ( AS3933_data_t ) + * + * @details It sets the wakeup pattern ( Manchester ). + * + * @param[in] myWakeUpPattern: PATT1B and PATT2B ( Manchester ). + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetWakeUpPattern. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetWakeUpPattern ( AS3933_data_t myWakeUpPattern ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Update PATT2B + cmd[0] = ( AS3933_WRITE | AS3933_R5 ); + cmd[1] = ( myWakeUpPattern.patt2b ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + // Update PATT1B + cmd[0] = ( AS3933_WRITE | AS3933_R6 ); + cmd[1] = ( myWakeUpPattern.patt1b ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_GetWakeUpPattern ( AS3933_data_t* ) + * + * @details It gets the wakeup pattern ( Manchester ). + * + * @param[in] N/A + * + * @param[out] myWakeUpPattern: PATT1B and PATT2B ( Manchester ). + * + * + * @return Status of AS3933_GetWakeUpPattern. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_GetWakeUpPattern ( AS3933_data_t* myWakeUpPattern ) +{ + char cmd = 0; + int mySPI_status; + + + // Read R5 register + cmd = ( AS3933_READ | AS3933_R5 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd, 1, (char*)&myWakeUpPattern->patt2b, 1 ); + _cs = 0; + + // Read R6 register + cmd = ( AS3933_READ | AS3933_R6 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd, 1, (char*)&myWakeUpPattern->patt1b, 1 ); + _cs = 0; + + + + + if ( mySPI_status == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetAutomaticTimeOut ( AS3933_r7_t_out_value_t ) + * + * @details It sets the automatic time-out setup. + * + * @param[in] myAutomaticTimeOut: Automatic time-out. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetAutomaticTimeOut. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetAutomaticTimeOut ( AS3933_r7_t_out_value_t myAutomaticTimeOut ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + + // Read R7 register + cmd[0] = ( AS3933_READ | AS3933_R7 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Automatic time-out + cmd[1] &= ~( T_OUT_MASK ); + + // Update Automatic time-out + cmd[0] = ( AS3933_WRITE | AS3933_R7 ); + cmd[1] |= ( myAutomaticTimeOut ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_SetParallelTuningCapacitance ( AS3933_parallel_tuning_channels_t , AS3933_parallel_tuning_capacitance_t ) + * + * @details It sets the parallel tuning capacitance on the chosen channel. + * + * @param[in] myChannel: Channel for Parallel Tuning Capacitance. + * @param[in] myAddedCapacitance: Parallel Tuning Capacitance. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_SetParallelTuningCapacitance. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_SetParallelTuningCapacitance ( AS3933_parallel_tuning_channels_t myChannel, AS3933_parallel_tuning_capacitance_t myAddedCapacitance ) +{ + char cmd[] = { 0, 0 }; + int mySPI_status; + + AS3933_spi_command_structure_registers_t myAuxRegister; + + + // Select the channel + switch ( myChannel ){ + default: + case AS3933_CHANNEL_LF1P: + myAuxRegister = AS3933_R17; + break; + + case AS3933_CHANNEL_LF2P: + myAuxRegister = AS3933_R18; + break; + + case AS3933_CHANNEL_LF3P: + myAuxRegister = AS3933_R19; + break; + } + + + // Read register + cmd[0] = ( AS3933_READ | myAuxRegister ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[1], 1 ); + _cs = 0; + + // Mask Parallel Tuning Capacitance + cmd[1] &= ~( AS3933_CAPACITANCE_MASK ); + + // Update Parallel Tuning Capacitance + cmd[0] = ( AS3933_WRITE | myAuxRegister ); + cmd[1] |= ( myAddedCapacitance ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), &cmd[0], 0 ); + _cs = 0; + + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + +/** + * @brief AS3933_GetRSSI ( AS3933_data_t* ) + * + * @details It gets the RSSI for all channels. + * + * @param[in] mySPI_parameters: N/A + * + * @param[out] myChannelRSSI: RSSI. + * + * + * @return Status of AS3933_GetRSSI. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_GetRSSI ( AS3933_data_t* myChannelRSSI ) +{ + char cmd[] = { 0, 0, 0 }; + int mySPI_status; + + + // Get All RSSIs + // Read R10 register ( auto-increment ) + cmd[0] = ( AS3933_READ | AS3933_R10 ); + _cs = 1; + mySPI_status = _spi.write ( &cmd[0], 1, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) ); + _cs = 0; + + // Parse the data + myChannelRSSI->rssi1 = ( cmd[0] & RSSI1_MASK ); // Channel1: RSSI1 + myChannelRSSI->rssi3 = ( cmd[1] & RSSI3_MASK ); // Channel3: RSSI3 + myChannelRSSI->rssi2 = ( cmd[2] & RSSI2_MASK ); // Channel2: RSSI2 + + + + + + if ( ( mySPI_status / ( sizeof( cmd )/sizeof( cmd[0] ) ) ) == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +} + + + +/** + * @brief AS3933_Send_DirectCommand ( AS3933_spi_direct_commands_t ) + * + * @details It sends a direct command. + * + * @param[in] myDirectCommand: Direct command to be sent. + * + * @param[out] N/A. + * + * + * @return Status of AS3933_Send_DirectCommand. + * + * + * @author Manuel Caballero + * @date 7/March/2018 + * @version 7/March/2018 The ORIGIN + * @pre N/A. + * @warning N/A. + */ +AS3933::AS3933_status_t AS3933::AS3933_Send_DirectCommand ( AS3933_spi_direct_commands_t myDirectCommand ) +{ + char cmd = 0; + int mySPI_status; + + + // Send a direct command + cmd = ( AS3933_DIRECT_COMMAND | myDirectCommand ); + _cs = 1; + mySPI_status = _spi.write ( &cmd, 1, &cmd, 0 ); + _cs = 0; + + + + + if ( mySPI_status == SPI_SUCCESS ) + return AS3933_SUCCESS; + else + return AS3933_FAILURE; +}