This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1101: RC-CC1101-SPI-868_F

Part Number: CC1101
Other Parts Discussed in Thread: CC2500, CC1100, TEST2

Tool/software:

Hi, I have an issue with my code. Specifically, whenever I try to read data sent from the second CC1101 transceiver,

my code gets stuck waiting for the interrupt to indicate that the data has been received (while(GDO0_FLAG == 0);).

I’ve been trying to solve this problem for 2 weeks now. Below is the entire code along with the libraries used.

/*

* TPMS.h

*

* Created on: Oct 16, 2024

* Author: Cienki

*/

#ifndef INC_CC1101_H_

#define INC_CC1101_H_

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

#ifndef __Stm32f4xx_HAL_H

#include "stm32f4xx_hal.h"

#endif

//-------------------------------------------------------------------------------------------------------

typedef unsigned char BOOL;

// Data

typedef unsigned char BYTE;

typedef unsigned short WORD;

typedef unsigned long DWORD;

// Unsigned numbers

typedef unsigned char UINT8;

typedef unsigned short UINT16;

typedef unsigned long UINT32;

// Signed numbers

typedef signed char INT8;

typedef signed short INT16;

typedef signed long INT32;

//-------------------------------------------------------------------------------------------------------

// Common values

#ifndef FALSE

#define FALSE 0

#endif

#ifndef TRUE

#define TRUE 1

#endif

//------------------------------------------------------------------------------------------------------

// CC2500/CC1100 STROBE, CONTROL AND STATUS REGSITER

#define IOCFG2 0x00 // GDO2 output pin configuration

#define IOCFG1 0x01 // GDO1 output pin configuration

#define IOCFG0 0x02 // GDO0 output pin configuration

#define FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds

#define SYNC1 0x04 // Sync word, high byte

#define SYNC0 0x05 // Sync word, low byte

#define PKTLEN 0x06 // Packet length

#define PKTCTRL1 0x07 // Packet automation control

#define PKTCTRL0 0x08 // Packet automation control

#define ADDR 0x09 // Device address

#define CHANNR 0x0A // Channel number

#define FSCTRL1 0x0B // Frequency synthesizer control

#define FSCTRL0 0x0C // Frequency synthesizer control

#define FREQ2 0x0D // Frequency control word, high byte

#define FREQ1 0x0E // Frequency control word, middle byte

#define FREQ0 0x0F // Frequency control word, low byte

#define MDMCFG4 0x10 // Modem configuration

#define MDMCFG3 0x11 // Modem configuration

#define MDMCFG2 0x12 // Modem configuration

#define MDMCFG1 0x13 // Modem configuration

#define MDMCFG0 0x14 // Modem configuration

#define DEVIATN 0x15 // Modem deviation setting

#define MCSM2 0x16 // Main Radio Control State Machine configuration

#define MCSM1 0x17 // Main Radio Control State Machine configuration

#define MCSM0 0x18 // Main Radio Control State Machine configuration

#define FOCCFG 0x19 // Frequency Offset Compensation configuration

#define BSCFG 0x1A // Bit Synchronization configuration

#define AGCCTRL2 0x1B // AGC control

#define AGCCTRL1 0x1C // AGC control

#define AGCCTRL0 0x1D // AGC control

#define WOREVT1 0x1E // High byte Event 0 timeout

#define WOREVT0 0x1F // Low byte Event 0 timeout

#define WORCTRL 0x20 // Wake On Radio control

#define FREND1 0x21 // Front end RX configuration

#define FREND0 0x22 // Front end TX configuration

#define FSCAL3 0x23 // Frequency synthesizer calibration

#define FSCAL2 0x24 // Frequency synthesizer calibration

#define FSCAL1 0x25 // Frequency synthesizer calibration

#define FSCAL0 0x26 // Frequency synthesizer calibration

#define RCCTRL1 0x27 // RC oscillator configuration

#define RCCTRL0 0x28 // RC oscillator configuration

#define FSTEST 0x29 // Frequency synthesizer calibration control

#define PTEST 0x2A // Production test

#define AGCTEST 0x2B // AGC test

#define TEST2 0x2C // Various test settings

#define TEST1 0x2D // Various test settings

#define TEST0 0x2E // Various test settings

#define PARTNUM 0x30 // Chip ID

#define VERSION 0x31 // Chip ID

#define FREQEST 0x32 // Frequency Offset Estimate from Demodulator

#define LQI 0x33 // Demodulator Estimate for Link Quality

#define RSSI 0x34 // Received Signal Strength Indication

#define MARCSTATE 0x35 // Main Radio Control State Machine State

#define WORTIME1 0x36 // High Byte of WOR Time

#define WORTIME0 0x37 // Low Byte of WOR Time

#define PKTSTATUS 0x38 // Current GDOx Status and Packet Status

#define VCO_VC_DAC 0x39 // Current Setting from PLL Calibration Module

#define TXBYTES 0x3A // Underflow and Number of Bytes

#define RXBYTES 0x3B // Overflow and Number of Bytes

#define RCCTRL1_STATUS 0x3C // Last RC Oscillator Calibration Result

#define RCCTRL0_STATUS 0x3D // Last RC Oscillator Calibration Result

