⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 load.c

📁 数码投影仪,包含电路,RS232通信,远程控制
💻 C
字号:
//=============================================================================
// Filename:     load.c
//
// Description:  Functions needed to load a program and start it on the DSP.
//
// Copyright (C) 2000 - 2002 Texas Instruments Incorporated
//
//============================================================================


#include "arm_boot.h"
#include "dsp_boot_code.h"


//============================================================================
// Function:		WriteAPI()
//
// Description:		This function copies one word into the API memory.  
//
//============================================================================
static void WriteAPI(volatile unsigned short *Address, unsigned short Data)
{
    *Address = Data;
}


//=============================================================================
// Function:    move_bits()
//
// Description:   Helper function for dsp_load().  Copy contents of bits_ary
// to a buffer in API memory.  When the buffer becomes full, sinal to DSP via 
// a handshake flag to read the bits from the buffer.
//
//=============================================================================
static int move_bits(volatile unsigned short *handshake_flag, 
                     const unsigned short *bits_ary)
{	
    volatile unsigned short *api_buffer  = (unsigned short*)
               MAP_DSP_TO_ARM(API_BUF_START);  // start of the API buffer 
	unsigned short  		 api_offset  = 0;  // offset into API memory
	unsigned short		     code_offset = 0;  // offset into DSP Code ary
	unsigned short		     done        = 0;  // flag to signal done.
	long 	                 time_cnt;         // loop index used for timeout
	unsigned short		     i;			  

    // Need outer loop in case program is larger than can be loaded	in one pass
	while (done == 0) {
        // If the current section is not empty and there is enough buffer
        // space left to write this section out, copy the section to API.

        // code_offset should be pointing to the number of words
        // in the this section.  We need to have room for all of them,
        // plus one for the count, plus one for the target address, plus
        // one for the zero termination word.
        unsigned short section_length = bits_ary[code_offset] + 2;
        int empty_section  = (bits_ary[code_offset] == 0); 
        int buffer_full    = ((api_offset + section_length + 1) >=
                              API_BUF_LENGTH); 
        if ((!empty_section) && (!buffer_full)) {
            for(i = 0; i < section_length; i++) {
                WriteAPI(&api_buffer[api_offset++], bits_ary[code_offset++]);
            }
        }
        else {
            // Either this is the end of the bits_ary, or there wasn't enough
            // buffer space.  In both cases moves the bits we have so far to
            // the DSP.

            // Tack on a 0 to signal the end of the section. 
            WriteAPI(&api_buffer[api_offset], 0);

            // Signal for DSP to read what we have so far.  
            WriteAPI(handshake_flag, 1);

            time_cnt = 0;
            while ((*handshake_flag == 1) && (++time_cnt < TIME_OUT_COUNT)) {
                // Wait for DSP to finish.  The DSP sets *handshake_flag
                // to zero after it finishes the section it's writing.
            }

            // Check if timeout occurred.
            if (time_cnt == TIME_OUT_COUNT) return LOAD_TIME_OUT;

            // Reset pointer for next section
            api_offset = 0;

            if (empty_section) {
                // Reached the end of the bits array
                done = 1;
            }
        }
    }

    return LOAD_OK;
}


//=============================================================================
// Function:    dsp_load()
//
// Description:   
//
// This function loads the DSP code and data .  It does this as
// a three stage process:
//    1) It loads the DSP Bootloader into API memory.  
//    2) The ARM and DSP Bootloader load the DSP Code a chunk at a time using a
//       small section of API memory.  
//    3) The ARM and DSP Bootloader load the DSP data a chunk at a time using
//       a small section of API memory. 
//
//=============================================================================
int dsp_load(dsp_app_struct *dsp_app)
{
    unsigned short		      code_offset;   // Curr. offset into DSP Code ary
    unsigned short		      section_length;// Number of words in each section
    long 	                  time_cnt;      // Loop index used for timeout
    unsigned short           *section_addr;
    unsigned short		      i;
    int                       status = LOAD_OK;

    volatile unsigned short *dsp_ready      = (unsigned short*)DSP_READY;
    volatile unsigned short *prog_buf_ready = (unsigned short*)PROG_BUF_READY;
    volatile unsigned short *data_buf_ready = (unsigned short*)DATA_BUF_READY;
    volatile unsigned short *copy_done      = (unsigned short*)COPY_DONE;
    volatile unsigned short *pmst           = (unsigned short*)PMST_VAL;

    volatile long  *clkm_cntl_reset = (long *)0xffff2f10;
    volatile long  *dsp_reg         = (long *)0xffff2f04;

    // put DSP In Reset
    *clkm_cntl_reset |= 0x1;  //set bit1, DSP XF LED will turn on

    // set DSP in API boot mode and microcomputer mode
    *dsp_reg &= ~0x0600; //clear bits 9 and 10

    // clear the handshaking registers
    WriteAPI(dsp_ready,   0);		// The DSP is still in API mode.
    WriteAPI(prog_buf_ready,  0);	// Prog is not ready to load.
    WriteAPI(data_buf_ready,  0);   // Data is not ready to load.
    WriteAPI(copy_done,  0);	    // We're not done.
	
    // set the PMST for the DSP Exec to setup the memory map during bootload
    WriteAPI(pmst, dsp_app->pmst); 

    // copy DSP Bootloader to API Ram
    code_offset=0;				// Current offset into DSP Program array
    section_length = dsp_boot_program[code_offset++];
    while(section_length != 0) {
        section_addr = (unsigned short *)
                            (MAP_DSP_TO_ARM(dsp_boot_program[code_offset++])); 
        // copy this section
        for (i = 0; i < section_length; i++) {
            WriteAPI(section_addr++, dsp_boot_program[code_offset++]);
        }
        // get next section's length
        section_length = dsp_boot_program[code_offset++];
    }

    // take the DSP out of reset
    *clkm_cntl_reset &= ~0x1; //clear bit 1

    time_cnt = 0;
    while ((*dsp_ready == 0) && (++time_cnt < TIME_OUT_COUNT)) {
        // Wait for DSP to finish.  The DSP sets *dsp_ready to 1 after it
        // switches from API boot mode to normal boot mode.
    }

    // Check if timeout occurred.
    if (time_cnt == TIME_OUT_COUNT) return LOAD_TIME_OUT;

    status = move_bits(prog_buf_ready, dsp_app->pprogram);
    if (status == LOAD_TIME_OUT) return status;

    status = move_bits(data_buf_ready, dsp_app->pdata);

    return status;
}



//============================================================================
// Function:    dsp_start()
//
// Description:   This function starts the DSP running following a dsp_load
//
//============================================================================
void dsp_start(void)
{
    // Write the register telling the DSP that the bootload is done. =====
    volatile unsigned short *copy_done = (unsigned short *)COPY_DONE;
    WriteAPI(copy_done, 1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -