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.