// Strobe commands

#define CCxxx0_SRES 0x30 // Reset chip.

#define CCxxx0_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).

// If in RX/TX: Go to a wait state where only the synthesizer is

// running (for quick RX / TX turnaround).

#define CCxxx0_SXOFF 0x32 // Turn off crystal oscillator.

#define CCxxx0_SCAL 0x33 // Calibrate frequency synthesizer and turn it off

// (enables quick start).

#define CCxxx0_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and

// MCSM0.FS_AUTOCAL=1.

#define CCxxx0_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if

// MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:

// Only go to TX if channel is clear.

#define CCxxx0_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit

// Wake-On-Radio mode if applicable.

#define CCxxx0_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer

#define CCxxx0_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)

#define CCxxx0_SPWD 0x39 // Enter power down mode when CSn goes high.

#define CCxxx0_SFRX 0x3A // Flush the RX FIFO buffer.

#define CCxxx0_SFTX 0x3B // Flush the TX FIFO buffer.

#define CCxxx0_SWORRST 0x3C // Reset real time clock.

#define CCxxx0_SNOP 0x3D // No operation. May be used to pad strobe commands to two

// bytes for simpler software.

// Status registers

#define TI_CCxxx0_NUM_RXBYTES 0x7F // Mask "# of bytes" field in _RXBYTES

#define CCxxx0_PATABLE 0x3E

#define CCxxx0_TXFIFO 0x3F

#define CCxxx0_RXFIFO 0x3F

// Masks for appended status bytes

#define TI_CCxxx0_LQI_RX 0x01 // Position of LQI byte

#define TI_CCxxx0_CRC_OK 0x80 // Mask "CRC_OK" bit within LQI byte

// Definitions to support burst/single access:

#define TI_CCxxx0_WRITE_BURST 0x40

#define TI_CCxxx0_READ_SINGLE 0x80

#define TI_CCxxx0_READ_BURST 0xC0

//-------------------------------------------------------------------------------------------------------

// RF_SETTINGS is a data structure which contains all relevant CCxxx0 registers

//i didnt use because i used with TI_write_settings() in cc1101.c

/*typedef struct S_RF_SETTINGS{

BYTE FSCTRL1; // Frequency synthesizer control.

BYTE FSCTRL0; // Frequency synthesizer control.

BYTE FREQ2; // Frequency control word, high byte.

BYTE FREQ1; // Frequency control word, middle byte.

BYTE FREQ0; // Frequency control word, low byte.

BYTE MDMCFG4; // Modem configuration.

BYTE MDMCFG3; // Modem configuration.

BYTE MDMCFG2; // Modem configuration.

BYTE MDMCFG1; // Modem configuration.

BYTE MDMCFG0; // Modem configuration.

BYTE CHANNR; // Channel number.

BYTE DEVIATN; // Modem deviation setting (when FSK modulation is enabled).

BYTE FREND1; // Front end RX configuration.

BYTE FREND0; // Front end RX configuration.

BYTE MCSM0; // Main Radio Control State Machine configuration.

BYTE FOCCFG; // Frequency Offset Compensation Configuration.

BYTE BSCFG; // Bit synchronization Configuration.

BYTE AGCCTRL2; // AGC control.

BYTE AGCCTRL1; // AGC control.

BYTE AGCCTRL0; // AGC control.

BYTE FSCAL3; // Frequency synthesizer calibration.

BYTE FSCAL2; // Frequency synthesizer calibration.

BYTE FSCAL1; // Frequency synthesizer calibration.

BYTE FSCAL0; // Frequency synthesizer calibration.

BYTE FSTEST; // Frequency synthesizer calibration control

BYTE TEST2; // Various test settings.

BYTE TEST1; // Various test settings.

BYTE TEST0; // Various test settings.

BYTE FIFOTHR; // RXFIFO and TXFIFO thresholds.

BYTE IOCFG2; // GDO2 output pin configuration

BYTE IOCFG0; // GDO0 output pin configuration

BYTE PKTCTRL1; // Packet automation control.

BYTE PKTCTRL0; // Packet automation control.

BYTE ADDR; // Device address.

BYTE PKTLEN; // Packet length.

} RF_SETTINGS;

RF_SETTINGS TISettings = {

0x08, // FSCTRL1 Frequency synthesizer control.

0x00, // FSCTRL0 Frequency synthesizer control.

0x10, // FREQ2 Frequency control word, high byte.

0xB4, // FREQ1 Frequency control word, middle byte.

0x2E, // FREQ0 Frequency control word, low byte.

0xCA, // MDMCFG4 Modem configuration.

0x83, // MDMCFG3 Modem configuration.

0x93, // MDMCFG2 Modem configuration.

0x22, // MDMCFG1 Modem configuration.

0xF8, // MDMCFG0 Modem configuration.

0x00, // CHANNR Channel number.

0x34, // DEVIATN Modem deviation setting (when FSK modulation is enabled).

0x56, // FREND1 Front end RX configuration.

0x10, // FREND0 Front end TX configuration.

0x18, // MCSM0 Main Radio Control State Machine configuration.

0x16, // FOCCFG Frequency Offset Compensation Configuration.

0x6C, // BSCFG Bit synchronization Configuration.

0x43, // AGCCTRL2 AGC control.

0x40, // AGCCTRL1 AGC control.

0x91, // AGCCTRL0 AGC control.

0xE9, // FSCAL3 Frequency synthesizer calibration.

0x2A, // FSCAL2 Frequency synthesizer calibration.

0x00, // FSCAL1 Frequency synthesizer calibration.

0x1F, // FSCAL0 Frequency synthesizer calibration.

0x59, // FSTEST Frequency synthesizer calibration.

0x81, // TEST2 Various test settings.

0x35, // TEST1 Various test settings.

0x09, // TEST0 Various test settings.

0x47, // FIFOTHR RXFIFO and TXFIFO thresholds.

0x29, // IOCFG2 GDO2 output pin configuration.

0x06, // IOCFG0D GDO0 output pin configuration.

0x04, // PKTCTRL1 Packet automation control.

0x05, // PKTCTRL0 Packet automation control.

0x00, // ADDR Device address.

0xFF // PKTLEN Packet length.

};

extern RF_SETTINGS code TISettings; //it didnt work

*/

