// FMRadioBootloader.h: interface for the CFMRadioBootloader class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FMRADIOBOOTLOADER_H__3E49A8D5_74D3_46E1_8CF6_F3C59932BF3C__INCLUDED_)
#define AFX_FMRADIOBOOTLOADER_H__3E49A8D5_74D3_46E1_8CF6_F3C59932BF3C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "FMRadioMCUImage.h"

//Reports specific to bootloading
#define WRITE_REPORT	19
#define RESPONSE_REPORT	22
#define FLASH_REPORT	20
#define CRC_REPORT		21

//Unique ID sent to bootloader and required to put into a bootload state
#define UNIQUE_BL_ID	0x34

//Mask for the flash data
#define FLASH_DATA_MASK	0x55

//Bootlaoder commands
#define GET_SW_VERSION_COMMAND	0x00
#define GET_HW_VERSION_COMMAND	0x07
#define	SET_PAGE_COMMAND		0x01
#define ERASE_PAGE_COMMAND		0x02
#define WRITE_PAGE_COMMAND		0x03
#define CRC_ON_PAGE_COMMAND		0x04
#define READ_FLASH_BYTE_COMMAND	0x05
#define RESET_DEVICE_COMMAND	0x06
#define BLANK					0xFF

//Bootloader command responses
#define COMMAND_OK		0x01
#define COMMAND_FAILED	0x02
#define COMMAND_PENDING	0x03

//Buffer sizes
#define COMMAND_BUFFER_SIZE		4
#define RESPONSE_BUFFER_SIZE	2
#define FLASH_BUFFER_SIZE		64
#define CRC_BUFFER_SIZE			3

#define FMTUNERDATA_BUFFER_SIZE	60
#define FMTUNERDATA_REPORT_SIZE	FMTUNERDATA_BUFFER_SIZE + 1

//Typedefs for the buffers
typedef BYTE COMMAND_BUFFER[COMMAND_BUFFER_SIZE];
typedef BYTE RESPONSE_BUFFER[RESPONSE_BUFFER_SIZE];
typedef BYTE FLASH_BUFFER[FLASH_BUFFER_SIZE];
typedef BYTE CRC_BUFFER[CRC_BUFFER_SIZE];

class CFMRadioBootloader  
{
public:
	CFMRadioBootloader(HANDLE fmRadioDataHandle, BYTE* pEndpoint0ReportBuffer, DWORD endpoint0ReportBufferSize, BYTE* pEndpoint2ReportBuffer, DWORD endpoint2ReportBufferSize);
	virtual ~CFMRadioBootloader();

	bool BootloadMCU(BYTE swVersion, BYTE hwVersion, BOOL *bCloseOnFail);
	BYTE m_ProgressPercentage;

private:
	bool EnterBootloadMode(BYTE swVersion, BYTE hwVersion);
	bool GetSoftwareVersion(BYTE* swVersion);
	bool GetHardwareVersion(BYTE* hwVersion);
	bool SetPage(BYTE page);
	bool ErasePage(BYTE page);
	bool WritePage(BYTE page, BYTE* data, DWORD dataSize);
	bool CheckCRCPage(WORD* pageCRC);
	bool ReadFlashByte(BYTE* data, WORD address);
	bool ResetFirmware();

	HANDLE	m_FMRadioDataHandle;
	
	BYTE*	m_pEndpoint0ReportBuffer;
	DWORD	m_Endpoint0ReportBufferSize;

	BYTE*	m_pEndpoint2ReportBuffer;
	DWORD	m_Endpoint2ReportBufferSize;


	bool SetMCUBootloadReport(BYTE* dataBuffer, DWORD dataBufferSize);
	bool GetMCUBootloadReport(BYTE* dataBuffer, DWORD dataBufferSize);
};

#endif // !defined(AFX_FMRADIOBOOTLOADER_H__3E49A8D5_74D3_46E1_8CF6_F3C59932BF3C__INCLUDED_)
