cancel
Showing results for 
Search instead for 
Did you mean: 

STEVAL-25R200SA Transparent Mode Implementation

SamuelMpol
Associate II

I'm working with the STEVAL-25R200SAand trying to implement Transparent Mode to directly receive raw data from the MISO line. I've followed the datasheet and configured everything as per the documentation, but I'm still not receiving any data.

Setup and Code Implementations:

In my main() function, the while loop calls these functions repeatedly:

while (1) {
    serCycle();
    enterTransparencyMode();
    readTransparentMode();
    HAL_Delay(1000);
}

I start by calling enterTransparencyMode() which ensures the transmitter and receiver are enabled, configures the AFE, sends the command to enter Transparent Mode, and raises the BSS (CS) line to keep it high as required by the datasheet:

void enterTransparencyMode(void) {
    printf("Setting up device for transparency mode\r\n");

    // Read initial state
    uint8_t regValue, statusReg;
    st25r200ReadRegister(ST25R200_OPERATION_REGISTER, &regValue);
    st25r200ReadRegister(ST25R200_STATUS_REGISTER, &statusReg);
    printf("Initial state - Operation: 0x%02X, Status: 0x%02X (RX %s, TX %s)\r\n", 
           regValue, statusReg,
           (statusReg & (1 << 2)) ? "ON" : "OFF",
           (statusReg & (1 << 1)) ? "ON" : "OFF");

    // Configure RX and measure initial field
    configureRX();
    
    // Measure field strength
    uint8_t fieldStrength;
    ReturnCode ret = rfalChipMeasureCombinedIQ(&fieldStrength);
    if (ret == RFAL_ERR_NONE) {
        printf("Initial field strength: 0x%02X\r\n", fieldStrength);
    }

    // Set CS Low to send command to enter transparent mode
    HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);

    // Enter transparent mode using st25r200ExecuteCommandAndGetResult
    uint8_t result;
    ret = st25r200ExecuteCommandAndGetResult(ST25R200_CMD_TRANSPARENT_MODE, 
                                           0, 
                                           ST25R200_TOUT_MEASUREMENT,  // 2ms timeout
                                           &result);
    if (ret != RFAL_ERR_NONE) {
        printf("Failed to enter transparent mode: %d\r\n", ret);
        return;
    }

    // Set CS HIGH to maintain transparent mode
    HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);
    
    printf("Entered transparent mode\r\n");
}

This function calls configureRX() to set up RX, TX modulation, and protocol transmission registers, enabling the en bit and setting dis_cor as required for Transparent Mode:

void configureRX(void) {
    uint8_t operationValue, rxDigitalValue, txModulationValue, protocolTxReg;

    // Configure Operation Register
    st25r200ReadRegister(ST25R200_OPERATION_REGISTER, &operationValue);
    operationValue |= (1 << 5);  // Enable TX
    operationValue |= (1 << 4);  // Enable RX
    operationValue |= (1 << 3);  // Enable AM
    operationValue |= (1 << 1);  // Enable ready mode (en bit)
    st25r200WriteRegister(ST25R200_OPERATION_REGISTER, operationValue);
    printf("Operation Register configured: 0x%02X\r\n", operationValue);

    // Configure RX Digital Register for better sensitivity
    st25r200ReadRegister(ST25R200_RX_DIGITAL_REGISTER, &rxDigitalValue);
    rxDigitalValue |= (1 << 7);  // Enable AGC for more stable readings
    rxDigitalValue &= ~(1 << 0);  // Enable correlation
    st25r200WriteRegister(ST25R200_RX_DIGITAL_REGISTER, rxDigitalValue);
    printf("RX Digital Register configured: 0x%02X\r\n", rxDigitalValue);

    // Configure TX Modulation for maximum amplitude
    st25r200ReadRegister(ST25R200_TX_MODULATION_REGISTER, &txModulationValue);
    txModulationValue |= (0xF << 4);  // Set TX amplitude to max
    txModulationValue |= (1 << 3);    // Enable modulation
    st25r200WriteRegister(ST25R200_TX_MODULATION_REGISTER, txModulationValue);
    printf("TX Modulation Register configured: 0x%02X\r\n", txModulationValue);

    // Set Modulation Type to AM (OOK Alternative)
    st25r200ReadRegister(ST25R200_PROTOCOL_TRANSMISSION_REGISTER, &protocolTxReg);  // Read Protocol Transmission Register 1
    protocolTxReg |= (1 << 4);  // Set `tr_am` to 1 (AM Modulation)
    st25r200WriteRegister(ST25R200_PROTOCOL_TRANSMISSION_REGISTER, protocolTxReg);
    printf("Protocol TX Register 1 set to AM Mode: 0x%02X\r\n", protocolTxReg);

    // Verify RX is enabled
    uint8_t statusValue;
    st25r200ReadRegister(ST25R200_STATUS_REGISTER, &statusValue);
    printf("Status Register: 0x%02X (RX %s)\r\n", statusValue, 
           (statusValue & (1 << 2)) ? "ON" : "OFF");
}

