diff --git a/platform/drivers/baseband/HR_C6000.cpp b/platform/drivers/baseband/HR_C6000.cpp index 795e0719..fa22a7ad 100644 --- a/platform/drivers/baseband/HR_C6000.cpp +++ b/platform/drivers/baseband/HR_C6000.cpp @@ -67,3 +67,25 @@ void HR_C6000::setRxCtcss(const tone_t tone) writeCfgRegister(0xD2, 0xD0); writeCfgRegister(0xD4, index); // Tone index } + +void HR_C6000::sendTone(const uint32_t freq, const uint8_t deviation) +{ + uint32_t tone = (freq * 65536) / 32000; + + // Set DTMF tone osc 1 to frequency of the required tone + writeReg16(C6000_SpiOpModes::CONFIG, 0x11A, (tone & 0xFF)); + writeReg16(C6000_SpiOpModes::CONFIG, 0x11B, (tone >> 8) & 0xFF); + + // Set DTMF tone osc 2 to frequency of the required tone + writeReg16(C6000_SpiOpModes::CONFIG, 0x122, (tone & 0xFF)); + writeReg16(C6000_SpiOpModes::CONFIG, 0x123, (tone >> 8) & 0xFF); + + writeCfgRegister(0xA1, 0x02); // Enable DTMF + writeCfgRegister(0xA0, deviation); // Set DTMF tone deviation + writeCfgRegister(0xA4, 0xFF); // Set the tone time to maximum + writeCfgRegister(0xA3, 0x00); // Set the tone gap to zero + writeCfgRegister(0xD1, 0x06); // Set the number of codes to six + writeCfgRegister(0xAF, 0x11); // Set the same code to be sent six times (2 codes per register) + writeCfgRegister(0xAE, 0x11); + writeCfgRegister(0xAD, 0x11); +} diff --git a/platform/drivers/baseband/HR_C6000.h b/platform/drivers/baseband/HR_C6000.h index 943b0038..8e9e4a4d 100644 --- a/platform/drivers/baseband/HR_C6000.h +++ b/platform/drivers/baseband/HR_C6000.h @@ -81,6 +81,36 @@ public: { writeCfgRegister(0xA1, 0x00); // Disable all tones } + + /** + * Transmit a tone of a given frequency. + * + * @param freq: tone frequency in Hz. + * @param deviation: tone deviation. + */ + void sendTone(const uint32_t freq, const uint8_t deviation); + +private: + + /** + * Write a register with 16-bit address. + * + * @param opMode: "operating mode" specifier, see datasheet for details. + * @param addr: register address. + * @param value: value to be written. + */ + void writeReg16(const C6000_SpiOpModes opMode, const uint16_t addr, const uint8_t value) + { + uint8_t data[4]; + + data[0] = static_cast< uint8_t >(opMode) | 0x40; + data[2] = (addr >> 8) & 0x07; + data[1] = addr & 0xFF; + data[3] = value; + + ScopedChipSelect cs(uSpi, uCs); + spi_send(uSpi, data, 4); + } }; #endif /* HRC6000_H */ diff --git a/platform/drivers/baseband/HR_Cx000.h b/platform/drivers/baseband/HR_Cx000.h index a5970e85..027cdc77 100644 --- a/platform/drivers/baseband/HR_Cx000.h +++ b/platform/drivers/baseband/HR_Cx000.h @@ -263,6 +263,8 @@ private: spi_send(uSpi, seq, len); } +protected: + const struct spiDevice *uSpi; const struct gpioPin uCs; };