//Function definitions

HAL_StatusTypeDef __spi_write(uint8_t* addr, uint8_t *pData, uint16_t size);

HAL_StatusTypeDef __spi_read(uint8_t* addr, uint8_t *pData, uint16_t size);

void TI_init(SPI_HandleTypeDef* hspi, GPIO_TypeDef* cs_port, uint16_t cs_pin);

void TI_write_reg(UINT8 addr, UINT8 value);

void TI_write_burst_reg(BYTE addr, BYTE * buffer, BYTE count);

void TI_write_burst_reg_c(BYTE addr, BYTE * buffer, BYTE count);

void TI_strobe(BYTE strobe);

BYTE TI_read_reg(BYTE addr);

BYTE TI_read_status(BYTE addr);

void TI_read_burst_reg(BYTE addr, BYTE * buffer, BYTE count);

BOOL TI_receive_packet(BYTE * rxBuffer, UINT8 *length);

void TI_send_packet(BYTE * txBuffer, UINT8 size);

void TI_write_settings();

UINT8 get_random_byte(void);

void Power_up_reset();

#endif /* INC_CC1101_H_ */

/*

* TPMS.h

*

* Created on: Oct 16, 2024

* Author: Cienki

*/

#include"cc1101.h"

SPI_HandleTypeDef* hal_spi3;

uint16_t CS_RF_Pin;

GPIO_TypeDef* CS_RF_GPIO_Port;

#define WRITE_BURST 0x40

#define READ_SINGLE 0x80

#define READ_BURST 0xC0

#define BYTES_IN_RXFIFO 0x7F

#define LQI_STATUS 1

#define CRC_OK 0x80

#define PKTSTATUS_CCA 0x10

#define PKTSTATUS_CS 0x40

#define RANDOM_OFFSET 67

#define RANDOM_MULTIPLIER 109

#define RSSI_VALID_DELAY_US 1300

//static UINT8 rnd_seed = 0;

HAL_StatusTypeDef __spi_write(uint8_t *addr, uint8_t *pData, uint16_t size){

HAL_StatusTypeDef status;

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_RESET); //set Chip Select to Low

while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)); //CS pini LOW yaptığımızd MISO pini adres yazılmadan önce low da beklemeli

status = HAL_SPI_Transmit(hal_spi3, addr, 1, 0xFFFF);

if(status==HAL_OK && pData!=NULL)

status = HAL_SPI_Transmit(hal_spi3, pData, size, 0xFFFF);

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_SET); //set Chip Select to High

return status;

}

HAL_StatusTypeDef __spi_read(uint8_t *addr, uint8_t *pData, uint16_t size){

HAL_StatusTypeDef status;

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_RESET); //set Chip Select to Low

while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)); //CS pini LOW yaptığımızd MISO pini adres yazılmadan önce low da beklemeli

//HAL_StatusTypeDef hal_spi3_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)

status = HAL_SPI_Transmit(hal_spi3, addr, 1, 0xFFFF);

status = HAL_SPI_Receive(hal_spi3, pData, size, 0xFFFF);

while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)); //CS pini LOW yaptığımızd MISO pini adres yazılmadan önce low da beklemeli

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_SET); //set Chip Select to High

return status;

}

void TI_write_reg(UINT8 addr, UINT8 value)

{

__spi_write(&addr, &value, 1);

}

void TI_write_burst_reg(BYTE addr, BYTE* buffer, BYTE count)

{

addr = (addr | WRITE_BURST);

__spi_write(&addr, buffer, count);

}

void TI_strobe(BYTE strobe)

{

__spi_write(&strobe, 0, 0);

}

BYTE TI_read_reg(BYTE addr)

{

uint8_t data;

addr= (addr | READ_SINGLE);

__spi_read(&addr, &data, 1);

return data;

}

BYTE TI_read_status(BYTE addr)

{

uint8_t data;

addr= (addr | READ_BURST);

__spi_read(&addr, &data, 1);

return data;

}

void TI_read_burst_reg(BYTE addr, BYTE* buffer, BYTE count)

{

addr= (addr | READ_BURST);

__spi_read(&addr, buffer, count);

}

