examples/google_voice_assistant/main/wmfwparse.cpp
/*
 *  Function: ProcessNextCoeffBlock
 * 
 *  @brief  Processes a coefficient block of the .bin file and writes it to the device if appropriate.
 * 
 *  @param  binFile    Open handle to file to process
 * 
 *  @retval WMFW_SUCCESS            Succeeded
 *  @retval WMFW_BAD_FILE_FORMAT    Couldn't parse block
 *  @retval WMFW_COMMS_ERROR        Write failed
 *  @retval WMFW_END_OF_FILE        Reached the end of file
 * 
 */


@brief  Processes a coefficient block of the .bin file and writes it to the device if appropriate.

@param  binFile    Open handle to file to process

@retval WMFW_SUCCESS            Succeeded
@retval WMFW_BAD_FILE_FORMAT    Couldn't parse block
@retval WMFW_COMMS_ERROR        Write failed
@retval WMFW_END_OF_FILE        Reached the end of file
@brief Processes a coefficient block of the . bin file and writes it to the device if appropriate . @param binFile Open handle to file to process @retval WMFW_SUCCESS Succeeded @retval WMFW_BAD_FILE_FORMAT Couldn ' t parse block @retval WMFW_COMMS_ERROR Write failed @retval WMFW_END_OF_FILE Reached the end of file
int ProcessNextCoeffBlock(FILE *binFile)
{
	WMFW_STATUS     status = WMFW_SUCCESS;
	BinCoeffBlockHeader blockHeader = { 0, 0, 0, 0, 0, 0 };
	AlgorithmIDBlockFormat *algorithmInfo = NULL;
	unsigned int    regionStart = 0;
	unsigned int	dataLength;
	unsigned char   *buffer = NULL;
	unsigned char   registersPerAddress;
	size_t amountRead = fread(&blockHeader, sizeof(blockHeader), 1, binFile);
	if (amountRead < 1)
	{
		status = WMFW_BAD_FILE_FORMAT;
		goto done;
	}
	dataLength = ((blockHeader.dataLength + 3) / 4) * 4;
	printf("\n");
	switch (blockHeader.region)
	{
#if defined(ADSP2)
	case WMFW_XM:
		printf("XM data block:\n");
		registersPerAddress = 2;
		algorithmInfo = FindMatchingAlgoBlock(blockHeader);
		if (NULL != algorithmInfo)
		{
			regionStart = xmBaseUnpacked + (algorithmInfo->algorithmXmBase * registersPerAddress);
		}
		break;
	case WMFW_YM:
		printf("YM data block:\n");
		registersPerAddress = 2;
		algorithmInfo = FindMatchingAlgoBlock(blockHeader);
		if (NULL != algorithmInfo)
		{
			regionStart = ymBaseUnpacked + (algorithmInfo->algorithmYmBase * registersPerAddress);
		}
		break;	
	case WMFW_ZM:
		printf("ZM data block:\n");
		registersPerAddress = 2;
		algorithmInfo = FindMatchingAlgoBlock(blockHeader);
		if (NULL != algorithmInfo)
		{
			regionStart = zmBase + (algorithmInfo->algorithmZmBase * registersPerAddress);
		}
		break;
#elif defined(HALOCORE)
	case WMFW_XM:
		printf("XM_UP24 data block:\n");
		registersPerAddress =4;
		algorithmInfo = FindMatchingAlgoBlock(blockHeader);
		if (NULL != algorithmInfo)
		{
			regionStart = xmBaseUnpacked + (algorithmInfo->algorithmXmBase * registersPerAddress);
		}
		break;
	case WMFW_YM:
		printf("YM_UP24 data block:\n");
		registersPerAddress = 4;
		algorithmInfo = FindMatchingAlgoBlock(blockHeader);
		if (NULL != algorithmInfo)
		{
			regionStart = ymBaseUnpacked + (algorithmInfo->algorithmYmBase * registersPerAddress);
		}
		break;
	case WMFW_XM_P:
		printf("XM Packed data block:\n");
		registersPerAddress = 3;
		algorithmInfo = FindMatchingAlgoBlock(blockHeader);
		if (NULL != algorithmInfo)
		{
			regionStart = (xmBasePacked + (algorithmInfo->algorithmXmBase * registersPerAddress)) & ~0x3; 
		}
		break;
	case WMFW_YM_P:
		printf("YM Packed data block:\n");
		registersPerAddress = 3;
		algorithmInfo = FindMatchingAlgoBlock(blockHeader);
		if (NULL != algorithmInfo)
		{
			regionStart = (ymBasePacked + (algorithmInfo->algorithmYmBase * registersPerAddress)) & ~0x3;
		}
		break;
#endif
	case (WMFW_USER_DEF_NAME << 8): 
		printf("User Defined Name Block:\n");
		buffer = (unsigned char *)malloc(dataLength + 1);
		if (!buffer)
		{
			status = WMFW_OUT_OF_MEMORY;
			goto done;
		}
		amountRead = fread(buffer, 1, dataLength, binFile);
		if (amountRead < dataLength)
		{
			if (feof(binFile))
				printf("\tError: Unexpected end of file after %d bytes of block\n", amountRead);
			else
				printf("\tError: Couldn't read from file\n");
			status = WMFW_BAD_FILE_FORMAT;
			goto done;
		}
		buffer[dataLength] = '\0';
		printf("\t%s\n", buffer);
		status = WMFW_SUCCESS;
		goto done;
	default:                
		 Skip over the rest of the block.
		printf("Unknown block type: 0x%04X\n", blockHeader.region);
		printf("\tSkipping over %d bytes\n", dataLength);
		if (0 != fseek(binFile, (long)dataLength, SEEK_CUR))
		{
			status = WMFW_BAD_FILE_FORMAT;
		}
		 And move on.
		goto done;
	}
	 If we got here, then it's an XM/YM/ZM data block for writing to the device.  
	 Allocate a buffer to hold the data.
	buffer = (unsigned char *)malloc(dataLength);
	if (!buffer)
	{
		status = WMFW_OUT_OF_MEMORY;
		goto done;
	}
	 Read in our data from the file.
	amountRead = fread(buffer, 1, dataLength, binFile);
	if (amountRead < dataLength)
	{
		if (feof(binFile))
			printf("\tError: Unexpected end of file after %d bytes of block\n", amountRead);
		else
			printf("\tError: Couldn't read from file\n");
		status = WMFW_BAD_FILE_FORMAT;
		goto done;
	}
	 If we identified an algorithm to write it to, send data to the chip. 
	 Otherwise, just ignore the data buffer we've read and move onto the next block
	if (regionStart != 0)
	{
		 Work out where to write it to.
		 The blockheader contains a register offset rather than memory offset, so no need to convert to registers
		unsigned int startAddress = regionStart + blockHeader.offset;
		printf("\tR%08Xh : %d bytes\n", startAddress, dataLength);
		 And write the data.
		HalWriteBlock(startAddress, ADDR_SIZE_4_BYTES, buffer, dataLength, 0);
	}
	 We've finished this block.  Go round for the next one.
	done:
		if (buffer)
		{
			free(buffer);
			buffer = NULL;
		}
		 If we hit EOF, assume that's why we got an error.
		if (feof(binFile))
		{
			printf("\nEnd of file\n");
			status = WMFW_END_OF_FILE;
		}
	return status;
}
int ProcessNextCoeffBlock ( FILE * binFile ) { WMFW_STATUS status = WMFW_SUCCESS ; BinCoeffBlockHeader blockHeader = { 0 , 0 , 0 , 0 , 0 , 0 } ; AlgorithmIDBlockFormat * algorithmInfo = NULL ; unsigned int regionStart = 0 ; unsigned int dataLength ; unsigned char * buffer = NULL ; unsigned char registersPerAddress ; size_t amountRead = fread ( & blockHeader , sizeof ( blockHeader ) , 1 , binFile ) ; if ( amountRead < 1 ) { status = WMFW_BAD_FILE_FORMAT ; goto done ; } dataLength = ( ( blockHeader . dataLength + 3 ) / 4 ) * 4 ; printf ( " \n " ) ; switch ( blockHeader . region ) { #if defined ( ADSP2 ) case WMFW_XM : printf ( " \n " ) ; registersPerAddress = 2 ; algorithmInfo = FindMatchingAlgoBlock ( blockHeader ) ; if ( NULL != algorithmInfo ) { regionStart = xmBaseUnpacked + ( algorithmInfo -> algorithmXmBase * registersPerAddress ) ; } break ; case WMFW_YM : printf ( " \n " ) ; registersPerAddress = 2 ; algorithmInfo = FindMatchingAlgoBlock ( blockHeader ) ; if ( NULL != algorithmInfo ) { regionStart = ymBaseUnpacked + ( algorithmInfo -> algorithmYmBase * registersPerAddress ) ; } break ; case WMFW_ZM : printf ( " \n " ) ; registersPerAddress = 2 ; algorithmInfo = FindMatchingAlgoBlock ( blockHeader ) ; if ( NULL != algorithmInfo ) { regionStart = zmBase + ( algorithmInfo -> algorithmZmBase * registersPerAddress ) ; } break ; #elif defined ( HALOCORE ) case WMFW_XM : printf ( " \n " ) ; registersPerAddress = 4 ; algorithmInfo = FindMatchingAlgoBlock ( blockHeader ) ; if ( NULL != algorithmInfo ) { regionStart = xmBaseUnpacked + ( algorithmInfo -> algorithmXmBase * registersPerAddress ) ; } break ; case WMFW_YM : printf ( " \n " ) ; registersPerAddress = 4 ; algorithmInfo = FindMatchingAlgoBlock ( blockHeader ) ; if ( NULL != algorithmInfo ) { regionStart = ymBaseUnpacked + ( algorithmInfo -> algorithmYmBase * registersPerAddress ) ; } break ; case WMFW_XM_P : printf ( " \n " ) ; registersPerAddress = 3 ; algorithmInfo = FindMatchingAlgoBlock ( blockHeader ) ; if ( NULL != algorithmInfo ) { regionStart = ( xmBasePacked + ( algorithmInfo -> algorithmXmBase * registersPerAddress ) ) & ~ 0x3 ; } break ; case WMFW_YM_P : printf ( " \n " ) ; registersPerAddress = 3 ; algorithmInfo = FindMatchingAlgoBlock ( blockHeader ) ; if ( NULL != algorithmInfo ) { regionStart = ( ymBasePacked + ( algorithmInfo -> algorithmYmBase * registersPerAddress ) ) & ~ 0x3 ; } break ; #endif case ( WMFW_USER_DEF_NAME << 8 ) : printf ( " \n " ) ; buffer = ( unsigned char * ) malloc ( dataLength + 1 ) ; if ( ! buffer ) { status = WMFW_OUT_OF_MEMORY ; goto done ; } amountRead = fread ( buffer , 1 , dataLength , binFile ) ; if ( amountRead < dataLength ) { if ( feof ( binFile ) ) printf ( " \t \n " , amountRead ) ; else printf ( " \t \n " ) ; status = WMFW_BAD_FILE_FORMAT ; goto done ; } buffer [ dataLength ] = ' \0 ' ; printf ( " \t \n " , buffer ) ; status = WMFW_SUCCESS ; goto done ; default : printf ( " \n " , blockHeader . region ) ; printf ( " \t \n " , dataLength ) ; if ( 0 != fseek ( binFile , ( long ) dataLength , SEEK_CUR ) ) { status = WMFW_BAD_FILE_FORMAT ; } goto done ; } buffer = ( unsigned char * ) malloc ( dataLength ) ; if ( ! buffer ) { status = WMFW_OUT_OF_MEMORY ; goto done ; } amountRead = fread ( buffer , 1 , dataLength , binFile ) ; if ( amountRead < dataLength ) { if ( feof ( binFile ) ) printf ( " \t \n " , amountRead ) ; else printf ( " \t \n " ) ; status = WMFW_BAD_FILE_FORMAT ; goto done ; } if ( regionStart != 0 ) { unsigned int startAddress = regionStart + blockHeader . offset ; printf ( " \t \n " , startAddress , dataLength ) ; } done : if ( buffer ) { free ( buffer ) ; buffer = NULL ; } if ( feof ( binFile ) ) { printf ( " \n \n " ) ; status = WMFW_END_OF_FILE ; } return status ; }
Function: ProcessNextCoeffBlock
Function : ProcessNextCoeffBlock
/*NULL*/ //bool algorithmMatchFound = false; /*
	 *  Format for a coefficient block:
	 * 
	 *      31       24 23      16 15       8 7        0
	 *  0   +----------+----------+----------+---------+
	 *      |      type[15:0]     |    offset[15:0]    |
	 *  4   +----------+-------------------------------+
	 *		|               Algorithm ID               |
	 *		+------------------------------------------+
	 *		|            Algorithm Version             |
	 *		+------------------------------------------+
	 *		|               Sample Rate                |
	 *		+------------------------------------------+
	 *      |                dataLength                |
	 *  8   +------------------------------------------+
	 *      |                   data                   |
	 *      :                   ....                   :
	 *      :                                          :
	 *  The offset/region and data length are little endian. 
	 *  The data is formatted big-endian to facilitate writing
	 *  straight to the core.
	 */ //  Read the block header. This tells us what type of block it is and how //  big it is. // Round the datalength up to the nearest multiple of four, as padding bytes may be included in data section // but are not included in the datalength count.  // Check it's a block we understand. // ~0x3 is performed to ensure a valid register address // Name block string // Read in the data section and print it out on console. // This can be skipped over, as this string data is only for user information // If skipping this, use fseek to skip over the data section and move on to the next block // Unknown block // // Skip over the rest of the block. // // And move on. // If we got here, then it's an XM/YM/ZM data block for writing to the device.   // Allocate a buffer to hold the data. // Read in our data from the file. // If we identified an algorithm to write it to, send data to the chip.  // Otherwise, just ignore the data buffer we've read and move onto the next block /*NULL*/ // Work out where to write it to. // The blockheader contains a register offset rather than memory offset, so no need to convert to registers // And write the data. //HalWriteBlock(startAddress, ADDR_SIZE_4_BYTES, buffer, dataLength, 0); // We've finished this block.  Go round for the next one. // If we hit EOF, assume that's why we got an error.