SPI IRQ Handler written for the LPC54018 fails to execute the SPI_ReadData function

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI IRQ Handler written for the LPC54018 fails to execute the SPI_ReadData function

Jump to solution
2,631 Views
jmueckl
Contributor IV
I wrote the following IRQ Handler to transfer one byte of SPI data to a slave. The handler is called by the function writeRegister8() which first writes the address of the slave followed by the slave data that is to be written to that address. The same handler is called by the function readRegister8() which first writes the address of the slave to be read from and then reads the data from that address using the dedicated function SPI_ReadData(). The function writeRegister8 works, but the readRegister8 function fails when SPI_ReadData() is called. All SPI_ReadData() does is return base->FIFORD, a 32 bit register. Although SPI_ReadData typically returns values like 0xe00ff, 0xe003f or 0x300d0, the scope does not get triggered. Channel 1 of my scope is connected to SCK and channel 2 to MISO (SDO). The scope does correctly capture the Clock and MOSI signals when SPI_WriteData is executed. Can someone tell me why SPI_ReadData is failing? I think the problem is related to something I don’t understand about the nature of the FIFO in the LPC54018, since I am attempting to read or write a single byte to the slave. I know that my slave works and is wired correctly because I have implemented a similar version of my writeRegister8 and readRegister8 function using the masterCallback function as implemented in the SDK example spi_interrupt_b2b_master_transfer. In this implementation my scope correctly captures both MOSI and MISO signals. Note that both implementations are C++. I would like to understand which of the two methods I am experimenting with is preferable for the purpose of transferring byte sized data to a SPI slave. Is one more efficient than the other? Will the interrupt driven method take more or less time than the masterCallback method? uint8_t SPIAddr; static uint32_t RxData; static uint8_t TxData; void FLEXCOMM9_IRQHandler(void) { if ((SPI_GetStatusFlags(SPI9) & kSPI_TxNotFullFlag)) { if (SPI_RW == WRITE) // A second Write is coming { // need to disable Both Rx & Tx interrupts or handler wraps SPI_DisableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq); // SSEL will be deasserted (stays low) at the end of transfer SPI_WriteData(SPI9, (uint16_t)(SPIAddr), 0); } if (SPI_RW == READ) { // need to disable Both Rx & Tx interrupts or handler wraps SPI_DisableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq); // SSEL will be deasserted (stays low) at the end of transfer SPI_WriteData(SPI9, (uint16_t)(SPIAddr), 0); } } if ((SPI_GetStatusFlags(SPI9) & kSPI_RxNotEmptyFlag) && (SPI_RW == READ)) { RxData = SPI_ReadData(SPI9); SDK_DelayAtLeastUs(10, BOARD_BOOTCLOCKFRO12M_CORE_CLOCK); // 10us } if ((SPI_GetStatusFlags(SPI9) & kSPI_TxNotFullFlag) && (SPI_RW == WRITE)) { // End of transfer // Set MOSI high after the write SPI_WriteData(SPI9, (uint16_t)(TxData), kSPI_FrameAssert); } SPI_IRQ_Finished = true; IRQH_count++; SDK_ISR_EXIT_BARRIER; } uint32_t MAX31865::readRegister8(uint8_t RegAddr) { SPI_RW = READ; SPIAddr = RegAddr & 0x7F; // make sure top bit is not set TxData = 0; SPI_EnableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq); while (SPI_IRQ_Finished != true) { } SPI_IRQ_Finished = false; return RxData; // RxData obtained in SPI_Handler } void MAX31865::writeRegister8(uint8_t RegAddr, uint8_t writeData) { SPI_RW = WRITE; SPIAddr = RegAddr | 0x80; // top bit keeps PCSn signals asserted between transfers TxData = writeData; SPI_EnableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq); while (SPI_IRQ_Finished != true) { } SPI_IRQ_Finished = false; }
0 Kudos
1 Solution
2,419 Views
jmueckl
Contributor IV

I have revised my IRQHander which now works correctly.  The logic is simplified, to be sure, but the main problem inherent in my original code was in the use of an if statement to detect that the RxNotEmptyFlag status flag was set, as opposed to the while loop I now use.  The if statement is fine for checking the TxEmptyFlag status flag, but for receiving data the while loop allows the processor all the time it needs to detect the presence of received data.

I was not able to get the polling method Rong recommended to work, even though I used the while loop to check for received data as opposed to the if statement.  I do believe that the configuration data 0x0F1E0000 is correct.  I welcome anyone who appreciates a challenge to determine what the problem is.

I also asked the community if anyone could comment on the efficiency of using my ISR handler and that of the spi_int_b2b_master_transfer example which uses a Callback to transfer blocks of data.  It turns out that my interrupt single byte transfers took about 400us, but the Callback transfers took around 1.5ms to transfer a single byte.   

 

void FLEXCOMM9_IRQHandler(void)

{

    if (SPI_RW == WRITE)

    {

       if (SPI_GetStatusFlags(SPI9) & kSPI_TxEmptyFlag)

       {

                 // need to disable Both Rx & Tx interrupts or handler wraps

          SPI_DisableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq);

          // End of transfer  // Set MOSI high after the write

          SPI_WriteData(SPI9, (uint16_t)(WRData), kSPI_FrameAssert);

       }

    }

    if (SPI_RW == READ)

    {

       if (SPI_GetStatusFlags(SPI9) & kSPI_TxEmptyFlag)

       {

                 // need to disable Both Rx & Tx interrupts or handler wraps

          SPI_DisableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq);

          // End of transfer  // Set MOSI high after the write

          SPI_WriteData(SPI9, (uint16_t)(RDData), kSPI_FrameAssert);

       }

       while (SPI_GetStatusFlags(SPI9) & kSPI_RxNotEmptyFlag)

       {

          RxData = SPI_ReadData(SPI9);

       }

    }

    SPI_IRQ_Finished = true;

    IRQH_count++;

    SDK_ISR_EXIT_BARRIER;

}