BOOL TI_receive_packet(BYTE* rxBuffer, UINT8 *length)

{

volatile BYTE status[2];

UINT8 packet_len;

// This status register is safe to read since it will not be updated after

// the packet has been received (See the CC1100 and 2500 Errata Note)

if (TI_read_status(RXBYTES) & BYTES_IN_RXFIFO)

{

// Read length byte

packet_len = TI_read_reg(CCxxx0_RXFIFO);

// Read data from RX FIFO and store in rxBuffer

if (packet_len <= *length)

{

TI_read_burst_reg(CCxxx0_RXFIFO, rxBuffer, packet_len);

*length = packet_len;

// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)

TI_read_burst_reg(CCxxx0_RXFIFO, status, 2);

//while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0));

//while(!HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0));

// MSB of LQI is the CRC_OK bit

return(status[LQI_STATUS] & CRC_OK);

}

else

{

*length = packet_len;

// Make sure that the radio is in IDLE state before flushing the FIFO

// (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point)

TI_strobe(CCxxx0_SIDLE);

// Flush RX FIFO

TI_strobe(CCxxx0_SFRX);

return(FALSE);

}

}

else return(FALSE);

}

void TI_send_packet(BYTE* txBuffer, UINT8 size)

{

volatile BYTE status;

TI_strobe(CCxxx0_SIDLE); //ïåðåâîäèì ìîäåì â IDLE

TI_write_reg(CCxxx0_TXFIFO, size);

status = TI_read_status(TXBYTES);

TI_write_burst_reg(CCxxx0_TXFIFO, txBuffer, size);

status = TI_read_status(TXBYTES);

TI_strobe(CCxxx0_STX);

}

//For 433MHz, +10dBm

//it is also high

BYTE paTable[] = {0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0};

void TI_write_settings()

{

//i checked in smartRF studio 7 of Mr. ilynx's code // the setting is yours

TI_write_reg(IOCFG2,0x29); //GDO2 Output Pin Configuration

TI_write_reg(IOCFG1,0x2E); //GDO1 Output Pin Configuration

TI_write_reg(IOCFG0,0x06); //GDO0 Output Pin Configuration

TI_write_reg(FIFOTHR,0x47); //RX FIFO and TX FIFO Thresholds

TI_write_reg(SYNC1,0x7A); //Sync Word, High Byte

TI_write_reg(SYNC0,0x0E); //Sync Word, Low Byte

TI_write_reg(PKTLEN,0x14); //Packet Length

TI_write_reg(PKTCTRL1,0x04); //Packet Automation Control

TI_write_reg(PKTCTRL0,0x05); //Packet Automation Control

TI_write_reg(ADDR,0x00); //Device Address

TI_write_reg(CHANNR,0x00); //Channel Number

TI_write_reg(FSCTRL1,0x06); //Frequency Synthesizer Control

TI_write_reg(FSCTRL0,0x00); //Frequency Synthesizer Control

TI_write_reg(FREQ2,0x21); //Frequency Control Word, High Byte

TI_write_reg(FREQ1,0x62); //Frequency Control Word, Middle Byte

TI_write_reg(FREQ0,0x76); //Frequency Control Word, Low Byte

TI_write_reg(MDMCFG4,0xCA); //Modem Configuration

TI_write_reg(MDMCFG3,0xF8); //Modem Configuration

TI_write_reg(MDMCFG2,0x16); //Modem Configuration

TI_write_reg(MDMCFG1,0x22); //Modem Configuration

TI_write_reg(MDMCFG0,0xF8); //Modem Configuration

TI_write_reg(DEVIATN,0x40); //Modem Deviation Setting

TI_write_reg(MCSM2,0x07); //Main Radio Control State Machine Configuration

TI_write_reg(MCSM1,0x30); //Main Radio Control State Machine Configuration

TI_write_reg(MCSM0,0x18); //Main Radio Control State Machine Configuration

TI_write_reg(FOCCFG,0x16); //Frequency Offset Compensation Configuration

TI_write_reg(BSCFG,0x6C); //Bit Synchronization Configuration

TI_write_reg(AGCCTRL2,0x43); //AGC Control

TI_write_reg(AGCCTRL1,0x49); //AGC Control

TI_write_reg(AGCCTRL0,0x91); //AGC Control

TI_write_reg(WOREVT1,0x87); //High Byte Event0 Timeout

TI_write_reg(WOREVT0,0x6B); //Low Byte Event0 Timeout

TI_write_reg(WORCTRL,0xFB); //Wake On Radio Control

TI_write_reg(FREND1,0x56); //Front End RX Configuration

TI_write_reg(FREND0,0x10); //Front End TX Configuration

TI_write_reg(FSCAL3,0xE9); //Frequency Synthesizer Calibration

TI_write_reg(FSCAL2,0x2A); //Frequency Synthesizer Calibration

TI_write_reg(FSCAL1,0x00); //Frequency Synthesizer Calibration

TI_write_reg(FSCAL0,0x1F); //Frequency Synthesizer Calibration

TI_write_reg(RCCTRL1,0x41); //RC Oscillator Configuration

TI_write_reg(RCCTRL0,0x00); //RC Oscillator Configuration

TI_write_reg(FSTEST,0x59); //Frequency Synthesizer Calibration Control

TI_write_reg(PTEST,0x7F); //Production Test

TI_write_reg(AGCTEST,0x3F); //AGC Test

TI_write_reg(TEST2,0x81); //Various Test Settings

TI_write_reg(TEST1,0x35); //Various Test Settings

TI_write_reg(TEST0,0x09); //Various Test Settings

TI_write_reg(PARTNUM,0x00); //Chip ID

TI_write_reg(VERSION,0x04); //Chip ID

TI_write_reg(FREQEST,0x00); //Frequency Offset Estimate from Demodulator

TI_write_reg(LQI,0x00); //Demodulator Estimate for Link Quality

TI_write_reg(RSSI,0x00); //Received Signal Strength Indication

TI_write_reg(MARCSTATE,0x00); //Main Radio Control State Machine State

TI_write_reg(WORTIME1,0x00); //High Byte of WOR Time

TI_write_reg(WORTIME0,0x00); //Low Byte of WOR Time

TI_write_reg(PKTSTATUS,0x00); //Current GDOx Status and Packet Status

TI_write_reg(VCO_VC_DAC,0x00); //Current Setting from PLL Calibration Module

TI_write_reg(TXBYTES,0x00); //Underflow and Number of Bytes

TI_write_reg(RXBYTES,0x00); //Overflow and Number of Bytes

TI_write_reg(RCCTRL1_STATUS,0x00);//Last RC Oscillator Calibration Result

TI_write_reg(RCCTRL0_STATUS,0x00);//Last RC Oscillator Calibration Result

}

