AnsweredAssumed Answered

Problem with SPORT Interrupt - Blackfin BF533 processor

Question asked by ndquangr on Jan 25, 2012
Latest reply on Jan 27, 2012 by PrasanthR


I recently started to work with eval-bf5xx board, cm-bf533 and audio extension board. Because I am new with embedded system programming so there are some problems I could not solve although I have refered to many blackfin documents.

Firstly I want to describe detaily my problem. I have modified the audio talkthough tdm code for bf533 to push data obtained from microphones to a data buffer every SPORT interrupt. I only modify the interrupt handler, not other settings or code.


This is initialize_bf533.c file, just the same with original file:



#include "Talkthrough.h"
#include "parameter.h"
// Function:     Init1836()                                                                 //
//                                                                                               //
// Description:     This function sets up the SPI port to configure the AD1836. //
//                    The content of the array sCodec1836TxRegs is sent to the      //
//                    codec.                                                                      //
void Init1836(void)
int j;
// Enable PF5
// Set baud rate SCK = HCLK/(2*SPIBAUD) SCK = 2MHz
*pSPI_BAUD = 16;
// configure spi port
// SPI DMA write, 16-bit data, MSB first, SPI Master
// Set up DMA5 to transmit
// Map DMA5 to SPI
*pDMA5_PERIPHERAL_MAP     = 0x5000;
// Configure DMA5
// 16-bit transfers
// Start address of data buffer
*pDMA5_START_ADDR = (void *)sCodec1836TxRegs;
// DMA inner loop count
// Inner loop address increment
*pDMA5_X_MODIFY = 2;
// enable DMAs
// enable spi
*pSPI_CTL = (*pSPI_CTL | SPE);
// wait until dma transfers for spi are finished
for (j=0; j<0xaff0; j++) asm("nop;");
// disable spi
*pSPI_CTL = 0x0000;
// Function:     Init_Sport0                                                                 //
//                                                                                               //
// Description:     Configure Sport0 for TDM mode, to transmit/receive data      //
//                    to/from the AD1836. Configure Sport for external clocks and //
//                    frame syncs.                                                            //
void Init_Sport0(void)
// Sport0 receive configuration
// External CLK, External Frame sync, MSB first
// 32-bit data
*pSPORT0_RCR2 = SLEN_32;
// Sport0 transmit configuration
// External CLK, External Frame sync, MSB first
// 24-bit data
*pSPORT0_TCR2 = SLEN_32;
// Enable MCM 8 transmit & receive channels
*pSPORT0_MTCS0 = 0x000000FF;
*pSPORT0_MRCS0 = 0x000000FF;
// Set MCM configuration register and enable MCM mode
*pSPORT0_MCMC1 = 0x0000;
*pSPORT0_MCMC2 = 0x101c;
// Function:     Init_DMA                                                                 //
//                                                                                               //
// Description:     Initialize DMA1 in autobuffer mode to receive and DMA2 in     //
//                    autobuffer mode to transmit                                             //
void Init_DMA(void)
// Set up DMA1 to receive
// Map DMA1 to Sport0 RX
// Configure DMA1
// 32-bit transfers, Interrupt on completion, Autobuffer mode
// Start address of data buffer
*pDMA1_START_ADDR = (void *)iRxBuffer1;
// DMA inner loop count
//*pDMA1_X_COUNT = 8;
// Inner loop address increment
*pDMA1_X_MODIFY     = 4;
// Set up DMA2 to transmit
// Map DMA2 to Sport0 TX
// Configure DMA2
// 32-bit transfers, Autobuffer mode
// Start address of data buffer
*pDMA2_START_ADDR = (void *)iTxBuffer1;
// DMA inner loop count
//*pDMA2_X_COUNT = 8;
// Inner loop address increment
*pDMA2_X_MODIFY     = 4;
// Function:     Init_Interrupts                                                            //
//                                                                                               //
// Description:     Initialize Interrupt for Sport0 RX                                   //
void Init_Sport_Interrupts(void)
// using the adi interrupt manager
// get the IVG
unsigned long nCurrentIVG;
adi_int_SICGetIVG(ADI_INT_DMA1_SPORT0_RX, &nCurrentIVG);
//printf("current ivg: %d", nCurrentIVG);
// hook the sport0 rx interrupt handler
adi_int_CECHook(nCurrentIVG, SPORT0RxHandler, NULL, FALSE);
adi_int_SICWakeup(ADI_INT_DMA1_SPORT0_RX, TRUE);
// Function:     Enable_DMA_Sport                                                       //
//                                                                                               //
// Description:     Enable DMA1, DMA2, Sport0 TX and Sport0 RX                         //
void Enable_DMA_Sport0(void)
// enable DMAs
// enable Sport0 TX and RX
*pSPORT0_TCR1      = (*pSPORT0_TCR1 | TSPEN);
*pSPORT0_RCR1      = (*pSPORT0_RCR1 | RSPEN);