View solution in original post

0 Kudos
16 Replies
2,630 Views
jmueckl
Contributor IV

Let's submit this post again with the code in an attached document.

I wrote the following IRQ Handler to transfer one byte of SPI data to a slave.  The handler is called by the function writeRegister8() which first writes the address of the slave followed by the slave data that is to be written to that address.  The same handler is called by the function readRegister8() which first writes the address of the slave to be read from and then reads the data from that address using the dedicated function SPI_ReadData().  The function writeRegister8 works, but the readRegister8 function fails when SPI_ReadData() is called.  All SPI_ReadData() does is return base->FIFORD, a 32 bit register.  Although SPI_ReadData typically returns values like 0xe00ff, 0xe003f or 0x300d0, the scope does not get triggered. Channel 1 of my scope is connected to SCK and channel 2 to MISO (SDO).  The scope does correctly capture the Clock and MOSI signals when SPI_WriteData is executed.  Can someone tell me why SPI_ReadData is failing?  I think the problem is related to something I don’t understand about the nature of the FIFO in the LPC54018, since I am attempting to read or write a single byte to the slave.    

I know that my slave works and is wired correctly because I have implemented a similar version of my writeRegister8 and readRegister8 function using the masterCallback function as implemented in the SDK example spi_interrupt_b2b_master_transfer.  In this implementation my scope correctly captures both MOSI and MISO signals.  Note that both implementations are C++.

I would like to understand which of the two methods I am experimenting with is preferable for the purpose of transferring byte sized data to a SPI slave.  Is one more efficient than the other?  Will the interrupt driven method take more or less time than the masterCallback method?

2,613 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Jerry,

It appears that you use MC31865, it is a RTD converter.

This is the SPI timing:

xiangjun_rong_0-1617950875193.png

For the above SPI timing, you should set the data length as 16 bits, in other words, after all 16 bits has transferred, the flag in SPI status will be set, then you can read the data.

 

uint32_t temp;

 

SPI_FIFOWR=0x0F1E0000|BYTE_ADDRSSS<<8;

While(!(SPI_FIFOSTAT*0x10)) {}

temp= (SPI_FIFOWR&0xFF);

You have to init the other register for example setting the baud rate, master mode, CPHA/CPOL...

Hope it can help you

BR

XiangJun Rong

0 Kudos
2,607 Views
jmueckl
Contributor IV

Xiang_jun, what you have described is related to the the function SPI_WriteData(), which works well for me.  The problem I have described is only with respect to the SPI_READ() function which is defined in fsl_spi.h as

