/***********************************************************************/
/**
 \file
 Functions for reading DSP code to load into DSP

Copyright (C) 1997-2017 AudioScience, Inc. All rights reserved.

This software is provided 'as-is', without any express or implied warranty.
In no event will AudioScience Inc. be held liable for any damages arising
from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This copyright notice and list of conditions may not be altered or removed
   from any source distribution.

AudioScience, Inc. <support@audioscience.com>

( This license is GPL compatible see http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses )

*/
/***********************************************************************/
#ifndef _HPIDSPCD_H_
#define _HPIDSPCD_H_

#include "hpi_internal.h"

/** Header structure for dsp firmware file
 This structure must match that used in s2bin.c for generation of asidsp.bin
 */
//#ifndef DISABLE_PRAGMA_PACK1
//#pragma pack(push, 1)
//#endif
struct code_header{
	/** Size in bytes including header */
	uint32_t size;
	/** File type tag "CODE" == 0x45444F43 */
	uint32_t type;
	/** Adapter model number */
	uint32_t adapter;
	/** Firmware version*/
	uint32_t version;
	/** Data checksum */
	uint32_t checksum;
};
//#ifndef DISABLE_PRAGMA_PACK1
//#pragma pack(pop)
//#endif

//? Don't need the pragmas?
compile_time_assert((sizeof(struct code_header) == 20), code_header_size);

/** Descriptor for dspcode from firmware loader */
struct dsp_code {
	/** copy of  file header */
	struct code_header header;
	/** Expected number of words in the whole dsp code,INCL header */
	uint32_t block_length;
	/** Number of words read so far */
	uint32_t word_count;

	/** internal state of DSP code reader */
	struct dsp_code_private *pvt;
};

/** Prepare *psDspCode to refer to the requested adapter's firmware.
Code file name is obtained from HpiOs_GetDspCodePath

\return 0 for success, or error code if requested code is not available
*/
short HpiDspCode_Open(
	/// Code identifier, usually adapter family
	uint32_t nAdapter,
	struct hpi_os_adapter *pAdapter,
	/// Pointer to DSP code control structure
	struct dsp_code *psDspCode
    );

/** Close the DSP code file */
void HpiDspCode_Close(struct dsp_code *psDspCode);

/** Rewind to the beginning of the DSP code file (for verify) */
void HpiDspCode_Rewind(struct dsp_code *psDspCode);

/** Read one word from the dsp code file
	\return 0 for success, or error code if eof, or block length exceeded
*/
short HpiDspCode_ReadWord(
	struct dsp_code *psDspCode, ///< DSP code descriptor
	uint32_t *pdwWord ///< Where to store the read word
);

/** Get a block of dsp code into an internal buffer, and provide a pointer to
that buffer. (If dsp code is already an array in memory, it is referenced,
not copied.)

\return Error if requested number of words are not available
*/
short HpiDspCode_ReadBlock(size_t nWordsRequested,
			   struct dsp_code *psDspCode,
      	// Pointer to store (Pointer to code buffer)
			   uint32_t **ppdwBlock
    );

#endif
