/*
 * Copyright 2018-2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 */

#ifndef __ACK_LPC55S16_OTA_SHARED_H__
#define __ACK_LPC55S16_OTA_SHARED_H__

#include <stdint.h>

#ifdef __cplusplus
extern "C"
{
#endif

#define ACK_LPC55S16_OTA_FLASH_PAGE_SIZE (512U)
#define ACK_LPC55S16_OTA_FLASH_SIZE      (244*1024U)

#define ACK_LPC55S16_OTA_STATUS_PARTITION_SIZE (1024U)
#define ACK_LPC55S16_OTA_LOADER_PARTITION_SIZE (0x3C00U)
#define ACK_LPC55S16_OTA_PRIMARY_PARTITION_SIZE (0x1C800U)
#define ACK_LPC55S16_OTA_STAGING_PARTITION_SIZE (0x1C800U)

// Partition start and end addresses.
#define ACK_LPC55S16_OTA_LOADER_PARTITION_START (0X0U)
#define ACK_LPC55S16_OTA_LOADER_PARTITION_END ((ACK_LPC55S16_OTA_LOADER_PARTITION_START + \
    ACK_LPC55S16_OTA_LOADER_PARTITION_SIZE) - 1)

#define ACK_LPC55S16_OTA_STATUS_PARTITION_START (ACK_LPC55S16_OTA_LOADER_PARTITION_END + 1)
#define ACK_LPC55S16_OTA_STATUS_PARTITION_END ((ACK_LPC55S16_OTA_STATUS_PARTITION_START + \
    ACK_LPC55S16_OTA_STATUS_PARTITION_SIZE) - 1)

#define ACK_LPC55S16_OTA_PRIMARY_PARTITION_START (ACK_LPC55S16_OTA_STATUS_PARTITION_END + 1)
#define ACK_LPC55S16_OTA_PRIMARY_PARTITION_END ((ACK_LPC55S16_OTA_PRIMARY_PARTITION_START + \
    ACK_LPC55S16_OTA_PRIMARY_PARTITION_SIZE) - 1)

#define ACK_LPC55S16_OTA_STAGING_PARTITION_START (ACK_LPC55S16_OTA_PRIMARY_PARTITION_END + 1)
#define ACK_LPC55S16_OTA_STAGING_PARTITION_END ((ACK_LPC55S16_OTA_STAGING_PARTITION_START + \
    ACK_LPC55S16_OTA_STAGING_PARTITION_SIZE) - 1)

 // Sanity checks on partition sizes.
 #if (ACK_LPC55S16_OTA_LOADER_PARTITION_SIZE % ACK_LPC55S16_OTA_FLASH_PAGE_SIZE) \
     || (ACK_LPC55S16_OTA_STATUS_PARTITION_SIZE % ACK_LPC55S16_OTA_FLASH_PAGE_SIZE) \
     || (ACK_LPC55S16_OTA_PRIMARY_PARTITION_SIZE % ACK_LPC55S16_OTA_FLASH_PAGE_SIZE) \
     || (ACK_LPC55S16_OTA_STAGING_PARTITION_SIZE % ACK_LPC55S16_OTA_FLASH_PAGE_SIZE) \
     || (ACK_LPC55S16_OTA_STAGING_PARTITION_SIZE != ACK_LPC55S16_OTA_PRIMARY_PARTITION_SIZE) \
     || ((ACK_LPC55S16_OTA_LOADER_PARTITION_SIZE + ACK_LPC55S16_OTA_STATUS_PARTITION_SIZE \
         + ACK_LPC55S16_OTA_PRIMARY_PARTITION_SIZE + ACK_LPC55S16_OTA_STAGING_PARTITION_SIZE) \
             != ACK_LPC55S16_OTA_FLASH_SIZE)
 #error \
 Partition sizes must be a multiple of the page size; \
 Primary and Staging Partitions must be the same size,;\
 and the sum of the sizes of the Loader, Status, Primary, \
 and Staging Partitions must equal the total flash size.
 #endif

typedef struct _ACKLpc55s16OtaStatusPartition_t
{
    // Must be ACK_LPC55S16_OTA_STATUS_PARTITION_SIGNATURE1.
    uint32_t Signature1;

    // Note that this is at the end of the structure so that it's the very final thing flashed
    // to make the Status Partition valid.
    // ACK_LPC55S16_OTA_STATUS_PARTITION_STATE_UNAPPLIED_IMAGE: Unapplied image present in Staging Partition.
    // Anything else: No unapplied OTA image present in Staging Partition.
    uint8_t State;

    // Reserved. Must be 0.
    uint8_t Pad[3];

    // Address in the Primary partition where the program starts. Must match the base address of
    // the Primary Partition.
    uint32_t ImageStartAddress;

    // Size in bytes of the OTA image on the Staging Partition.
    uint32_t ImageSize;

    // CRC32 of image data, for image validation.
    uint32_t Crc32;

    // Must be ACK_LPC55S16_OTA_STATUS_PARTITION_SIGNATURE2, or else State is ignored and considered 0.
    // This is deliberately placed at the end of the partition to avoid seeing the Status Partition
    // as valid unless the *entire* contents of this struct can be successfully flashed to it.
    uint32_t Signature2;
}
ACKLpc55s16OtaStatusPartition_t;

// Value for ACK_Lpc55s16OtaStatusPartition_t Signature1 and Signature2.
#define ACK_LPC55S16_OTA_STATUS_PARTITION_SIGNATURE1 0x314b4341
#define ACK_LPC55S16_OTA_STATUS_PARTITION_SIGNATURE2 0x324b4341

// Value for ACK_HostFirmwareUpdateStatusPartition_t State.
#define ACK_LPC55S16_OTA_STATUS_PARTITION_STATE_UNAPPLIED_IMAGE 0xa5

#ifdef __cplusplus
}
#endif

#endif // endef __ACK_LPC55S16_OTA_SHARED_H__
