No se puede lograr que SPI funcione en STM32 Cortex-M3 (píldora azul) con CMSIS

0

Estoy intentando conectarme a un módulo RFM95W utilizando la píldora azul Cortex-M3 de ST.

Soy un principiante integrado pero conozco Linux, así que utilicé el siguiente código en un Rpi3 para conectarme al chip y leí la versión del registro REG_VERSION en la dirección 0x42 y pude obtener el valor correcto de 0x12 .

int main()
{
    ...
    wiringPiSetup();
    pinMode(rfmodule->pin_rst, OUTPUT);
    wiringPiSPISetup(SPI_CHANNEL, SPI_RATE);
    digitalWrite(rfmodule->pin_rst, LOW);
    delay(100);
    digitalWrite(rfmodule->pin_rst, HIGH);
    delay(100);
    uint8_t version = read_register(REG_VERSION);
}

uint8_t
read_register(uint8_t addr)
{
    uint8_t spibuf[2];
    spibuf[0] = addr & 0x7F;
    spibuf[1] = 0x00;

    wiringPiSPIDataRW(SPI_CHANNEL, spibuf, 2);

    return spibuf[1];
}

He estado trabajando para portar este código para trabajar en la píldora azul leyendo el manual de referencia (rm0008), usando CMSIS para iniciar SPI1 y esto tutorial en línea . Mi código es

#include "stm32f10x.h"
#include "stm32f10x_spi.h"

#define SYS_CLOCK_HZ 9000000U
#define REG_VERSION  0x42

void dummy(unsigned int i);

void dummy(unsigned int i)
{
    while (i > 0)
    {
        i--;
    }
}

void blink(void)
{
    if ( (GPIOC->ODR & (1U << 13)) == 0U )
    {
        // turn on
        GPIOC->ODR |= (1U << 13);
    }
    else 
    {
        // turn off
        GPIOC->ODR &= ~(1U << 13);
    }
    dummy(1000000U);

}

int main ( void )
{

    SPI_InitTypeDef SPI_InitStruct;

    SPI_StructInit(&SPI_InitStruct);

    // enable ports A and C and SPI1
    RCC->APB2ENR |= (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_SPI1EN);

    //config PC13 as digital output
    GPIOC->CRH &= ~(GPIO_CRH_MODE13);   //PC13
    GPIOC->CRH |= GPIO_CRH_MODE13_0;      //PC13

    // SCK/PA5  -- Alternate function push-pull    CNF 10  -- MODE 11
    // MOSI/PA7 -- Alternate function push-pull    CNF 10  -- MODE 11
    // MISO/PA6 -- Input floating / Input pull-up  CNF 01  -- MODE 00
    // NSS/PA3  -- Alternate function push-pull    CNF 10  -- MODE 11

    // RST/PA4 -- Output mode, max speed 10 MHz    CNF 01  -- MODE 00

    // leave MISO in RESET STATE

    // set CNF 10 for A4, A5, and A7
    GPIOA->CRL |= (GPIO_CRL_MODE4 | GPIO_CRL_MODE5| GPIO_CRL_MODE7);

    // set MODE 11 for A4, A5, and A7
    GPIOA->CRL |= (GPIO_CRL_CNF5_0 | GPIO_CRL_CNF7_0 | GPIO_CRL_CNF6_1 | GPIO_CRL_CNF4_0);

    // reset pin is generic output pin
    GPIOA->CRL |= ~(GPIO_CRL_MODE3);

    GPIOA->CRL |= GPIO_CRL_CNF3_1;

    // disable slave by setting NSS to high
    GPIOA->ODR |= (1U << 4U);

    /*

    In input mode (MODE[1:0]=00):
    00: Analog mode
    01: Floating input (reset state)
    10: Input with pull-up / pull-down
    11: Reserved
    In output mode (MODE[1:0] > 00):
    00: General purpose output push-pull
    01: General purpose output Open-drain
    10: Alternate function output Push-pull
    11: Alternate function output Open-drain

    */


    SPI_Init(SPI1, &SPI_InitStruct);

    SPI_Cmd(SPI1, ENABLE);

    while(1){

        // enable slave by setting NSS low
        GPIOA->ODR |= (0U << 4U); 
        dummy(500);
        // reset radio with PA3
        GPIOA->ODR |= (0U << 3U);
        dummy(500);
        GPIOA->ODR |= (1U << 3U);
        dummy(500);

        // Write data to be transmitted to the SPI data register
        SPI1->DR = REG_VERSION & 0x7F;
        // // Wait until transmit complete
        while (!(SPI1->SR & (SPI_I2S_FLAG_TXE)));
        // Wait until receive complete
        while (!(SPI1->SR & (SPI_I2S_FLAG_RXNE)));
        // Wait until SPI is not busy anymore
        while (SPI1->SR & (SPI_I2S_FLAG_BSY));

        uint32_t tmp = SPI1->DR;

        // disable slave by setting NSS to high
        GPIOA->ODR |= (1U << 4U);

        blink();
    }

    return(0);
}

Pasando con gdb en Sublime llego hasta la variable temp, así que sé que SPI_I2S_FLAG_TXE y SPI_I2S_FLAG_RXNE están configurados. Sin embargo, el valor 0 está en el registro DR y no en el 0x12 esperado.

Vuelvo a revisar el cableado y ahora estoy mirando a la comunidad para ver si alguien puede detectar un problema en el código que simplemente no veo.

    
pregunta Sam Hammamy

1 respuesta

0

Siguiendo el consejo de Chris Stratton, encontré un ejemplo de trabajo que pude para seguir en combinación con Arduino Uno y luego lo ajusté para que funcione para el HopeRF95W.

Sin embargo, hay otro problema con el read_register que planeo publicar en una nueva pregunta.

    
respondido por el Sam Hammamy

Lea otras preguntas en las etiquetas