void Power_up_reset()

{

//Güç geldikten sonra CC1101 i Macro resetlemek için

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_SET);

HAL_Delay(1);

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_RESET);

HAL_Delay(1);

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_SET);

HAL_Delay(1);

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_RESET);

while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)); //CS pini LOW yaptığımızd MISO pini adres yazılmadan önce low da beklemeli

TI_strobe(CCxxx0_SRES);

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_SET);

}

void TI_init(SPI_HandleTypeDef* hspi, GPIO_TypeDef* cs_port, uint16_t cs_pin)

{

//UINT8 i;

//UINT16 delay;

volatile BYTE status;

hal_spi3 = hspi;

CS_RF_GPIO_Port = cs_port;

CS_RF_Pin = cs_pin;

for(int i=0; i<10; i++){

status = TI_read_status(VERSION);

if(status!=0x14)

{

}

}

TI_strobe(CCxxx0_SFRX); //î÷èùàåì RX FIFO

TI_strobe(CCxxx0_SFTX); //î÷èùàåì TX FIFO

TI_write_settings();

TI_write_burst_reg(CCxxx0_PATABLE, paTable, 8);//is it true

TI_write_reg(FIFOTHR, 0x07);

TI_strobe(CCxxx0_SIDLE); //ïåðåâîäèì ìîäåì â IDLE

TI_strobe(CCxxx0_SFRX); //î÷èùàåì RX FIFO

TI_strobe(CCxxx0_SFTX); //î÷èùàåì TX FIFO

//TI_strobe(CCxxx0_SRX);

/*delay = RSSI_VALID_DELAY_US;

do

{

status = TI_read_status(CCxxx0_PKTSTATUS) & (PKTSTATUS_CCA | PKTSTATUS_CS);

if (status)

{

break;

}

ACC = 16;

while(--ACC);

delay -= 64;

} while(delay > 0);

for(i = 0; i < 16; i++)

{

rnd_seed = (rnd_seed << 1) | (TI_read_status(CCxxx0_RSSI) & 0x01);

}

rnd_seed |= 0x0080;*/

TI_strobe(CCxxx0_SIDLE);

}

/* USER CODE BEGIN Header */

/**

******************************************************************************

* @file : main.c

* @brief : Main program body

******************************************************************************

* @attention

*

* Copyright (c) 2024 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"

/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */

#include "fonts.h"

#include "ssd1306.h"

#include "stdio.h"

#include "TPMS.h"

#include "cc1101.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/

/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/

/* USER CODE BEGIN PD */

#define CC1101_WRITE_BURST 0x40

#define CC1101_READ_SINGLE 0x80

#define CC1101_READ_BURST 0xC0

#define CC1101_SRES 0x30 // Reset

#define CC1101_PATABLE 0x3E

#define CC1101_TXFIFO 0x3F

#define CC1101_RXFIFO 0x3F

#define state 0

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/

/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

I2C_HandleTypeDef hi2c1;

SPI_HandleTypeDef hspi3;

/* USER CODE BEGIN PV */

volatile uint8_t GDO0_FLAG;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_I2C1_Init(void);

static void MX_SPI3_Init(void);

/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/

/* USER CODE BEGIN 0 */

//rfstop=gdo

/* USER CODE END 0 */

/**

* @brief The application entry point.

* @retval int

*/

int main(void)