static inline uint32_t SPI_ReadData(SPI_Type *base)

{

    assert(NULL != base);

    return base->FIFORD;

}

 

My SPI IRQHandler performs a byte write to the slave by calling SPI_WriteData() to write the slave address (SPIAddr), and a second call to SPI_WriteData() to write the transmit byte (TxData).  The two 8 bit writes is equivalent to a 16 bit write.

As the timing diagrams you posted illustrates, to read a byte from the slave one must first write the address of the slave, which I implement in my handler using  

(1) SPI_WriteData(SPI9, uint16_6 (SPIAddr), 0);

To read the byte from that slave address I then execute the code

(2) RxData = SPI_ReadData(SPI9);

But during this call my oscilloscope doesn’t detect any clock or MISO transitions.  The value that my readRegister8() function returns is the value that my scope captured on the MISO pin during code line (1).

I hope that clarifies my question so that you or someone else can answer it.

0 Kudos
2,587 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

As you said that  during this call my oscilloscope doesn’t detect any clock or MISO transitions. The value that my readRegister8() function returns is the value that my scope captured on the MISO pin during code line (1).

If you can not see the SCK, MOSI even CS signal of SPI via scope, I suppose that it is another question, have you set up the pin mux.

PIO4_14 ENET_RX_CLK CTIMER4_MAT1 FC9_SCK - SCT0_GPI7 - - - -

/* Enables the clock for the IOCON block. 0 = Disable; 1 = Enable.: 0x01u */
CLOCK_EnableClock(kCLOCK_Iocon);

IOCON->PIO[4][14] = ((IOCON->PIO[4][14] &
/* Mask bits to zero which are setting */
(~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK)))

/* Selects pin function.
* : PORT010 (pin P2) is configured as SWO. */
| IOCON_PIO_FUNC(PIO010_FUNC_ALT3)

/* Selects function mode (on-chip pull-up/pull-down resistor control).
* : Inactive.
* Inactive (no pull-down/pull-up resistor enabled). */
| IOCON_PIO_MODE(PIO414_MODE_INACTIVE)

/* Select Analog/Digital mode.
* : Digital mode. */
| IOCON_PIO_DIGIMODE(PIO414_DIGIMODE_DIGITAL));

 


PIO4_15 ENET_MDC CTIMER4_MAT2 FC9_RXD_SDA_MOSI - - - - - -
PIO4_16 ENET_MDIO CTIMER4_MAT3 FC9_TXD_SCL_MISO

xiangjun_rong_0-1618227737810.png

BTW, I suggest you set up the SPI width with 16 bits instead of 8 bits.

Hope it can help you

BR

XiangJun Rong

0 Kudos
2,580 Views
jmueckl
Contributor IV

Please understand that my scope is triggered by CLK, CS, MOSI & MISO signals at the time the following function is called:

(1) SPI_WriteData(SPI9, uint16_6 (SPIAddr), 0);

It is only when SPI_ReadData() is called that there is no scope activity.

I don’t see a means to specify the width of my SPI bus.  Exactly how do you do that for the LPC54018?  The fact that I am using an 8 bit variable to read the result of SPI_ReadData() does not change the internal width of the SPI bus. Is there a setting for the SPI FIFO size?

0 Kudos
2,549 Views
jmueckl
Contributor IV

Please realize there are two questions here.

You are indicating then that there is no need to use the function SPI_ReadData().  Why is it in the API?  It is misleading.

You suggested that I specify the width of my SPI bus as 16 bits.  Exactly how do I do that in the code for the LPC54018?  

0 Kudos
2,539 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Jerry,

Pls refer to the SPI_WriteData() function in SDK package, which writes the FIFOWR register and generate SPI timing. The control bits specify the bit width of SPI data.

Regarding the SPI_ReadData(), it just reads the FIFORD register and encapsulate a function. As I said it does not generate SPI timing.

You can download SDK package from the link:

https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-s...

 

Hope it can help you

BR

XiangJun Rong

 

