/*
 * 04_flash_to_from_file.c
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 *
 * Copyright (c) 2026 Georgy Moshkin <https://georgymoshkin.com>
 * All rights reserved.
 *
 */

#include "examples.h"

#ifdef EXAMPLE_04_FLASH_TO_FROM_FILE

#ifndef SRC_04_FLASH_TO_FROM_FILE_C_
#define SRC_04_FLASH_TO_FROM_FILE_C_

#define UART_BUFFER_SIZE 64
__IO uint8_t uartBuffer[UART_BUFFER_SIZE];	// DMA buffer for serial port RX
uint8_t cmdByte; 							// Temporary TX/RX byte variable

void app_boot()
{
	flash_region_run(REGION_PRECONFIGURED);
}

void app_init(UART_HandleTypeDef *huartPtr)
{
	// Initialize universal serial port library (uart.h, uart.c)
	COM_Init(0,					// Port number
			huartPtr,			// HAL port handle
			uartBuffer,			// RX buffer array
			UART_BUFFER_SIZE);	// RX buffer size
}


void app_loop()
{

	// PC13 LED Blink
//	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, (HAL_GetTick() & 0b1111000000) ? GPIO_PIN_SET : GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, (HAL_GetTick() & 64) ? GPIO_PIN_SET : GPIO_PIN_RESET);

	// Check if at least one byte is present in RX buffer
	if (COM_ReadFast(&cmdByte, 1)) switch (cmdByte)
	{

	// Command 0x01: Set read/write pointer
	case 0x01:
	{
		flash_region_select(REGION_APPLICATION);

		// Send response to serial port
		cmdByte=0xA1;
		COM_Write(&cmdByte, 1);
		COM_Write(&flash_size_application, 4);
		break;
	}

	// Command 0x02: Read 32-byte block (increments pointer by 32 bytes)
	case 0x02:
	{
		uint8_t bytes[32];
		flash_region_read(bytes);

		// Send response to serial port
		cmdByte=0xA2;
		COM_Write(&cmdByte, 1);
		COM_Write(&bytes, 32);
		break;
	}

	// Command 0x03: Erase application region, return region size
	case 0x03:
	{
		flash_region_erase_and_select(REGION_APPLICATION);

		// Send response to serial port
		cmdByte=0xA3;
		COM_Write(&cmdByte, 1);
		COM_Write(&flash_size_application, 4);
		break;
	}

	// Command 0x04: Write 32-byte block (increments pointer by 32 bytes)
	case 0x04:
	{
		// Send response to serial port
		uint8_t bytes[32];
		if (COM_Read(&bytes,32))
		{
			flash_region_write((uint8_t*)&bytes);

			// Send response to serial port
			cmdByte=0xA4;
			COM_Write(&cmdByte, 1);
		}
		break;
	}

	// Command 0xF1: Run application
	case 0xF1:
	{
		flash_region_run(REGION_APPLICATION);
		break;
	}

	}
}


#endif /* SRC_04_FLASH_TO_FROM_FILE_C_ */
#endif /* EXAMPLE_04_FLASH_TO_FROM_FILE */