{

/* USER CODE BEGIN 1 */

const unsigned char bitmap[] = {

0xff, 0xff, 0xff, 0xff, 0x80, 0x40, 0x00, 0x01, 0x80, 0x40, 0x00, 0x19,

0x80, 0x40, 0x00, 0x3d, 0x80, 0x40, 0x00, 0x3d, 0x80, 0x40, 0x00, 0x01,

0x80, 0x40, 0x00, 0x01, 0x81, 0xff, 0x03, 0xff, 0x81, 0xff, 0x03, 0x81,

0x81, 0xff, 0x03, 0x81, 0x81, 0xff, 0x03, 0x81, 0x81, 0xff, 0x03, 0x81,

0x81, 0xff, 0x03, 0x81, 0x80, 0x0f, 0x03, 0x81, 0x80, 0x0f, 0x03, 0x81,

0x80, 0x0f, 0x03, 0x81, 0x80, 0x0f, 0x03, 0x81, 0x80, 0x0f, 0x03, 0x81,

0x80, 0x0f, 0x03, 0x81, 0x81, 0xff, 0x03, 0x81, 0x81, 0xff, 0x03, 0x81,

0x81, 0xff, 0x03, 0x81, 0x81, 0xff, 0x03, 0x81, 0x81, 0xff, 0x03, 0x81,

0x81, 0xff, 0x03, 0x81, 0x80, 0x03, 0x03, 0x81, 0x80, 0x01, 0x03, 0x81,

0x80, 0x01, 0x03, 0x81, 0x80, 0x01, 0x03, 0x81, 0x80, 0x01, 0x03, 0x81,

0x80, 0x01, 0x03, 0x81, 0xff, 0xff, 0xff, 0xff

};

int16_t x = 32;

int16_t y = 32;

uint16_t color = 1;

//uint8_t dataTx[]= "0"; //zmienna przechowująca nadane dane z modułu rf

uint8_t dataRx[200]={0};// zmienna przechowująca odebrane dane z modułu rf

char displayBuffer[64]; // Bufor na sformatowany tekst do wyświetlenia

//uint8_t dataTx[2]={0};

/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */

SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_I2C1_Init();

MX_SPI3_Init();

/* USER CODE BEGIN 2 */

SSD1306_Init();

volatile BYTE status;

Power_up_reset();

TI_init(&hspi3, CS_RF_GPIO_Port, CS_RF_Pin);

//CC1101_Init(CS_RF_Pin);

//CC1101_Strobe(CC1101_SRX,CS_RF_Pin);

//CC1101_Strobe(CC1101_SIDLE,CS_RF_Pin);

// CC1101_Strobe(CC1101_SRES,CS_RF_Pin);

//CC1101_Strobe(CC1101_SRX,CS_RF_Pin);

#if state

//for transiver

BYTE veri = 7;

char packet[] = "RF Test";

while (1)

{

status = TI_read_status(VERSION); // it is for checking only //sadece kontrol için

//it must be 0x14 //0x14 değeri vermelidir

status = TI_read_status(TXBYTES); // it is too // bu da kontrol için

TI_strobe(CCxxx0_SFTX); // flush the buffer //bufferi temizler

UserLEDShow(); // turn on the led before send the data // veri göndermeden önce ledi yakar

TI_send_packet(packet, sizeof(packet)); //the function is sending the data

while(HAL_GPIO_ReadPin(GDO0_GPIO_Port, GDO0_Pin));

while(!HAL_GPIO_ReadPin(GDO0_GPIO_Port, GDO0_Pin));

//if the pass to this function, the data was sent. // veri gönderme işlemi tamamlanması için bekletir

status = TI_read_status(TXBYTES); // it is checking to send the data //veri gönderildiğini kontrol etmek için

UserLEDHide(); // turn off the led // veri gönderildiğinde led söner

HAL_Delay(100);

}

#else

//for receiver/modem

char buffer[64];

char mesaj[7];

char kontrol[7] = {'R', 'F', ' ', 'T', 'e', 's', 't' };

uint8_t value = 0;

volatile BYTE length;

TI_write_reg(IOCFG0, 0x06);

//interrupt setting on GDO0 for data receiving with FIFO

// GDO0 pininde FIFO ile kullanmak için interrupt ayarı

/* EXTI interrupt init*/

__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);

HAL_NVIC_EnableIRQ(EXTI0_IRQn);

while(1)

{

//BYTE status;

volatile BYTE LQI_stat;

__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);

GDO0_FLAG = 0;

TI_strobe(CCxxx0_SFRX);// Flush the buffer //Bufferi temizle

TI_strobe(CCxxx0_SRX); // Set RX Mode //RX moda ayarlar

// while(GDO0_FLAG == 0);

//when the data came, it passes this fucntion

//veri geldiğinde bu adımı geçer

status = TI_read_status(RXBYTES);

//it is for checking

// gelen datanın olup olmadığını denetler

if (!(status & 0x7f)) continue;

// if it get the data, the code can contuniue

// data gelirse, kod devam eder

LQI_stat = TI_read_status(LQI);

// LQI is quaility of the receiving data

// LQI gelen veri kalitesi

if (LQI_stat & 0x80 /*CRC_OK*/)

