DSP 之中断控制(Interrupt):/*
* Copyright (C) 2004 Texas Instruments Incorporated
* All Rights Reserved
*/
#include
#include
/* mmc0 从cslmem中分配内存 */
#pragma DATA_SECTION(mmc0, "cslmem")
MMC_Handle mmc0;
MMC_CardObj *card, cardalloc;
MMC_CardIdObj *cid, cardid;
int retVal,count;
Uint16 rca;
Uint16 cardtype;
/* Because of different operating clock frequencies, the Init structure for c5509 *
* and c5509a have different values for memory and function clock divide down values */
#if CHIP_5509A
/* Native mode Initialization Structure
* 本机模式初始化
*/
MMC_SetupNative Init = {
0, /* disable DMA for data read/write */
0, /* Set level of edge detection for DAT3 pin */
0, /* Determines if MMC goes IDLE during IDLE instr */
1, /* Memory clk reflected on CLK Pin */
7, /* CPU CLK to MMC function clk divide down */
5, /* MMC function clk to memory clk divide down */
0, /* No. memory clks to wait before response timeout */
0, /* No. memory clks to wait before data timeout */
512, /* Block Length must be same as CSD */
};
#else
MMC_SetupNative Init = {
0, /* disable DMA for data read/write */
0, /* Set level of edge detection for DAT3 pin */
0, /* Determines if MMC goes IDLE during IDLE instr */
1, /* Memory clk reflected on CLK Pin */
3, /* CPU CLK to MMC function clk divide down */
3, /* MMC function clk to memory clk divide down */
0, /* No. memory clks to wait before response timeout */
0, /* No. memory clks to wait before data timeout */
512, /* Block Length must be same as CSD */
};
#endif
/* read with write function allocate in .text */
#pragma CODE_SECTION(read_interrupt,".text")
#pragma CODE_SECTION(write_interrupt,".text")
/* These are the interrupts to be called for each write and read */
void read_interrupt();
void write_interrupt();
/* *******************************************************************************
* How MMC interrupts work.
*
* MMC Registers for interrupts
* - MMCIE : MMC Interrupt Enable Register
* - MMCST0: MMC Status 0 Register
*
* Structures
* - MMC_CallBackObj : Has the call back table for interrupts for different
* MMC operations
*
* Functions
* - MMC_dispatch0 :
* - MMC_dispatch1 : Functions plugged in to service the MMC interrupt
* generated by the CPU
* - MMC_setCallBack : Sets the functions to be called as ISRs for MMC
* events (e.g. read, write interrupts) into the
* MMC_CallBackObj structure
* - MMC_intEnable : Write to the MMCIE to enable the interrupt for a
* particular MMC event
*
* Working
* The MMC device (in this case device 1) has an associated MMC_dispatch function
* (defined in mmc_disp1.c) which is the ISR. This is plugged in to service
* interrupts for the MMC. When an interrupt is triggered, the MMC_dispatch checks
* the MMCIE and MMCST0 and decodes which event (read, write, etc.) the MMC interrupt
* is triggered for and calls the service function for the event from the entries in
* the call back structure.
* ********************************************************************************** */
#pragma DATA_SECTION(cback, ".csldata");
/* Call back structure: This holds the functions to be called when an interrupt for a
* particular MMC event is triggered */
MMC_CallBackObj cback = {
(MMC_CallBackPtr)0x0000, /* Callback for Data Transfer Done */
(MMC_CallBackPtr)0x0000, /* Callback for Busy Done */
(MMC_CallBackPtr)0x0000, /* Callback for response Done */
(MMC_CallBackPtr)0x0000, /* Callback for Read-data time-out */
(MMC_CallBackPtr)0x0000, /* Callback for Response time-out */
(MMC_CallBackPtr)0x0000, /* Callback for write-data CRC error */
(MMC_CallBackPtr)0x0000, /* Callback for read-data CRC error */
(MMC_CallBackPtr)0x0000, /* Callback for response CRC error */
(MMC_CallBackPtr)0x0000, /* This is never used */
write_interrupt, /* Callback for data xmt ready */
read_interrupt, /* Callback for data rcv ready */
(MMC_CallBackPtr)0x0000 /* Callback for DAT3 edge */
} ;
volatile int reads_done = 0;
volatile int writes_done = 0;
Uint16 datasend[512];
Uint16 datareceive[512];
/* Function to be called on data receive ready */
void read_interrupt(void)
{
++reads_done;
return;
}
/* Function to be called on data transmit ready */
void write_interrupt(void)
{
++writes_done;
return;
}
void main()
{
Uint16 old_intm;
/* CSL libary initialize */
CSL_init();
/* Clear all interrupt register */
IRQ_globalDisable();
/* Set interrupt vector table */
IRQ_setVecs(0x10000);
printf ("
Starting interrupt test...
");
/* Fill in source and destination buffers */
for (count=0; count<=256; count++)
{
datasend[count] = count;
datareceive[count] = 0xFFFF;
}
/* Refer to mmc_setup example for explanation
* Reserves the MMC device as specified by device
*/
mmc0 = MMC_open(MMC_DEV1);
/* Native mode Initialization Structure */
MMC_setupNative(mmc0,&Init);
/* Sends a broadcast GO_IDLE command */
MMC_sendGoIdle(mmc0);
for (retVal=0; retVal<4016; retVal++)
asm(" NOP");
/* Sets the operating voltage window while in Native mode
* 设置操作电压窗口,为本机模式
*/
cardtype = MMC_sendOpCond(mmc0,0x00100000);
if (cardtype == 0xFFFF){
printf ("Card not recognized
");
exit(0);
}
if (cardtype == MMC_CARD){
cid = &cardid;
/* Sends a broadcast command to all cards to identify themselves */
MMC_sendAllCID(mmc0,cid); // get the CID structure for all cards.
card = &cardalloc;
/* Sets the relative card address of an attatched memory card */
retVal = MMC_setRca(mmc0,card,10);
} else {
cid = &cardid;
/* Sends a broadcast command to all cards to identify themselves */
SD_sendAllCID(mmc0,cid); // get the CID structure for all cards.
card = &cardalloc;
/* Sets the relative card address of an attatched memory card */
rca = SD_sendRca(mmc0,card);
printf ("RCA sent is 0x%x
", rca);
}
/* Refer to mmc_setup example for explanation of the above code */
/* Fill in the handle's callback function structure with contents of the cback *
* structure. These will be the functions called when the MMC interrupt occurs
* 给中断安装调度程序
*/
MMC_setCallBack(mmc0, &cback);
/* Write to the MMCIE register to enable interrupts for particular events
* 0x200 enables an interrupt on data transmit ready
* Enables interrupts by writing to the MMCIE register
*/
MMC_intEnable(mmc0, 0x200);
/* IRQ Enable interrupt register */
IRQ_globalEnable();
/* pick the card to transfer data to/from */
retVal = MMC_selectCard(mmc0, card);
/* start data write. mmc_read_write example provides a more detailed explanation */
printf ("Writing data to card...
");
/* Writes a block of data to a pre-selected memory card */
retVal = MMC_write(mmc0, /* MMC Handle returned by call to MMC_open */
0x00000000,/* Address on card where read begins */
datasend, /* Pointer to buffer where received data should be stored */
512); /* number of bytes to store in buffer */
for (retVal = 0; retVal <= 256; ++retVal)
asm(" NOP");
/* Globally disables interrupts */
old_intm = IRQ_globalDisable();
/* Enable interrupts for data recieve ready now */
MMC_intEnable(mmc0, 0x400);
/* Restores the global interrupt mask state */
IRQ_globalRestore(old_intm);
/* delay before we start reading the data */
for (retVal = 0; retVal <= 25000; ++retVal)
asm(" NOP");
for (retVal = 0; retVal <= 25000; ++retVal)
asm(" NOP");
#if CHIP_5509A
/* This requires a longer delay */
for (retVal = 0; retVal <= 25000; ++retVal)
asm(" NOP");
for (retVal = 0; retVal <= 25000; ++retVal)
asm(" NOP");
#endif
printf ("Reading data from card...
");
/* Reads a block of data from a pre-selected memory card */
retVal = MMC_read(mmc0,0x00000000,datareceive,512);
/* check if data has been tranmitted and received correctly */
for (count = 0; count < 256; ++count)
if (datasend[count] != datareceive[count])
break;
if (count < 256)
printf ("
Not all data was transferred/read successfully!
");
else
printf ("
Data transfer successful
");
if (writes_done != 256)
printf ("Not all data writes triggered interrupts
");
else
printf ("Interrupts triggered for each data transmit ready
");
if (reads_done != 256)
printf ("Not all data reads triggered interrupts
");
else
printf ("Interrupts triggered for each data receive ready
");
if ((reads_done == 256) && (writes_done == 256))
printf ("TEST PASSED");
else
printf ("TEST FAILED");
}