Approach 1: Using SPI Functions

I initially used HAL_SPI_TransmitReceive() with 0xFF to transmit a continuous pattern on MOSI and simultaneously receive data from MISO, ensuring that the SCLK line was toggled correctly by the SPI peripheral during the transfer:

void readTransparentMode(void) {
    printf("\nStarting transparent mode monitoring...\r\n");
    
    uint8_t rxBuffer[10];
    uint8_t txBuffer[10];
    memset(rxBuffer, 0, sizeof(rxBuffer));
    memset(txBuffer, 0xAA, sizeof(txBuffer));

    // Ensure CS stays HIGH for transparent mode
    HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);
    
    // First transmit
    HAL_StatusTypeDef status = HAL_SPI_Transmit(&hspi1, txBuffer, sizeof(txBuffer), HAL_MAX_DELAY);
    if (status != HAL_OK) {
        printf("SPI transmit failed with status: %d\r\n", status);
        return;
    }

    // Then receive 
    status = HAL_SPI_Receive(&hspi1, rxBuffer, sizeof(rxBuffer), HAL_MAX_DELAY);
    if (status != HAL_OK) {
        printf("SPI receive failed with status: %d\r\n", status);
        return;
    }

    // Process received data
    uint32_t nonZeroCount = 0;
    printf("Received values:\r\n");
    for (int i = 0; i < sizeof(rxBuffer); i++) {
        printf("Sample %d: 0x%02X\r\n", i, rxBuffer[i]);
        if (rxBuffer[i] != 0) {
            nonZeroCount++;
        }
    }

    printf("Monitoring complete. Non-zero samples: %lu\r\n", nonZeroCount);
}

No data was received, all values were 0x00. A possible reason for this is that the timing requirements for Transparent Mode might not be met, particularly with the SCLK line toggling when using the SPI function, potentially causing no data to be read from the MISO line.

Approach 2: GPIO Pin Configuration

I disabled SPI and manually toggled SCK, MOSI, CS, and IRQ using GPIO functions, manually driving the SCK line high and low, setting MOSI, and reading MISO while ensuring the IRQ line was also monitored when the dis_cor was set to 1. All lines are now configured as GPIO pins to allow manual toggling and monitoring:

void readTransparentMode(void) {
    printf("\nStarting transparent mode monitoring...\r\n");
    
    // Disable SPI1
    __HAL_RCC_SPI1_CLK_DISABLE();
    
    // Configure pins as GPIO
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    // Configure SCK (PA5) and MOSI (PA7) as outputs
    GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    // Configure MISO (PA6) as input
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    // Set initial pin states
    HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);     // CS high
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);                 // SCK low
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);                  // MOSI high

    // Read data
    uint8_t rxBuffer[10] = {0};
    for(int byte = 0; byte < sizeof(rxBuffer); byte++) {
        for(int bit = 7; bit >= 0; bit--) {
            // Toggle clock high
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
            
            // Read MISO
            if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == GPIO_PIN_SET) {
                rxBuffer[byte] |= (1 << bit);
            }
            
            // Toggle clock low
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
        }
    }

    // Process received data
    uint32_t nonZeroCount = 0;
    printf("Received values:\r\n");
    for (int i = 0; i < sizeof(rxBuffer); i++) {
        printf("Sample %d: 0x%02X\r\n", i, rxBuffer[i]);
        if (rxBuffer[i] != 0) {
            nonZeroCount++;
        }
    }

    printf("Monitoring complete. Non-zero samples: %lu\r\n", nonZeroCount);

    // Reconfigure pins back to SPI mode
    GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // Re-enable SPI1
    __HAL_RCC_SPI1_CLK_ENABLE();
    MX_SPI1_Init();
}