{

status = TI_receive_packet(buffer, &length);//read function //okuma fonksiyonu

for(uint8_t i = 0; i <7; i++)//to check for receiving data // gelen datayı kontrol etmek için

{

mesaj[i] = buffer[i];

if(strcmp(mesaj[i], kontrol[i])!=0)

{

value = 1;

break;

}

}

//to send over uart on serial port with 9600baudrate

// Gelen datayı uart üzerinden 9600 baudrate ile seri porta gönderir

if (value == 0)

// if receiving data is equal to checking data, the led is blink

// eğer gelen data kontrol datasına eşitse, led yanıp söner

{

//snprintf(displayBuffer, sizeof(displayBuffer), "%s[BAR]", mesaj);

SSD1306_DrawBitmap(95, 32, bitmap, x, y, color);

SSD1306_GotoXY(96, 9);

SSD1306_Puts("TPMS", &Font_7x10, 1);

SSD1306_GotoXY(0, 9);

SSD1306_Puts("PRESSURE:", &Font_7x10, 1);

SSD1306_GotoXY(0, 35);

SSD1306_Puts("git", &Font_11x18, 1);

SSD1306_UpdateScreen();

HAL_Delay(1000);

}

else{

SSD1306_DrawBitmap(95, 32, bitmap, x, y, color);

SSD1306_GotoXY(96, 9);

SSD1306_Puts("TPMS", &Font_7x10, 1);

SSD1306_GotoXY(0, 9);

SSD1306_Puts("PRESSURE:", &Font_7x10, 1);

SSD1306_GotoXY(0, 35);

SSD1306_Puts("ZLE", &Font_11x18, 1);

SSD1306_UpdateScreen();

HAL_Delay(1000);

}

}

else

{

status = TI_read_status(PKTSTATUS); // if it isnt, check pktstatus // değilse, paket durumunu kontrol eder

SSD1306_DrawBitmap(95, 32, bitmap, x, y, color);

SSD1306_GotoXY(96, 9);

SSD1306_Puts("TPMS", &Font_7x10, 1);

SSD1306_GotoXY(0, 9);

SSD1306_Puts("PRESSURE:", &Font_7x10, 1);

SSD1306_GotoXY(0, 35);

SSD1306_Puts("ERROR", &Font_11x18, 1);

SSD1306_UpdateScreen();

HAL_Delay(1000);

GDO0_FLAG = 0;

}

}

#endif

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

CC1101_ReceiveData(&dataRx, sizeof(dataRx),CS_RF_Pin);

snprintf(displayBuffer, sizeof(displayBuffer), "%d[BAR]", dataRx[0]);

SSD1306_DrawBitmap(95, 32, bitmap, x, y, color);

SSD1306_GotoXY(96, 9);

SSD1306_Puts("TPMS", &Font_7x10, 1);

SSD1306_GotoXY(0, 9);

SSD1306_Puts("PRESSURE:", &Font_7x10, 1);

SSD1306_GotoXY(0, 35);

SSD1306_Puts(displayBuffer, &Font_11x18, 1);

SSD1306_UpdateScreen();

//HAL_Delay(1000); // opóźnienie

// Czyszczenie bufora

memset(dataRx, 0, sizeof(dataRx));

// Powrót do trybu odbioru

//CC1101_Strobe(CC1101_SRX,CS_RF_Pin);

//HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin,GPIO_PIN_SET );

// dataTx[1] = (0x3D );

// dataTx[0] = (0x3D | 0x00);

// CC1101_Strobe(dataTx[0],CS_RF_Pin);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

/**

* @brief System Clock Configuration

* @retval None

*/

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Configure the main internal regulator output voltage

*/

__HAL_RCC_PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

/** Initializes the RCC Oscillators according to the specified parameters

* in the RCC_OscInitTypeDef structure.

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

/** Initializes the CPU, AHB and APB buses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

{

Error_Handler();

}

}

/**

* @brief I2C1 Initialization Function

* @param None

* @retval None

*/

static void MX_I2C1_Init(void)

{

/* USER CODE BEGIN I2C1_Init 0 */

/* USER CODE END I2C1_Init 0 */

/* USER CODE BEGIN I2C1_Init 1 */

/* USER CODE END I2C1_Init 1 */

hi2c1.Instance = I2C1;

hi2c1.Init.ClockSpeed = 400000;

hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;

hi2c1.Init.OwnAddress1 = 0;

hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c1.Init.OwnAddress2 = 0;

hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

if (HAL_I2C_Init(&hi2c1) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN I2C1_Init 2 */

/* USER CODE END I2C1_Init 2 */

}

/**

* @brief SPI3 Initialization Function

* @param None

* @retval None

*/

static void MX_SPI3_Init(void)

{

/* USER CODE BEGIN SPI3_Init 0 */

/* USER CODE END SPI3_Init 0 */

/* USER CODE BEGIN SPI3_Init 1 */

/* USER CODE END SPI3_Init 1 */

/* SPI3 parameter configuration*/

hspi3.Instance = SPI3;

hspi3.Init.Mode = SPI_MODE_MASTER;

hspi3.Init.Direction = SPI_DIRECTION_2LINES;

hspi3.Init.DataSize = SPI_DATASIZE_8BIT;

hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;

hspi3.Init.NSS = SPI_NSS_SOFT;

hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;

hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi3.Init.TIMode = SPI_TIMODE_DISABLE;

hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi3.Init.CRCPolynomial = 7;

if (HAL_SPI_Init(&hspi3) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN SPI3_Init 2 */

/* USER CODE END SPI3_Init 2 */

}

/**

* @brief GPIO Initialization Function

* @param None

* @retval None

*/

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(CS_RF_GPIO_Port, CS_RF_Pin, GPIO_PIN_RESET);

/*Configure GPIO pin : PC13 */

GPIO_InitStruct.Pin = GPIO_PIN_13;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pin : CS_RF_Pin */

GPIO_InitStruct.Pin = CS_RF_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(CS_RF_GPIO_Port, &GPIO_InitStruct);

#if state

//for transiver

/*Configure GPIO pin : GDO0_Pin */

GPIO_InitStruct.Pin = GDO0_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GDO0_GPIO_Port, &GPIO_InitStruct);

#else

//for receiver/modem

/*Configure GPIO pin : GDO0_Pin */

GPIO_InitStruct.Pin = GDO0_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GDO0_GPIO_Port, &GPIO_InitStruct);