Then I moved the SPORT0RxHandler to main.c to use a variable which I create to manager data buffer.


static RTDataState *rt;


void main(void)


rt = rt_data_state_init(FRAME_SHIFT, WINDOW_LEN, FRAME_SHIFT);


// initialize the interrupt manager

adi_int_Init( intmgr_storage, sizeof(intmgr_storage), &response_count, &critical_reg);











         // Pop data from circular buffer

         rt_data_pop(rt, data_mic_1, data_mic_2, data_mic_3);





ADI_INT_HANDLER_RESULT SPORT0RxHandler(void *pa_pClientArg)


int i, i_frame;



#if defined (__ADSPBF533__)

// clear interrupt flag

*pDMA1_IRQ_STATUS = 0x0001;

#elif defined (__ADSPBF537__)

*pDMA3_IRQ_STATUS |= 0x0001;

#elif defined (__ADSPBF561__)

*pDMA2_0_IRQ_STATUS |= 0x0001;


#error "processor not yet supported"


for(i=0; i<FRAME_SIZE; i++)


      i_frame = i << 3;     // x FRAME_SIZE   

      // copy input data from dma input buffer into variables

      iChannel0LeftIn[i]  = iRxBuffer1[INTERNAL_ADC_L0 + i_frame];

      iChannel0RightIn[i] = iRxBuffer1[INTERNAL_ADC_R0 + i_frame];

      iChannel1LeftIn[i]  = iRxBuffer1[INTERNAL_ADC_L1 + i_frame];

      iChannel1RightIn[i] = iRxBuffer1[INTERNAL_ADC_R1 + i_frame];





      rt_data_push(rt, iChannel0LeftIn,iChannel0RightIn,iChannel1LeftIn);





I have remove some pieces of code in above 2 functions (for power management service and measure sampling rate) because I think they do not relate to my purpose. (The problem is not different if I do not remove them).


RTDataState is my class to manage data buffer with the funtions rt_data_push (push data to buffer), rt_data_pop (pop data from buffer), rt_data_IS_AVAILABLE (check if data is available).


Now, the problem is:

I put a breakpoint at the line while(rt_data_IS_AVAILABLE(rt)) in the while loop inside main function. When I debug, the program stop there, but when I press F11 with the hope it will run into rt_data_IS_AVAILABLE function, it strangely run into _adi_int_NonNestingISR function in adi_int_asm.asm and then run to SPORT0RxHandler. I remove breakpoint and put printf function in  three functions rt_data_push, rt_data_pop, rt_data_IS_AVAILABLE, the console alway print out the text I put inside rt_data_push (in interrupt handler), never print out the text in two other functions.


I am not familiar with embedded system programming, so I do not understand this situation.

Please explain for me why it always run interrupt handler and show me the way to solve it. I'm in a hurry so I need your help very much. I have attached my project in this post.

Thank you in advance!