AnsweredAssumed Answered

BF592 SPI1 Slave Interrupts

Question asked by jomegasteve on Sep 2, 2014
Latest reply on Sep 23, 2014 by jobo23

I am having difficulty with SPI1 configured as a slave. This port will use interrupts, rather than DMA, because the remote master's protocol is full duplex. I am new to the BF592 but have not had much trouble getting the SPORTs and SPI0 running successfully. (SPI0 is polled, no DMA or ISR required, so its not similar). I am attempting to operate with TIMOD = 00, PSSE on, EMISO on, 8 bits. What I am seeing is the data is received on MOSI into SPI1_RDBR as expected, but the ISR never fires. Instead, I find DMA6 (IRQ14) asserting an interrupt at SIC_ISR0, rather than IRQ6. I have code in place to disable DMA6, and kill its sticky error bits just to be sure. When I halt the emulaton (EZ-LITE 592 kit) I can see the SPI1_STAT is asserting the RXS full flag (and overflow flags too), but no interrupt is ever seen pending or processed. A DMA6 status register dump shows no interrupt asserted, but the SIC_ISR0 register dump shows DMA6 is asserting. The DMA assertion may be normal for the BF592, but it look suspicious to me. It doesn't occur until I start sending characters. Since the SIC_IMASK blocks that bit, it remains asserted.

 

I also see several different output characters on MISO, when I exchange a sequence of 4 bytes. Since no ISR runs, I expect to see my pre-loaded Tx byte repeated (0xFF, Repeat Last is selected), but I am seeing 4 unrelated bytes (0x00,FF, C0, 00). This pattern repeats whenever the master sends a message, even if the emulation is halted. Can the DMA run when execution is halted?.

 

Though I set TIMOD to 0, is there anything else I need to do that would affect the status bit reaching the SIC_IMASK register as I expect?  Hopefully someone can see what I missed. Any help would be appreciated.

 

Thanks to all,

Steve

 

 

Below are snippets. I used the Expert Pin Mux tool to set my IO - except the SPI1_SS feature that it does not support.

void InitPorts() // Pin mux tool
{
// First Set PORTF_MUX registers
*pPORTF_MUX = 0x0;

*pPORTG_MUX = 0x0; 

// Set PORTx_FER registers
*pPORTF_FER = 0xe00e;
*pPORTG_FER = 0x7e0;
// Set PORTxIO_DIR registers
*pPORTFIO_DIR = 0x1bf1;
*pPORTGIO_DIR = 0xd015;
// Set PORTxIO_INEN registers
*pPORTFIO_INEN = 0x400;
*pPORTGIO_INEN = 0x280a;
}

 

void SpiSlaveConfig(void)

{

*pSPI1_CTL  &=  (~SPE);    // disable SPI
  *pSPI1_RDBR; // dummy read , errata 05000501

  *pPORTG_FER |= PG13; // the SPI_SS input must be enabled. pin mux.c does not do this

// now the SPI port registers
*pSPI1_CTL   =  RDBR_CORE |     /* RDBR Read Initiates, IRQ When RDBR Full  */
     PSSE  |  /* Slave-Select Input Enable     */
    #if EZ_LITE_KIT
     EMISO  |  /* Enable MISO As Output    */
    #endif
     0;
*pSPI1_BAUD  =  MSP_BAUD_CFG;  // reference only 
*pSPI1_FLG   =  0xFF00;   // Disable all SlaveSelect, force hi (ignored in slave mode)
asm("ssync;");

// Make sure SPI1's DMA is off
*pDMA_CONFIG(6) &= ~DMAEN;
*pDMA_PERIPHERAL_MAP(6) = 0x6000; // default assignment : SPI1 Status to DMA6
*pDMA_IRQ_STATUS(6) = 0x0003; // clear W1C bits

// register the ISR
    register_handler_ex(ik_ivg7, SPI1_ISR, EX_INT_ALWAYS_ENABLE);  //  use default assignment

// IMASK is now enabled but SIC_IMASK is not

asm("ssync;");

}

 

void spiSlave_start(int SpiNum)
{
switch(SpiNum)

{
  case 1:  // MSP link
   *pSPI1_TDBR = SPI_BUS_NOT_BUSY; // pre-load the outbound register
   *pSPI1_CTL  |=  (SPE);    // enable SPI
    *pSPI1_RDBR; // dummy read , clear any pending
    *pSIC_IMASK0 |= (IRQ_SPI1_ERR);  // interrupts on

     break;

  case 0:    // removed code    
  default:  
   break;
} // switch

asm("ssync;");
}

EX_INTERRUPT_HANDLER(static SPI1_ISR)
{

if (*pSPI1_STAT & RXS) {

    *pSPI1_TDBR = next byte;

          // code removed here

  NewRx = *pSPI1_RDBR;    // clears interrupt

      // code removed here

}

}

Outcomes