#endif

/*Configure GPIO pin : START_RF_Pin */

GPIO_InitStruct.Pin = START_RF_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(START_RF_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}

/* USER CODE BEGIN 4 */

#if state == 0

//for receiver/modem

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

//if it get the receiving data, the interrupt works

// eğer gelen data gelirse, kesme çalışır.

if(GPIO_Pin == GDO0_Pin){

GDO0_FLAG = 1;

}

}

#endif

/* USER CODE END 4 */

/**

* @brief This function is executed in case of error occurrence.

* @retval None

*/

void Error_Handler(void)

{

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

__disable_irq();

while (1)

{

}

/* USER CODE END Error_Handler_Debug */

}

#ifdef USE_FULL_ASSERT

/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t *file, uint32_t line)

{

/* USER CODE BEGIN 6 */

/* User can add his own implementation to report the file name and line number,

ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* USER CODE END 6 */

}

#endif /* USE_FULL_ASSERT */

  • It is not possible for me to say why you are not receiving anything as I do not know anything abouth what HW you are using (custom HW or a CC1101 EM), what MCU you are writing your code for etc.

    How do you even know that the problem is on the receiver and not the transmitter? Do you knpw that you are sending a correct packet?

    The first thing you should do is to test TX and RX with settings from SmartRF Studio (use default settings without changes and get this to work before starting to change them).

    I selected the following:

    // Sync word qualifier mode = 30/32 sync word bits detected
    // CRC autoflush = false
    // Channel spacing = 199.951172
    // Data format = Normal mode
    // Data rate = 4.79794
    // RX filter BW = 101.562500
    // PA ramping = false
    // Preamble count = 4
    // Whitening = false
    // Address config = No address check
    // Carrier frequency = 867.999939
    // Device address = 0
    // TX power = 0
    // Manchester enable = false
    // CRC enable = true
    // Deviation = 25.390625
    // Packet length mode = Variable
    // Packet length = 255
    // Modulation format = GFSK
    // Base frequency = 867.999939
    // Modulated = true
    // Channel number = 0
    // PA table
    #define PA_TABLE {0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}
    
    static const registerSetting_t preferredSettings[]= {
        {CC1101_IOCFG2,     0x06},
        {CC1101_IOCFG0,     0x06},
        {CC1101_FIFOTHR,    0x47},
        {CC1101_PKTCTRL0,   0x05},
        {CC1101_FSCTRL1,    0x08},
        {CC1101_FREQ2,      0x21},
        {CC1101_FREQ1,      0x62},
        {CC1101_FREQ0,      0x76},
        {CC1101_MDMCFG4,    0xC7},
        {CC1101_MDMCFG3,    0x83},
        {CC1101_MDMCFG2,    0x93},
        {CC1101_DEVIATN,    0x40},
        {CC1101_MCSM0,      0x18},
        {CC1101_FOCCFG,     0x16},
        {CC1101_AGCCTRL2,   0x43},
        {CC1101_WORCTRL,    0xFB},
        {CC1101_FSCAL3,     0xE9},
        {CC1101_FSCAL2,     0x2A},
        {CC1101_FSCAL1,     0x00},
        {CC1101_FSCAL0,     0x1F},
        {CC1101_TEST2,      0x81},
        {CC1101_TEST1,      0x35},
        {CC1101_TEST0,      0x09},
    };
    

    The only thing your code should do on the TX side, to for example send a packet with payload 0x05, 0x01, 0x02, 0x03, 0x04, 0x05 is the following:

    • Strobe SRES
    • Write the data above to the radio, including the PATABLE
    • Write the packet to the TX FIFO (5, 1, 2, 3, 4, 5)
    • Strobe STX

    Use a logic analyser to verify that all of the above is done correctly:

    On the RX side, you need to do the following:

    • Strobe SRES
    • Write the config registers to the radio (same as you used for TX)
    • Strobe SRX
    • Wait for GDO0 to get high and then low

    If your TX and RX uses the same settings and you have verified your SPI communication, and you still do not receive anything, this indicates that there are issues with your HW. 

    This could be issues that are affecting the RF performance, if you have not followed out ref. Design for example, or there could simply be problems with reading the GDO0 pin from your MCU.

    Siri