/* Includes ------------------------------------------------------------------*/
#include "mg32f10x.h"
#include <stdio.h>
#include <string.h>
#include "bsp_uart1.h"
#include "drv_spi_flash_quad.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define FLASH_WRITE_ADDRESS       0x1000
#define FLASH_READ_ADDRESS        FLASH_WRITE_ADDRESS
#define FLASH_SECTOR_TO_ERASE     FLASH_WRITE_ADDRESS

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
const uint8_t WriteData[] = 
{
  0x52,0x79,0x0C,0xAF,0xC0,0x99,0x44,0x71,0x9D,0x30,0xAD,0x68,0xF7,0x95,0xF8,0x38,
  0xF5,0x9C,0x19,0xDD,0xEC,0xBC,0x6C,0xF0,0x71,0xD8,0xE4,0x1D,0x6F,0x7F,0x08,0xD7,
  0x92,0x61,0x36,0x36,0xE3,0x08,0x7E,0xED,0x44,0x22,0x72,0x36,0x84,0x27,0xF5,0x98,
  0x95,0x7C,0xFE,0x4F,0x17,0x8A,0xD3,0x6C,0x43,0xB0,0xBC,0xEC,0x07,0x99,0x81,0x29,
  0x28,0x32,0xFD,0x3B,0x8D,0xCD,0x02,0x97,0xAE,0x80,0xE6,0xC9,0xE5,0x3B,0x9A,0x24,
  0x97,0x31,0xAF,0x57,0x00,0x5E,0xCC,0x1B,0xEB,0x5F,0x2C,0x07,0x68,0x21,0x72,0xFD,
  0x8B,0xDE,0x66,0x74,0xB4,0x09,0xD5,0x33,0xD7,0x5E,0x4A,0x42,0x46,0xD9,0x6F,0x5D,
  0x33,0xCF,0xAD,0xD6,0x62,0x5C,0xF8,0x62,0x92,0x4E,0xE0,0xF0,0x81,0x9A,0xCE,0x94,
  0x5A,0xCC,0x05,0x67,0xD0,0x3E,0xFE,0xB1,0x51,0xFF,0x57,0x8D,0xB1,0x8D,0xAC,0x32,
  0xB5,0xD5,0x7F,0xA8,0xB8,0x4A,0x0E,0xD3,0xEF,0x4A,0x15,0x0D,0x40,0x2D,0xA4,0xC6,
  0x97,0x8D,0x38,0xDA,0xDB,0x54,0xBF,0x6D,0x1C,0xFF,0x54,0xEF,0x82,0x5C,0x40,0xAC,
  0x68,0xA0,0x91,0xEC,0x1B,0x24,0x1D,0x86,0x77,0x5B,0xB6,0x85,0xAF,0xC1,0xAA,0xAD,
  0xC2,0xA6,0xA5,0x76,0x4C,0x66,0xA5,0xFF,0x0A,0x99,0xCA,0x1F,0xC3,0x71,0x86,0xA1,
  0x64,0x85,0xD6,0xA0,0xFB,0xE4,0x68,0x0D,0xDB,0x90,0xC6,0x4B,0x5B,0xB6,0x63,0xE3,
  0x4B,0x8A,0xAA,0x99,0xDD,0x31,0xD2,0xC1,0x4D,0x4A,0xEA,0xC2,0x42,0x36,0xC7,0x0A,
  0x28,0xC8,0xBD,0x46,0x52,0x70,0x94,0x23,0x44,0x39,0xD7,0x07,0xCC,0xCC,0x5C,0x81,
  0x4B,0x2F,0x8C,0xA1,0xDA,0xF4,0x86,0x74,0xB0,0x5A,0x49,0x10,0x1F,0xD4,0x8B,0x7B,
  0x9C,0x65,0x14,0x8E,0x81,0x28,0x6F,0x50,0xE2,0x4E,0x62,0x55,0xFD,0x27,0x7C,0x87,
  0x0E,0xAB,0xD0,0xE9,0x09,0xC7,0x9A,0x77,0xD7,0xBD,0x45,0xEE,
};
uint8_t ReadBuffer[sizeof(WriteData)];
uint32_t jedec_id;
uint16_t mfr_did;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

int main(void)
{
  uint32_t tmp;

  /* Init UART1 to 115200-8n1 for print message */
  uart1_init(72000000, 115200);

  /* Initialize the SPI FLASH driver */
  SpiFlash_Init();

  printf("Quad SPI Flash example\r\n");

  /* Enable QE bit */
  tmp = SpiFlash_ReadStatusReg2();
  printf("StatusReg2 = 0x%02X\r\n", tmp);
  if (!(tmp & 0x02)) {
    printf("QE bit is not set!\r\n");
    printf("Set QE bit...\r\n");
    tmp |= 0x02;
    SpiFlash_WriteStatusReg2(tmp);
    tmp = SpiFlash_ReadStatusReg2();
    printf("StatusReg2 = 0x%02X\r\n", tmp);
  }

  /* Get SPI Flash ID */
  jedec_id = SpiFlash_ReadIdentification();
  printf("This flash chip JEDEC ID is 0x%06X\r\n", jedec_id);

  /* Get SPI Flash ID through Quad I/O */
  mfr_did = SpiFlash_QuadReadMidDid();
  printf("This flash chip Manufacture/Device ID is 0x%04X\r\n", mfr_did);

  /* Perform a write in the Flash followed by a read of the written data */
  /* Erase SPI FLASH Sector to write on */
  SpiFlash_SectorErase(FLASH_SECTOR_TO_ERASE);

  /* Write WriteData data to SPI FLASH memory through Quad I/O */
  SpiFlash_QuadWriteBuffer(FLASH_WRITE_ADDRESS, WriteData, sizeof(WriteData));

  /* Read data from SPI FLASH memory through Quad I/O */
  SpiFlash_QuadFastRead(FLASH_READ_ADDRESS, ReadBuffer, sizeof(ReadBuffer));

  /* Check the correctness of written data */
  if(memcmp(WriteData, ReadBuffer, sizeof(WriteData)) == 0)
  {
    printf("Flash progam and read operation ok.\r\n");
  }
  else
  {
    printf("Flash progam and read operation failed!\r\n");
  }

  /* Infinite loop */
  while (1)
  {
  }
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif
