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.

interrupt routine is not called after enabling interrupt of McSPI

Update: This problem was resolved with "-fno-zero-initialized-in-bss" flag during compile time.

=======================================

Hi,

I'm trying to use McSPI in beaglebone. I copied and pasted evmAM35x's mcspiFlash.c. I removed all Flash related parts. Then I commented out EVMProfileGet(); from mcspi.c and just assgined '2' to 'profile' in mcspi.c. I did this because EVMProfileGet() seems to perform I2C initialization in EVM and doesn't seem to related to McSPI (or is it?).

Now, the compilation is OK (both Debug and Release mode). But the system does not produce interrupt. I put UARTPuts in the McSPIIsr() to see if this service routine is ever called. But no text was seen. Could you help me to figure out? (Or is it really related to EVMProfileGet(); function? Then, how can I simplify for beaglebone?)

Thank you very much for your help in advance.

=========================

BTW, the output of the following code looks like...

*********************
sending data...

Raw status get 0
pending irq masked status get 0
**********************

==============================================

/* Include the necessary header files */

#include "soc_AM335x.h"
#include "beaglebone.h"
#include "interrupt.h"
#include "uartStdio.h"
#include "hw_types.h"

#include "mcspi.h"
#include "hw_control_AM335x.h"
#include "hw_cm_per.h"


#define MCSPI_OUT_FREQ (24000000u)
#define MCSPI_IN_CLK (48000000u)

/******************************************************************************

** INTERNAL FUNCTION PROTOTYPES
******************************************************************************/
static void McSPITransfer(void);
static void McSPIIsr(void);


/******************************************************************************
** GLOBAL VARIABLE DEFINITIONS
******************************************************************************/
volatile unsigned int flag = 1;
unsigned int chNum = 0;
unsigned char txBuffer[260];
unsigned char rxBuffer[260];
unsigned char *p_tx;
unsigned char *p_rx;
unsigned int length = 0;

/******************************************************************************
** INTERNAL FUNCTION DEFINITIONS
******************************************************************************/

int main(void) {


McSPI0ModuleClkConfig(); 
McSPIPinMuxSetup(0);
McSPI0CSPinMuxSetup(chNum); 


/* McSPI Setup */

McSPIReset(SOC_SPI_0_REGS); 
McSPICSEnable(SOC_SPI_0_REGS); 
McSPIMasterModeEnable(SOC_SPI_0_REGS); 
McSPIMasterModeConfig(SOC_SPI_0_REGS, MCSPI_SINGLE_CH, MCSPI_TX_RX_MODE, MCSPI_DATA_LINE_COMM_MODE_1,chNum); 
McSPIClkConfig(SOC_SPI_0_REGS, MCSPI_IN_CLK, MCSPI_OUT_FREQ, chNum,
MCSPI_CLK_MODE_0); 
McSPIWordLengthSet(SOC_SPI_0_REGS, MCSPI_WORD_LENGTH(8), chNum); 
McSPICSPolarityConfig(SOC_SPI_0_REGS, MCSPI_CS_POL_LOW, chNum); 
McSPITxFIFOConfig(SOC_SPI_0_REGS, MCSPI_TX_FIFO_ENABLE, chNum); 
McSPIRxFIFOConfig(SOC_SPI_0_REGS, MCSPI_RX_FIFO_ENABLE, chNum);


/* Map McSPI Interrupts to AINTC */
IntAINTCInit();

IntRegister(SYS_INT_SPI0INT, McSPIIsr);
IntPrioritySet(SYS_INT_SPI0INT, 1, AINTC_HOSTINT_ROUTE_IRQ); 
IntSystemEnable(SYS_INT_SPI0INT);

 IntMasterIRQEnable();



UARTPuts("sending data... \n\r",-1);
txBuffer[0] = 0x03;
txBuffer[1] = 0x80; ; // 0x80 to program baud rate
length = 2;
McSPITransfer();

while(1);
return -1;
}

/*
** This function will activate/deactivate CS line and also enable Tx and Rx
** interrupts of McSPI peripheral.
*/
static void McSPITransfer(void) {
p_tx = txBuffer;
p_rx = rxBuffer;

McSPICSAssert(SOC_SPI_0_REGS, chNum); /* SPIEN line is forced to low state.*/
McSPIIntEnable(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum) | MCSPI_INT_RX_FULL(chNum)); /* Enable the Tx/Rx interrupts of McSPI.*/
McSPIChannelEnable(SOC_SPI_0_REGS, chNum); /* Enable the McSPI channel for communication.*/


unsigned int kkk;
kkk = (unsigned int)IntRawStatusGet(SYS_INT_SPI0INT);
UARTprintf("Raw status get %d\n\r", kkk);
unsigned int lll;
lll = (unsigned int) IntPendingIrqMaskedStatusGet(SYS_INT_SPI0INT);
UARTprintf("pending irq masked status get %d\n\r",lll);

/* Wait until control returns back from McSPI ISR.*/
while(flag);
flag = 1;

UARTPuts("DeAssert\n\r",-1);
McSPICSDeAssert(SOC_SPI_0_REGS, chNum); /* Force SPIEN line to the inactive state.*/
UARTPuts("ChannelDisable\n\r",-1);
McSPIChannelDisable(SOC_SPI_0_REGS, chNum); /* Disable the McSPI channel.*/
}


