MSP430FR5994: MSP430FR5994 SPI ISSUE

Part Number: MSP430FR5994
Other Parts Discussed in Thread: ADS8866, MSPM0G3507

Tool/software:

MSP430FR5994 SPI communication, using a 16MHz clock, when sending one byte followed by the next byte, there is a 6.63µs gap between each byte?

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//******************************************************************************
// SPI SRAM I/O Initial *******************************************************
//******************************************************************************
void SPI_IO_SRAM_initial(void)
{
// Configure SPI
P6SEL0 |= BIT4 | BIT5 | BIT6;
P6SEL1 &= ~(BIT4 | BIT5 | BIT6);
SLAVE_SRAM_CS_DIR |= SLAVE_SRAM_CS_PIN;
SLAVE_SRAM_CS_OUT |= SLAVE_SRAM_CS_PIN;
}
//******************************************************************************
// SPI SRAM register Initial *************************************************
//******************************************************************************
void SPI_register_SRAM_initial(void)
{
//Clock Polarity: The inactive state is high
//MSB First, 8-bit, Master, 3-pin mode, Synchronous
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//******************************************************************************
// SPI_SRAM_Master_Write_data *************************************************
//******************************************************************************
void SPI_SRAM_Master_Write_data(uint32_t Write_SRAM_start_Address,uint8_t *data_buf ,uint16_t Write_SRAM_len)
{
uint16_t i= 0;
SRAM_MasterMode = SRAM_TX_DATA_MODE;
SRAM_ReceiveIndex = 0;
SRAM_RXByteCtr = 0;
SRAM_TransmitIndex = 0;
SRAM_TXByteCtr = (SRAM_Instruction_len + SRAM_Address_len + Write_SRAM_len); // Total SRAM_TransmitIndex length.
SRAM_TransmitBuffer[0] = 0x02; // SEQUENTIAL WRITE (SPI MODE)
//Read address 3 byte.
SRAM_TransmitBuffer[1] = ((Write_SRAM_start_Address >> 16) & 0xFF); // Address h byte.
SRAM_TransmitBuffer[2] = ((Write_SRAM_start_Address >> 8) & 0xFF); // Address m byte.
SRAM_TransmitBuffer[3] = (Write_SRAM_start_Address & 0xFF); // Address l byte.
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//******************************************************************************
// SPI SRAM SendUCB1Data *****************************************************
//******************************************************************************
void SendUCB3Data(uint8_t val)
{
while (!(UCB3IFG & UCTXIFG)); // USCI_B3 TX buffer ready?
UCB3TXBUF = val;
}
//******************************************************************************
// SPI USCI_B3_VECTOR Interrupt ***********************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B3_VECTOR
__interrupt void USCI_B3_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B3_VECTOR))) USCI_B3_ISR (void)
#else
#error Compiler not supported!
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Can you try not to use the interrupt and directly send it with your  SendUCB3Data() function?

  • 1. I modified the SendUCB3Data to send 3 bytes at a time, but the CS preparation time is a bit long, and the result seems a bit unexpected. After sending the data, I cannot pull CS to a high level.



    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //******************************************************************************
    // SPI SRAM SendUCB1Data *****************************************************
    //******************************************************************************
    void SendUCB3Data(uint8_t val)
    {
    int i = 0;
    while (!(UCB3IFG & UCTXIFG)); // USCI_B3 TX buffer ready?
    for(i = 0;i < 3; i++)
    {
    UCB3TXBUF = val+i;
    }
    while (!(UCB3IFG & UCTXIFG)); // USCI_B3 TX buffer ready?
    // UCB3TXBUF = val;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX



    2.Another issue is that my target sampling frequency is 50kHz, and I need to complete the sound collection. For the external ADC (ADS8866) and external SRAM (23AA04M), it must be completed within 20 us. Can the MSP430FR5994 meet these conditions? If not, do you have any recommended MCUs?

  • 1) With SCK=SMCLK=MCLK, one SPI byte takes 8 CPU clocks, which is maybe 1-3 CPU instructions. (This is why you get away with not checking TXIFG in the loop.) This is very tight timing, and I suspect the CPU isn't keeping up.

    The usual answer here is DMA, but it turns out that with the DMA channel/trigger assignments [Ref data sheet (SLASE54D) Table 9-11] DMA is only occasionally useful (Tx-only) for UCB1/2/3. Is it too late in your design to switch to UCB0?

    I'm not sure what I'm looking at in the analyzer trace -- specifically: what is that line below SCK?

    2) You can send (exchange) 2x SPI bytes in 1us, but the SRAM takes a minimum of 5 bytes to do anything. Folding in the ADC (2x more bytes plus conversion time) will make the timing even tighter. Even with DMA, managing the Chip Selects will require CPU intervention. This might be feasible (just barely), but your MCU won't be able to do anything else.

    TI's current offering in the small/cheap/fast(er) category is the MSPM0 line. The MSPM0G35x series can run at 80MHz and has 7x DMA channels (all general-purpose). [I don't work for TI; you can explore the range at the Product pages.]

  • This appears to be mismatch between the task and the hardware. The MSP430 is good at low power applications where it is in a low power mode most of the time. This is a task that requires doing something quickly. Low power doesn't appear to be a requirement.

    At 50K SPS you have 320 MCLKs per sample to do everything. Read data from the ADC and then write it to the external SRAM. It might be doable. It might require tight coding done in assembly language. At which point you should be thinking about some other device with higher clock speeds.

    Lots of ARMs out there with clocks over 100MHz.

  • Hi Bruce,

    1. Switching to UCB0 is probably too late, but I tend to think it's more about the limitations of the MSP430 itself. Interrupts are still a better architectural design for me; the line under SCK is CS.

    2. I'll give the MSPM0G3507 a try, I happen to have a board on hand to test it. Thank you very much for the suggestion.

    Best regards,

    Anthony

  • Hi David,

    Subsequently, I will test with a higher-clock MCU. Assigning the 50k SPS sampling rate to the MSP430FR5994 is truly too much of a burden. Thank you very much for your suggestion.

    Best regards,

    Anthony

**Attention** This is a public forum