Despite this, MISO remains low.

Results Observed:

The results I keep getting are all zeros. Below is a snippet of the Putty logs showing repeated attempts:

Setting up device for transparency mode
Initial state - Operation: 0x3A, Status: 0x00 (RX OFF, TX OFF)
Operation Register configured: 0x3A
RX Digital Register configured: 0xCC
TX Modulation Register configured: 0xF9
Protocol TX Register 1 set to AM Mode: 0x70
Status Register: 0x00 (RX OFF)
Initial field strength: 0x05
Entered transparent mode

Starting transparent mode monitoring...
Received values:
Sample 0: 0x00
....
Sample 9: 0x00
Monitoring complete. Non-zero samples: 0

Has anyone successfully implemented Transparent Mode with the ST25R200? Are there specific timing requirements or additional register configurations I may have missed? Any help is appreciated!

Additionally, @Ulysses HERNIOSUS if there are any details regarding Transparent Mode operation that are confidential, could ST provide this information under an NDA? This would greatly help in understanding and troubleshooting the issue.



5 REPLIES 5
Ulysses HERNIOSUS
ST Employee

Hi SamuelMpol,

it sounds like you rather want to use the transparent mode with disabled correlator (dis_corr=1). Otherwise you will only get information about a given subcarrier signal being present.

Additionally for debugging: Also look using a sniff coil to see if field actually has your expected modulation.

BR, Ulysses

Ulysses HERNIOSUS
ST Employee

Hi,

what are you actually trying to achieve with transparent mode?

Inside the community you can find some information which can help deepening your understanding of transparent mode. In your code I see toggling of the SCLK pin which IMO does not make really sense. E.g. this post questions-about-configurations-of-st25r3916-for-transparent-mode has some explanation for transparent mode. Even if for ST25R3916B, the concept is the same for ST25R200.

BR, Ulysses

 

I am trying to use Transparent Mode to capture received signal variations is amplitude when I move a tag around the antenna. My goal is to:

  1. Transmit a signal with no modulation (keeping the MOSI line high and not toggling it).
  2. Capture the envelope of the received signal on a pin such as MISO, so that the signal level changes as I move a tag closer or farther from the antenna.
  3. Alternatively, bypass all internal processing and directly receive the raw received signals on an output pin, which I can later process in software to extract the amplitude information.

Concerns with Transparent Mode Behavior

1. When dis_corr = 0 (Correlator Data Output, Sum of I+Q)

  • The MISO and IRQ signals remain mostly stable, showing little to no variation when moving a tag around the antenna.
  • The datasheet states that in this mode, MISO outputs the sum of I+Q. My expectation was that this would provide a signal reflecting the received RF field strength, but this is not the case.
  • When I probe the RFI pin with an oscilloscope, I see a clear amplitude variation as I move the tag. However, this effect is not present on MISO.
  • Question: Could this behavior be due to incorrect Correlator Register settings? Should I be adjusting specific registers (e.g., correlator thresholds, AGC settings, or gain levels) to properly extract the received signal?

2. When dis_corr = 1 (Digitized Subcarrier Signal Output)

  • I observe a digital signal (highs and lows) on MISO and IRQ.
  • However, these signals only change when I toggle MOSI, meaning they are influenced by transmitter modulation rather than passive tag movement.
  • This suggests that in dis_corr = 1** mode**, the MISO and IRQ outputs are more related to detecting a modulated subcarrier rather than providing continuous envelope detection.
  • Question: Is this digitized subcarrier meant to be read through SPI, or is it expected to be processed differently?

Main Question:

  • Can Transparent Mode be used to achieve what I want (i.e., obtaining the envelope of the received RF signal or bypassing processing to extract amplitude variations)?
  • If so, what register configurations should I adjust to achieve this?
  • If not, is there another way to obtain the raw RF amplitude data from the ST25R200?

Hi,

I think what you are trying to achieve is not possible.

Correlated signal will correlate the signal to a subcarrier - e.g. 848kHz.

Digitized subcarrier signal out is expected to remove the baseband and leave only signals expected for certain subcarrier frequencies. Your experiment of physically moving the tag is really low frequency. Thie transparent mode is not meant to produce an envelope signal.

What are you trying to achieve with an envelope signal?

Regards, Ulysses

Oh okay, I just need to be able to get the amplitude of the received signal so that is why I am asking about the envelope.