/*
** McSPI Interrupt Service Routine. This function will clear the status of the
** Tx/Rx interrupts when generated. Will write the Tx data on transmit data
** register and also will put the received data from receive data register to
** a location in memory.
*/
static void McSPIIsr(void)
{
unsigned int intCode = 0;

UARTPuts("Int StatusGet\n\r",-1);                <<<<<====== I want to see this string.
intCode = McSPIIntStatusGet(SOC_SPI_0_REGS);

UARTprintf("intCode = %d\n\r", intCode);
while(intCode){
     if(MCSPI_INT_TX_EMPTY(chNum) == (intCode & MCSPI_INT_TX_EMPTY(chNum))) {
        McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));
        length--;
        McSPITransmitData(SOC_SPI_0_REGS,(unsigned int)(*p_tx++), chNum); /* McSPI transmit */
        if(!length) {
            McSPIIntDisable(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));

            McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_TX_EMPTY(chNum));
        }
    }

    if(MCSPI_INT_RX_FULL(chNum) == (intCode & MCSPI_INT_RX_FULL(chNum))) {
        McSPIIntStatusClear(SOC_SPI_0_REGS, MCSPI_INT_RX_FULL(chNum));
        *p_rx++ = (unsigned char) McSPIReceiveData(SOC_SPI_0_REGS, chNum); /* McSPI receive */
        if(!(length)) {
            McSPIIntDisable(SOC_SPI_0_REGS, MCSPI_INT_RX_FULL(chNum));
            flag = 0;
        }
    }
    UARTprintf("intCode in while = %d\n\r", intCode);
    intCode = McSPIIntStatusGet(SOC_SPI_0_REGS);
}
}

/********************************* End Of File ******************************/

  • Hi,

    Since I haven't got it working by myself, I want to change my question to more pragmatically approach this issue.

    1. How can I check a particular clock module is working properly? Is it enough to check the bit of the clock register? Or is there a function for it? Is there any other way to indirectly check its behavior?

    2. How can I check if an interrupt routine is properly set and work as advertised? In particular, how can I check the SPI rx/tx buffer related interrupt setting is actually functioning? Or is there any indirect way to probe it (like directly triggering the interrupt or something like that)?

    Thank you.

  • Hi Sang,

    EVMProfileGet() function is not required for beaglebone. The code running on evmAM335x was using the profileGet function because the SPI flash was present on a daughter board and SOC resides on the base board. To access the SPI flash we have to set the profile to 2.

    However the sequence followed by you seems to be correct to generate the interrupts.

    To check the clocks you can follow this procedure -

    1) Connect to the target  via CCS.

    2) Check the memory map of McSPI registers before and after executing McSPIModuleClkConfig() function. Before executing one can see the memory block as a bad block. After execution one can see the reset values of the registers.

    3) Try writing to any writable register(directly in the memory window). If the value gets reflected then clocks are properly configured for McSPI.

    To check whether interrupts are enabled you can check the memory block of the interrupt register(check for the corresponding bit whether set or not) 

     

    Regards,

    Jeethan

  • Hi Jeethan,

    Thank you very much for your suggestion.

    I opened CSSv5, compiled and first tried to run without using target connection, because it is super-slow. (Is it common? The connection takes several minutes to boot-up the device and takes so much time to execute a single line of code. I'm using CSSv5 in Ubuntu as VBox guest in Windows 7 Host.)
    Anyway, it ran fine. It got into the interrupt without problem. I did not even have to debug.

    Now, a bit different story...

    So, the source of problem was collision between StarterWare and the CodeSourcery tool chain. I was using arm-2012.03-56-arm-none-eabi.bin version. So, I tested with the TI provided 2009.q1-161 version. But it didn't work either.

    Somehow, CodeSourcery does not match well enough with StarterWare (another ex is the 'app' name problem with strcat() in bootloader routine), which is a bit annoying, because CSS is, essentially, not free. 

    Anyway, because I cannot debug the hardware using CodeSourcery, it won't be easy to track down what the difference is... So, I might have to go back and stick with CSS. Or, is there any way to download TMS470 compiler/assembler only and use them just like CodeSourcery? I can't find any way to do that.

    Thanks a lot.
    SG 

  • Hi Sang,

    1) Beaglebone has an onboard Emulator(xds100v2) and it is bit slower when compared to other emulators like xds510, xds560. Hence loading the executable and also debugging will take time when compared to other emulators.

    2) From your other query what i can understand is you are not able to put breakpoints in the source code. This is because since we have compiled the code using CodeSourcery and load it via CCS, CCS is not able to recognize the debug information and hence it wont allow the user to put breakpoints. But CCS does allow the user to put breakpoints in disassembly.

    For e.g. you want to put a breakpoint for McSPIIsr(). Then copy McSPIIsr at the disassembly search window and put a breakpoint there which will get applied.

    Hope this answers your queries.

    Regards,

    Jeethan

  • Hi Jeethan,

    Thank you for your information. I'll try disassembling.

    BTW, it was working properly with 2009q1 version after I rebooted my computer.

    And, the problem with the 2012.03 CodeSourcery was resolved this morning, too. I read a post about UARTprintf problem for the old StarterWare last night. He solved it with "-fno-zero-initialized-in-bss" flag. And, today, magically it solved my problem as well. So, it seems to be a collision of a certain convention between StarterWare (or AM335x?) and CodeSourcery in utilizing a BSS section. Then, there could be other similar problems,,, I guess.

    Anyway, thank you very much for your help.
    SG 

  • FWIW, I stepped through the BSS initialization and saw that _bss_end was too small.  The following fixed it for me (without using -fno-zero-initialized-in-bss):

    In your application linker script (<app>.lds), change:

    .bss :
    {
            *(.bss)
    }

    to 

    .bss :
    {

            *(.bss .bss.*)
    }