int DevSPI::txrx( uint8_t ds, uint8_t *dr ) { if( spi->State != HAL_SPI_STATE_READY ) { return 0; } uint8_t xx; if( !dr ) { dr = &xx; }; __HAL_LOCK( spi ); spi->State = HAL_SPI_STATE_BUSY_TX; spi->ErrorCode = HAL_SPI_ERROR_NONE; if( waitForFlag( SPI_FLAG_TXE, SPI_FLAG_TXE ) != HAL_OK ) { // spi->ErrorCode = HAL_TIMEOUT; return 0; } *( (__IO uint8_t*)&spi->Instance->DR ) = ds; spi->State = HAL_SPI_STATE_BUSY_RX; if( waitForFlag( SPI_FLAG_RXNE, SPI_FLAG_RXNE ) != HAL_OK ) { // spi->ErrorCode = HAL_SPI_ERROR_FRE; return 0; } *dr = *( (__IO uint8_t*)&spi->Instance->DR ); spi->State = HAL_SPI_STATE_READY; __HAL_UNLOCK( spi ); return 1; }
/* * Remotly read from a register of another pozyx device */ int PozyxClass::remoteRegFunction(uint16_t destination, uint8_t reg_address, uint8_t *params, int param_size, uint8_t *pData, int size) { // some checks if(!IS_FUNCTIONCALL(reg_address)) return POZYX_FAILURE; // the register is not a function int status = 0; // first prepare the packet to send uint8_t tmp_data[param_size+2]; tmp_data[0] = 0; tmp_data[1] = reg_address; // the first byte is the function register address we want to call. memcpy(tmp_data+2, params, param_size); // the remaining bytes are the parameter bytes for the function. status = regFunction(POZYX_TX_DATA, tmp_data, param_size+2, NULL, 0); // stop if POZYX_TX_DATA returned an error. if(status == POZYX_FAILURE) return status; // send the packet uint8_t tx_params[3]; tx_params[0] = (uint8_t)destination; tx_params[1] = (uint8_t)(destination>>8); tx_params[2] = 0x08; // flag to indicate a register function call status = regFunction(POZYX_TX_SEND, tx_params, 3, NULL, 0); // stop if POZYX_TX_SEND returned an error. if(status == POZYX_FAILURE) return status; // wait up to x ms to receive a response if(waitForFlag(POZYX_INT_STATUS_RX_DATA, POZYX_DELAY_INTERRUPT)) { // we received a response, now get some information about the response uint8_t rx_info[3]; regRead(POZYX_RX_NETWORK_ID, rx_info, 3); uint16_t remote_network_id = rx_info[0] + ((uint16_t)rx_info[1]<<8); uint8_t data_len = rx_info[2]; if( remote_network_id == destination && data_len == size+1) { uint8_t return_data[size+1]; status = readRXBufferData(return_data, size+1); if(status == POZYX_FAILURE) return status; memcpy(pData, return_data+1, size); return return_data[0]; } }else{ // timeout return POZYX_FAILURE; } }
/* * Remotly read from a register of another pozyx device */ int PozyxClass::remoteRegRead(uint16_t destination, uint8_t reg_address, uint8_t *pData, int size) { // some checks if(!IS_REG_READABLE(reg_address)) return POZYX_FAILURE; // the register is not readable if(size > MAX_BUF_SIZE) return POZYX_FAILURE; // trying to read too much data if(destination == 0) return POZYX_FAILURE; // remote read not allowed in broadcast mode int status = 0; // first prepare the packet to send uint8_t tmp_data[3]; tmp_data[0] = 0; // the offset in the TX buffer tmp_data[1] = reg_address; // the first byte is the register address we want to start reading from tmp_data[2] = size; // the number of bytes to read starting from the register address status = regFunction(POZYX_TX_DATA, (uint8_t *)&tmp_data, 3, NULL, 0); // stop if POZYX_TX_DATA returned an error. if(status == POZYX_FAILURE) return status; // send the packet uint8_t params[3]; params[0] = (uint8_t)destination; params[1] = (uint8_t)(destination>>8); params[2] = 0x02; // flag to indicate a register read status = regFunction(POZYX_TX_SEND, (uint8_t *)¶ms, 3, NULL, 0); // stop if POZYX_TX_SEND returned an error. if(status == POZYX_FAILURE) return status; // wait up to x ms to receive a response if(waitForFlag(POZYX_INT_STATUS_RX_DATA, POZYX_DELAY_INTERRUPT)) { // we received a response, now get some information about the response uint8_t rx_info[3]= {0,0,0}; regRead(POZYX_RX_NETWORK_ID, rx_info, 3); uint16_t remote_network_id = rx_info[0] + ((uint16_t)rx_info[1]<<8); uint8_t data_len = rx_info[2]; if( remote_network_id == destination && data_len == size) { status = readRXBufferData(pData, size); return status; }else{ return POZYX_FAILURE; } }else{ // timeout return POZYX_FAILURE; } }
int DevSPI::sendSame( uint8_t ds, int ns ) { if( ns < 1 || spi->State != HAL_SPI_STATE_READY ) { return 0; } __HAL_LOCK( spi ); spi->State = HAL_SPI_STATE_BUSY_TX; spi->ErrorCode = HAL_SPI_ERROR_NONE; if( ( spi->Instance->CR1 & SPI_CR1_SPE ) != SPI_CR1_SPE ) { // need to reenable? __HAL_SPI_ENABLE( spi ); } int n = 0; for( n=0; n<ns; ++n ) { if( waitForFlag( SPI_FLAG_TXE, SPI_FLAG_TXE ) != HAL_OK ) { return 0; } *( (__IO uint8_t*)&spi->Instance->DR ) = ds; } /* Check the end of the transaction */ if( waitForFlag( SPI_FLAG_BSY, 0 ) != HAL_OK ) { // TODO: error return 0; } __HAL_SPI_CLEAR_OVRFLAG( spi ); spi->State = HAL_SPI_STATE_READY; __HAL_UNLOCK( spi ); return n; }