void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags)
{
uint32_t control = 0U;
uint32_t instance;

/* check params */
assert(NULL != base);
/* get and check instance */
instance = SPI_GetInstance(base);

/* set data width */
control |= (uint32_t)SPI_FIFOWR_LEN((g_configs[instance].dataWidth));
/* set sssel */
control |= (SPI_DEASSERT_ALL & (~SPI_DEASSERTNUM_SSEL((uint32_t)(g_configs[instance].sselNum))));
/* mask configFlags */
control |= (configFlags & (uint32_t)SPI_FIFOWR_FLAGS_MASK);
/* control should not affect lower 16 bits */
assert(0U == (control & 0xFFFFU));
base->FIFOWR = data | control;
}

 

void SPI_MasterGetDefaultConfig(spi_master_config_t *config)
{
assert(NULL != config);

/* Initializes the configure structure to zero. */
(void)memset(config, 0, sizeof(*config));

config->enableLoopback = false;
config->enableMaster = true;
config->polarity = kSPI_ClockPolarityActiveHigh;
config->phase = kSPI_ClockPhaseFirstEdge;
config->direction = kSPI_MsbFirst;
config->baudRate_Bps = 500000U;
config->dataWidth = kSPI_Data8Bits;  ////// the line initilize the spi data width, it is kSPI_Data16Bits for //your case.
config->sselNum = kSPI_Ssel0;
config->txWatermark = (uint8_t)kSPI_TxFifo0;
config->rxWatermark = (uint8_t)kSPI_RxFifo1;
config->sselPol = kSPI_SpolActiveAllLow;
config->delayConfig.preDelay = 0U;
config->delayConfig.postDelay = 0U;
config->delayConfig.frameDelay = 0U;
config->delayConfig.transferDelay = 0U;
}

typedef enum _spi_data_width
{
kSPI_Data4Bits = 3, /*!< 4 bits data width */
kSPI_Data5Bits = 4, /*!< 5 bits data width */
kSPI_Data6Bits = 5, /*!< 6 bits data width */
kSPI_Data7Bits = 6, /*!< 7 bits data width */
kSPI_Data8Bits = 7, /*!< 8 bits data width */
kSPI_Data9Bits = 8, /*!< 9 bits data width */
kSPI_Data10Bits = 9, /*!< 10 bits data width */
kSPI_Data11Bits = 10, /*!< 11 bits data width */
kSPI_Data12Bits = 11, /*!< 12 bits data width */
kSPI_Data13Bits = 12, /*!< 13 bits data width */
kSPI_Data14Bits = 13, /*!< 14 bits data width */
kSPI_Data15Bits = 14, /*!< 15 bits data width */
kSPI_Data16Bits = 15, /*!< 16 bits data width */
} spi_data_width_t;

0 Kudos
2,533 Views
jmueckl
Contributor IV

Rong,

After changing the dataWidth from 8 bits to 16 bits, I simplified my writeRegister8() function as I show below.  However, my readRegister8() doesn’t work.   I attempted to implement your code line 

temp= (SPI_FIFOWR&0xFF);

but I don’t have direct access to register FIFOWR (SPI_FIFOWR doesn’t exist). I believe I can only call SPI_WriteData() or SPI_ReadData().  Since I have to write the register address before the processor can read the SDO read data, SPI_WriteData(SPI9, RDData) now writes two bytes rather than one. The following SPI_ReadData(SPI9) function always reads the value of 0xFF in the LS Byte.  

How did you intend for me to implement your process?

void FLEXCOMM9_IRQHandler(void)

{

    if ((SPI_GetStatusFlags(SPI9) & kSPI_TxEmptyFlag) && SPI_RW == WRITE)

    {

       // need to disable Both Rx & Tx interrupts or handler wraps

       SPI_DisableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq);

// WRData = (RegAddr | 0x80) << 8 | byte-to-write;

       SPI_WriteData(SPI9, (uint16_t)(WRData), kSPI_FrameAssert);

    }

    if (SPI_RW == READ)  // Doesn’t work

    {

       while (!(SPI_GetStatusFlags(SPI9) & kSPI_TxEmptyFlag)) { };

       // need to disable Both Rx & Tx interrupts or handler wraps

       SPI_DisableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq);

       // RDData = (RegAddr | 0x80) << 8;

       SPI_WriteData(SPI9, (uint16_t)(RDData), kSPI_FrameAssert);

       RxData = SPI_ReadData(SPI9);  // Always reads 0xFF 

    }

    SPI_IRQ_Finished = true;

    IRQH_count++;

    SDK_ISR_EXIT_BARRIER;

}

