/********************************************************************** * Function: loadDSP * * The loadDSP routine will take a COFF (COMMON OBJECT FILE FORMAT) * formatted file and load it into the DSP memory. The COFF file is * the format outputed by the lnk3x.exe linker program. * * The "message" parameter must be pointer to an EXISTING block of * of memory which is defined as type char. This is used to return * error messages back to the calling program. This routine will * allocate the memory for you if "message" is a NULL pointer. However, * you will be responsible for returning the memory to the heap by * calling a free(); * * You may alternatively convert all the sprintf statements to printf * if you want the error messages displayed to the standard output. * Then you may remove the "message" parameter completely. * * This routine returns 1 for success 0 otherwise. ***********************************************************************/ int loadDSP(const char *fName, char *message) { int section, m; U32 load_address; FILE *fpin; File_Header file_header; Section_Header section_header[MAX_SECTIONS]; long ssize; // section size int subsections; int i; // loop counter U32 *image_ptr; // pointer to section_image U32 section_image[MAX_SECTION_IMAGE_SIZE]; if(!message) message = (char *)calloc(1024,sizeof(char)); if((fpin=fopen(fName,"rb"))==NULL) { sprintf(message,"Can't open %s for read\n",fName); return(RETURN_ERROR); } if(fread(&file_header,sizeof(file_header),1,fpin) !=1) { sprintf(message,"Error reading %s",fName); return(RETURN_ERROR); } if(file_header.magic != 0x0093) { fclose(fpin); sprintf(message,"Invalid input file type"); return(RETURN_ERROR); } if(file_header.opt_head_size != 0) { fseek(fpin, file_header.opt_head_size, SEEK_CUR); } for(section=0;section<(int)file_header.num_sec;section++) { if(fread(§ion_header[section],sizeof(section_header[0]),1,fpin) != 1) { sprintf(message,"Error reading section header from %s\n",fName); return(RETURN_ERROR); } } for(section=0;section<(int)file_header.num_sec;section++) { if(section_header[section].flags != STYP_BSS) { if(fseek(fpin,section_header[section].raw_data_pointer,0)) { sprintf(message,"Seek error in file %s\n",fName); return(RETURN_ERROR); } load_address=section_header[section].physical_address; m=fread(section_image,sizeof(unsigned long),(int)section_header[section].size,fpin); if(m != (int)section_header[section].size) { sprintf(message,"Only read %d words. Should be %d words.\nError reading raw data from section %s", m,(int)section_header[section].size,section_header[section].name); return(RETURN_ERROR); } if(ssize=section_header[section].size>0) { subsections = ceil(ssize/DPRAM_USER_SIZE); image_ptr = section_image; for (i=0;i DPRAM_USER_SIZE) { printf("\nSection: %d Subsection: %d\nLoad address: %x\nSize: %x\n", section,i,load_address,DPRAM_USER_SIZE); writeDSPMem(load_address, DPRAM_USER_SIZE, image_ptr); ssize -= DPRAM_USER_SIZE; // decrememnt total size image_ptr += DPRAM_USER_SIZE; // increment pointer to next subsection load_address += DPRAM_USER_SIZE; // increment load address } else // last subsection { printf("\nSection: %d Subsection: %d\nLoad address: %x\nSize: %x\n", section,i,load_address,ssize); writeDSPMem(load_address, ssize, image_ptr); } } // end for } } } fclose(fpin); return RETURN_SUCCESS; } // end load DSP function