This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Using SPI transmit complete interrupt to trigger ADC with SOC signal

Other Parts Discussed in Thread: CONTROLSUITE, TMS320F28335

Hello,

I am aware of examples in control suite in which both the ADC and SPI interface of the module are used, but none in which both are used.

I want the SPI to send some instructions, and for the ADC to measure the output of my system as a result of this. For this reason, I want to use the transmit complete interrupt in the SPI module to trigger the start of conversion in the ADC. I presume that a similar procedure applies when using the end of conversion flag of the ADC to trigger the next SPI word transfer.

Is it necessary to route the output interrupt and SOC bits to GPI pins, or can the connection be made in software? If the latter, could you suggest an example of this?

Thanks for reading

  • Hi Tim,

    ADC SOCs can be triggered by:

    There are no examples available for your type of implementation. You can surely try to implement  "S/W - software immediate start" wrt to CAN interrupt.

    Regards,

    Gautam

  • Hi Tim,

    I don't think that you will want to (or even be able to) bring these interrupt bits out to a pin.  I think your application flow will be something like this:

    *Send SPI message.

    *On SPI message complete, trigger SPI ISR

    *In SPI ISR, send software trigger to ADC

    *End of ADC conversions triggers ADC ISR

    *In ADC ISR, read ADC results, perform any necessary calculations, determine next SPI message, send SPI message 

    (everything repeats from here)

  • Hi Devin,

    Thanks for reading. Your response makes sense to me, but I am unsure how an ISR works. From your response it seems that, like an ADC, or CAN module, it has to be initialised if used in a project, and is a generic piece of hardware which can be set up to handle the interrupt output of one component and in turn send an interrupt to another. Is this correct, or am I still off?

    Thanks,

    Tim

  • Hi Gautam, 

    Thanks for your suggestion. I have a quick question about this-why in particular do you suggest that I use a CAN interrupt?

    Thanks,

    Tim

  • Tim,

    The ISR has a hardware trigger which invokes a piece of software.  Execution for your program will being in the main() function.  This will execute until an interrupt occurs (via some hardware event, e.g. a SPI message is received).  Once the interrupt is received, the CPU will undergo a "context switch" where the execution state is saved and the CPU then begins executing from the address of the interrupt service routine (ISR).  The ISR is just a function declared at the same level as main().  When the ISR is complete, execution resumes in main. 

    When I say something like:

    *In SPI ISR, send software trigger to ADC

    I mean to have software that looks something like this:

    interrupt void SPI_complete(void){

        <do any SPI cleanup on message complete>

        <send software trigger to ADC>

        <acknowledge interrupt flag>

    }

    And you would also have some initializations somewhere at the beginning of your main() function that setup the SPI to trigger an interrupt on message complete, and enable the interrupt paths from the SPI through the PIE to the CPU (follow the template in the ControlSUITE examples and also read the SPI module documentation)

     

  • Devin,

    Thanks for that explanation.  One last question: when you say intializations, these generally involve setting the control registers of the SPI and ADC?

    Tim

  • Tim,

    Yeah, you will want to read the SPI and ADC module documentation, then start from one of the working ControlSUITE examples and incrementally modify the register settings until you get the desired behavior.  

  • Hi Devin,

    I have a number of questions regarding various potential interrupts generated by the SPI module.

    The simplest means of triggering the ADC, to my mind is to put in place an isr, spi_isr as shown below, which would issue a SOC command to the ADC in software.  I have tried to implement this, without including the software ADC trigger, by inserting the following code snippets into the spi_loopback code provided in loopback. In the main file, I disabled the loopback mode.

    interrupt void spi_isr(void);

    EALLOW; 
    PieVectTable.SPITXINTA = &spi_isr;
    EDIS; 

    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
    IER |= M_INT1; // Enable CPU Interrupt 1
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM

    interrupt void spi_isr(void)
    {

    }

    I inserted a break point inside the interrupt function, and my main function involves the SPI transmitting a range of numbers from 0 to 2^16-1 and starting again. Each time a transmit occurs, I would expect the code to pause at the breakpoint in teh interrupt description but it has not. Can anybody suggest what I may be leaving out?

    In addition, is there a way of mapping the SPITXINTA directly to ADCCTRL2.SOC_SEQ1?

    Lastly, an unlikely solution is that a reasonably reliable indicator of the SPI having transmitted seems to be the SPIFFRX.RXFFST bit, which changes state during a transmission. This bit should indicate whether the number of words in the receiver buffer, which should not change. However, when I try to repeat this with SPIFFTX.TXFFST, the bit does not change. Can anyone explain this?

    Thanks,

    Tim

  • Tim,

    May I ask what device you are using? 

    Here are some ideas for you to try out in the meantime:

    Tim Cronin said:
    I inserted a break point inside the interrupt function, and my main function involves the SPI transmitting a range of numbers from 0 to 2^16-1 and starting again. Each time a transmit occurs, I would expect the code to pause at the breakpoint in teh interrupt description but it has not. Can anybody suggest what I may be leaving out? 

    It seems that in your code you are mapping the correct transmit interrupt, but you are enabling the wrong interrupt.

    Tim Cronin said:
     PieCtrlRegs.PIEIER1.bit.INTx6 = 1;

    This line actually is enabling ADCINT9! To enable the SPIA transmit interrupt, you want to enable Group 6, INT 2:

     PieCtrlRegs.PIEIER6.bit.INTx2=1;     // Enable PIE Group 6, INT 2

    If you have ControlSuite, you can reference the spi_loopback_interrupts example. This example shows the correct way to initialize and use SPI Interrupts.

    Tim Cronin said:
    In addition, is there a way of mapping the SPITXINTA directly to ADCCTRL2.SOC_SEQ1? 

    Unfortunately this is not possible. But inside of your ISR, you can directly write a 1 to this bit, and the conversion will start.

    I will need to look into your last question. Try the things I mentioned above, and I will get back to you regarding the  SPIFFTX.TXFFST not being changed.

    Regards, 

    Mark

  • Thank You for your suggestions, Mark. I am using the TMS320F28335, on the eZDSP evaluation kit from Spectrum Digital.