I'm having trouble implementing the workaround that was mentioned in the following previous post: https://devzone.nordicsemi.com/question/55937/nrf52-sending-an-octet/
Thus, I've attached the relevant code that I have so far.
P.S. I'm a beginner so some things that may be obvious to you, might not be obvious to me. Thus I would greatly appreciate detailed answers! The more information, the better.
In my main.c file:
/**
* @brief Work-around for transmitting 1 byte with SPIM.
*
* @param spim: The SPIM instance that is in use.
* @param ppi_channel: An unused PPI channel that will be used by the
workaround.
* @param gpiote_channel: An unused GPIOTE channel that will be used by
the workaround.
*
* @warning Must not be used when transmitting multiple bytes.
* @warning After this workaround is used, the user must reset the PPI
channel and the GPIOTE channel before attempting to transmit multiple
bytes.
*/
void setup_workaround_for_ftpan_58(NRF_SPIM_Type *spim,
uint32_t ppi_channel,
uint32_t gpiote_channel){
// Create an event when SCK toggles.
NRF_GPIOTE->CONFIG[gpiote_channel] =
(GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos) |
(spim->PSEL.SCK << GPIOTE_CONFIG_PSEL_Pos) |
(GPIOTE_CONFIG_POLARITY_Toggle <<GPIOTE_CONFIG_POLARITY_Pos);
// Stop the spim instance when SCK toggles.
NRF_PPI->CH[ppi_channel].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[gpiote_channel];
NRF_PPI->CH[ppi_channel].TEP = (uint32_t)&spim->TASKS_STOP;
NRF_PPI->CHENSET = 1U << ppi_channel;
}
/**@brief Functions prepares buffers and starts data transfer to AS3911
*
* @param[in] p_tx_data A pointer to a buffer TX.
* @param[in] p_rx_data A pointer to a buffer RX.
* @param[in] len A length of the data buffers.
*/
static void spi_send_recv(uint8_t * const p_tx_data,
uint8_t * const p_rx_data,
const uint16_t len)
{
SEGGER_RTT_WriteString(0, "Send and Receive info \n");
if (len == 1){
nrf_ppi_channel_t ppi_channel;
uint32_t gpiote_task_addr;
ret_code_t err_code;
//initializes the GPIOTE channel so that SCK toggles
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
err_code = nrf_drv_gpiote_out_init(SPIM0_SCK_PIN, &config);
APP_ERROR_CHECK(err_code);
//allocates the first unused PPI Channel
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel);
APP_ERROR_CHECK(err_code);
//get the address of the GPIOTE task
//(is this is a GPIOTE channel??????)
gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get (SPIM0_SCK_PIN);
//enable the PPI channel.
err_code = nrf_drv_ppi_channel_enable(ppi_channel);
APP_ERROR_CHECK(err_code);
//enable the GPIOTE output pin task.
nrf_drv_gpiote_out_task_enable(SPIM0_SCK_PIN);
//Start transfer of data
err_code = nrf_drv_spi_transfer(&m_spi_master, p_tx_data, len, p_rx_data, len);
APP_ERROR_CHECK(err_code);
//interrupt transfer of data so that only one byte is sent
setup_workaround_for_ftpan_58(NRF_SPIM_Type *spim,
ppi_channel,
gpiote_task_addr);
//disable the ppi channel
err_code = nrf_drv_ppi_channel_disable(ppi_channel);
//disable a GPIOTE output pin task.
nrf_drv_gpiote_out_task_disable(SPIM0_SCK_PIN);
}
else{
// Start transfer.
uint32_t err_code = nrf_drv_spi_transfer(&m_spi_master, p_tx_data, len,
p_rx_data, len);
APP_ERROR_CHECK(err_code);
}
nrf_delay_ms(delay);
}
/**@brief Function for sending 1 byte to AS3911
*
* @param[in] cmd is the register of the AS3911 that you want to write to
*/
void as3911ExecuteCommand(uint8_t cmd){
uint8_t write_buffer[1];
SEGGER_RTT_WriteString(0, "Entered Execute Command\n");
write_buffer[0] = cmd | AS3911_CMD_MODE;
spi_send_recv(write_buffer, NULL, 1);
}
int main(void){
//0 is the terminal number where the text is output on the J-link RTT
//These lines are meant for debugging purposes and are not necessary
SEGGER_RTT_WriteString(0, "Program Begin\n");
//INITIALIZING PERIPHERALS
//Initialize UART, and board support
uart_config();
bsp_configuration();
//Configure SPI interface
nrf_drv_spi_config_t const config =
{
#if (SPI0_ENABLED == 1)
.sck_pin = SPIM0_SCK_PIN,
.mosi_pin = SPIM0_MOSI_PIN,
.miso_pin = SPIM0_MISO_PIN,
.ss_pin = SPIM0_SS_PIN,
#endif
.irq_priority = APP_IRQ_PRIORITY_LOW, //tells computer what to prioritize over other things
.orc = 0x00,
.frequency = NRF_DRV_SPI_FREQ_1M,
.mode = NRF_DRV_SPI_MODE_1,
.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,
};
//Initialize SPI
ret_code_t err_code = nrf_drv_spi_init(&m_spi_master, &config, spi_master_event_handler);
APP_ERROR_CHECK(err_code);
//initialize GPIOTE and PPI
err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);
//VARIABLES
uint8_t numBytesReg = 0x1D;
//Infinite loop containing main functionality
for(;;){
if (m_transfer_completed)
{
m_transfer_completed = false;
as3911WriteRegister(numBytesReg, 0x01);
as3911ExecuteCommand(0xC1);
}
}
}
ATTACHMENTS: main.c nrf_drv_spi.c nrf_drv_config.h nrf_drv_gpiote.c nrf_drv_ppi.c