Estoy tratando de escribir un protocolo de comunicación entre un FPGA y un Microcontrolador a través de un SPI, el µC es el Maestro aquí.
- FPGA: Rev.A (iCE5LP4K) de Ultra Breakout de Lattice iCE40
- µC: nórdico nRF52 (PCA10040)
Aquí está el código que estoy usando para la parte de FPGA , la simulación funciona muy bien dentro de Active HDL con Proceso que simula el comportamiento del maestro. Así es como se supone que se verá la transacción (como se explica en el enlace anterior):
- Hay datos disponibles en el registro tx_load_data - > trdy es alto
- El comando de envío principal "0000 0000" le indica al esclavo que cargue los datos MOSI subsiguientes en el registro de recepción, mientras que al mismo tiempo envía el registro de transmisión a MISO (el Maestro recibe tx_load_data)
- trrdy baja cuando se envía el último bit
- Del mismo modo, rrdy va alto para evaluar que se han recibido los nuevos datos enviados por el maestro.
Esto funciona en simulación, me las arreglé para obtener lo mismo que en la Figura 4 (vea el enlace anterior).
Intentando reproducir el mismo comportamiento con el µC adjunto, los datos se cargan, trrdy aumenta, envío un comando como "0x0A", se transmite y ocurre algo en el enlace MISO, pero no puedo leerlo correctamente. Por lo que entendí con las comunicaciones SPI, debo recibir la respuesta mientras estoy presentando datos a través de MOSI. ¿Es eso correcto?
Las siguientes son muestras de mi código C, estoy bastante seguro de que estoy haciendo algo mal pero me falta experiencia. Cuando se realiza la depuración, los registros del búfer de recepción a menudo se rellenan con "111111" (palabras de 6 u 8 bits, es inconsistente). La función sendByte se llama dentro de un controlador de botones, y el búfer rx se imprime en el controlador de eventos spi, llamado en cada transferencia.
/*
* This function is supposed to ouput 00000000 01000001 to MOSI
* Data received is buffered in m_rx_buf[20] array, declared in the header
*/
void sendByteTest() {
ret_code_t err_code;
uint8_t m_tx[2];
m_tx[0] = 0x0;
m_tx[1] = 'A';
m_length = sizeof(m_tx); /**< Transfer length. */
err_code = nrf_drv_spi_transfer(&spi, m_tx, m_length, m_rx_buf, m_length);
if (err_code != NRF_SUCCESS)
NRF_LOG_PRINTF(" Error during transfer.\r\n");
memset(m_rx_buf, 0, m_length);
}
int main(void) {
/** CLOCK, BUTTONS, GPIOTE initialization omitted **/
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG(SPI_INSTANCE);
spi_config.ss_pin = SPI_CS_PIN;
spi_config.mode = NRF_DRV_SPI_MODE_2; // ss_n is active low, set accordingly
spi_config.frequency = NRF_DRV_SPI_FREQ_125K;
spi_config.bit_order = NRF_SPI_BIT_ORDER_MSB_FIRST;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler));
int i = 0;
while(1) {
nrf_gpio_pin_toggle(LED_1);
nrf_delay_ms(200);
}
}