Estoy usando un STM32F103C8 para conectarme a un IC de transceptor Hope RF95W con el fin de aprender.
Solo intento leer el registro de la versión del chip, luego escribir un registro de configuración que tenga un valor de restablecimiento de 0x00 y luego leerlo para asegurarme de que mi código de escritura funciona.
La hoja de datos RF95W dice acerca de la transferencia de SPI:
Acceso SENCILLO: se envía un byte de dirección seguido de un byte de datos para un acceso de escritura, mientras que se envía un byte de dirección y un byte de lectura es recibido por el acceso de lectura. El pin NSS baja al comienzo de el marco y se eleva después del byte de datos.
MOSI es generado por el maestro en el borde descendente de SCK y es muestreado por el esclavo (es decir, esta interfaz SPI) en el borde ascendente de SCK. MISO es generado por el esclavo en el borde descendente de SCK.
Una transferencia siempre se inicia cuando el pin NSS baja. MISO es alto Impedancia cuando NSS es alta. El primer byte es el byte de dirección. Es comprende:
Un wnr bit, que es 1 para acceso de escritura y 0 para lectura acceso.
Luego 7 bits de dirección, primero MSB.
Para mí, esto significa que leer un registro requiere solo una transferencia. Enviando la dirección del registro, luego esperando el indicador SPI_I2S_FLAG_RXNE
, el valor de este registro estará en el registro de datos SPI.
Sin embargo, lo que sucede es que necesito dos secuencias de estas operaciones de escritura / marca / lectura para obtener el valor:
uint8_t read_register(uint8_t address){
uint8_t data;
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // slave select (low)
delay_ms(100);
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));
SPI_I2S_SendData(SPI1, address); // send
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));
data = SPI_I2S_ReceiveData(SPI1); // read received
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));
SPI_I2S_SendData(SPI1, address); // send
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));
data = SPI_I2S_ReceiveData(SPI1); // read received
GPIO_SetBits(GPIOA, GPIO_Pin_3); // slave deselect (high)
return data;
}
Solo al tener estos enviar / recibir y luego otro enviar / recibir puedo obtener el valor esperado del registro. Si no hace el segundo send
, la recepción devuelve un 0x00
.
La escritura es un poco más sencilla, porque es una escritura de dirección, seguida de una escritura de datos.
void write_register()
{
uint8_t numRead1 = 0;
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // slave select (low)
delay_ms(100);
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));
SPI_I2S_SendData(SPI1, 0x40 | 0x80); // send
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));
SPI_I2S_SendData(SPI1, 0x7E); // send
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));
numRead1 = SPI_I2S_ReceiveData(SPI1); // read received
GPIO_SetBits(GPIOA, GPIO_Pin_3); // slave deselect (high)
}
En este caso, espero que numRead1 sea 0x00
, que es el valor predeterminado del registro al que estoy escribiendo. Una llamada posterior a read_register
con la misma dirección devuelve el valor que le escribí.
Pero estoy seguro de que hay un error fundamental en lo que estoy haciendo que, si no se corrige, dará lugar a problemas más graves en el futuro.
¿Alguna idea?