cancel
Showing results for 
Search instead for 
Did you mean: 

STEVAL-25R200SA Transparent Mode Implementation

SamuelMpol
Visitor

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.



0 REPLIES 0