0 Kudos
2,529 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

for simplicity, you can access the SPI9 register with the code like:

uint32_t temper_var;
#define SPI9_FIFOWR_ADDR 0x4009AE20
#define SPI9_FIFORD_ADDR 0x4009AE24
void spi_writ(void)
{
*(uint32_t *)SPI9_FIFOWR_ADDR=0x12345678;
temper_var=*(uint32_t *)SPI9_FIFORD_ADDR;
}

The address is specified in UM10912.pdf.

Hope it can help you

BR

Xiangjun Rong

0 Kudos
2,519 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

For simplicity, you can use polling mode, access the SPI9 register with the code like:

uint32_t temper_var;
#define SPI9_FIFOWR_ADDR 0x4009AE20
#define SPI9_FIFORD_ADDR 0x4009AE24

#define SPI9_FIFOSTAT_ADDR 0x4009AE04


void spi_write_read(void)
{
*(uint32_t *)SPI9_FIFOWR_ADDR=0x12345678;

while(!(*(uint32_t *)SPI9_FIFOWR_ADDR)&0x10) {} //poll TXEMPTY bit


temper_var=*(uint32_t *)SPI9_FIFORD_ADDR;
}

The address is specified in UM10912.pdf.

Hope it can help you

BR

Xiangjun Rong

0 Kudos
2,516 Views
jmueckl
Contributor IV

Rong,

I attempted the code you just wrote, but still have the same issue.  From experimenting I learned that

1. The write only works if I specify 0x0F1E000 in the write data as you first wrote.

WRData = 0x0F1E0000 | ((RegAddr | 0x80) << | writeData;

2. The address for FIFORD is an offset of 0xE30, not 0xE24

#define SPI9_FIFORD_ADDR 0x4009AE30 // Offset 0xE30

Even with these necessary improvements the write works but the read fails. Inserting a second write after the read does initiate a read value, as if the response was delayed, but the second write changes the answer. 

0 Kudos
2,486 Views
jmueckl
Contributor IV

I still have not resolved the SPI read issue I began with, even with the polling method Rong suggested.  It may be that the configuration value of 0x0F1E000 needs to be tweaked.  Where do I find documentation to help me?

0 Kudos
2,478 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

 Pls download UM11060.pdf from the link, and check the SPI chapter.

https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mc...

 

BR

Xiangjun Rong

0 Kudos
2,420 Views
jmueckl
Contributor IV

I have revised my IRQHander which now works correctly.  The logic is simplified, to be sure, but the main problem inherent in my original code was in the use of an if statement to detect that the RxNotEmptyFlag status flag was set, as opposed to the while loop I now use.  The if statement is fine for checking the TxEmptyFlag status flag, but for receiving data the while loop allows the processor all the time it needs to detect the presence of received data.

I was not able to get the polling method Rong recommended to work, even though I used the while loop to check for received data as opposed to the if statement.  I do believe that the configuration data 0x0F1E0000 is correct.  I welcome anyone who appreciates a challenge to determine what the problem is.

I also asked the community if anyone could comment on the efficiency of using my ISR handler and that of the spi_int_b2b_master_transfer example which uses a Callback to transfer blocks of data.  It turns out that my interrupt single byte transfers took about 400us, but the Callback transfers took around 1.5ms to transfer a single byte.   

 

void FLEXCOMM9_IRQHandler(void)

{

    if (SPI_RW == WRITE)

    {

       if (SPI_GetStatusFlags(SPI9) & kSPI_TxEmptyFlag)

       {

                 // need to disable Both Rx & Tx interrupts or handler wraps

          SPI_DisableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq);

          // End of transfer  // Set MOSI high after the write

          SPI_WriteData(SPI9, (uint16_t)(WRData), kSPI_FrameAssert);

       }

    }

    if (SPI_RW == READ)

    {

       if (SPI_GetStatusFlags(SPI9) & kSPI_TxEmptyFlag)

       {

                 // need to disable Both Rx & Tx interrupts or handler wraps

          SPI_DisableInterrupts(SPI9, kSPI_TxLvlIrq | kSPI_RxLvlIrq);

          // End of transfer  // Set MOSI high after the write

          SPI_WriteData(SPI9, (uint16_t)(RDData), kSPI_FrameAssert);

       }

       while (SPI_GetStatusFlags(SPI9) & kSPI_RxNotEmptyFlag)

       {

          RxData = SPI_ReadData(SPI9);

       }

    }

    SPI_IRQ_Finished = true;

    IRQH_count++;

    SDK_ISR_EXIT_BARRIER;

}

0 Kudos
2,523 Views
jmueckl
Contributor IV

Rong,

Below is the code that I tested based on your recommendations.  I do like your implementation because it avoids the need for an IRQ handler, but it has the same problem as the code I submitted at first in void FLEXCOMM9_IRQHandler(void). Spi_WR() works but spi_RD() does not.  My oscilloscope shows the correct MOSI and MISO signals for both functions, including the correct read data as the last byte of the MISO signal.  

The following illustrates the problem I am seeing:

   ReadTest1 = spi_RD(MAX31865_CONFIG_REG);   // ReadTest1 = 0xff

   spi_WR(MAX31865_CONFIG_REG, 0xaa);              // Write 0xaa to the address just read

   ReadTest1 = spi_RD(MAX31865_CONFIG_REG);   // ReadTest1 = 0xd0 (correct value)

For some reason, spi_RD() returns the correct results only if I insert a spi_WR() after the first call.

It may be helpful to realize that my code works when it is implemented in a masterCallback which looks like the SDK example

static void masterCallback(SPI_Type *base, spi_master_handle_t *handle, status_t status,               void *userData)

{

                               masterFinished = true;

}

My masterCallback implementation has the same phase, polarity, sselNum & sselPol configuration settings as does this code, which I prefer.  The only configuration differences are that the masterCallback implementation has dataWidth of 8 bits verses 16 bits.  The variable ConfigFlags is 0x100000 in the Callback.    

// from LPC54018.h

// #define SPI9_BASE     (0x4009A000u)

// #define SPI9          ((SPI_Type *)SPI9_BASE)

#define SPI9_FIFOWR_ADDR 0x4009AE20   // Offset 0xE20

#define SPI9_FIFORD_ADDR 0x4009AE30   // Offset 0xE30

#define SPI9_FIFOSTAT_ADDR 0x4009AE04 // Offset 0xE04

 

void MAX31865::spi_WR(uint8_t RegAddr, uint8_t writeData)

{

       WRData = 0x0F1E0000 | ((RegAddr | 0x80) << | writeData; 

       //while(!(SPI9_FIFOSTAT_ADDR * 0x10)) {}; // While TX is empty (has no effect on result)

       *(uint32_t *)SPI9_FIFOWR_ADDR=WRData;

}

uint8_t MAX31865::spi_RD(uint8_t RegAddr)

{

       uint8_t temp_var = 0;

       WRData = 0x0F1E0000 | ((RegAddr & 0x7f) << 8);

       *(uint32_t *)SPI9_FIFOWR_ADDR = WRData;

       //while(!(SPI9_FIFOSTAT_ADDR * 0x10 )) {}; // While TX is empty (has no effect on result)

       temp_var= *(uint32_t *)SPI9_FIFORD_ADDR & 0xFF;

    return temp_var;

}

0 Kudos
2,561 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Jerry,

It appears that you misunderstand the SPI mechanism. When the SPI module is configured as a master, after your write the SPI_FIFOWR register, the SPI module will generate the SPI timing, the bits in SPI_FIFOWR will appeared on MOSI with SCK clocking, at the same time, the master will receive data from MISO pin with SCK and save the data in SPI->FIFORD. In other words, reading data from SPI->FIFORD can NOT generate SPI timing.

This is the model of the SPI writing/reading, firstly, write SPI_FIFOWR, after the data in SPI_FIFOWR has been transmitted, a flag will be set, after the flag is set, it means that the data has been received also, it is okay read it to memory variable temp.


SPI_FIFOWR=0x0F1E0000|BYTE_ADDRSSS<<8;

While(!(SPI_FIFOSTAT*0x10)) {}

temp= (SPI_FIFOWR&0xFF);

Hope it can help you

BR

XiangJun Rong

0 Kudos