/** @brief Interface to QSPI Flash
 *
 * @copyright 2020 Remsdaq Ltd.
 * @file c4_qspi.h
 *
 * @date 19 Mar 2020
 * @author Dan Smithers <dwhs@remsdaq.com>
 *
 */

#ifndef C4_QSPI_H_
#define C4_QSPI_H_

#include "c4_error_codes.h"
#include "flexspi_nor_flash.h"
#include <stdint.h>  // for C99 types.

/** @brief Maximum
 *
 * @param[in] a first value
 * @param[in] b second value
 *
 * @return a if a > b otherwise b
 */
#ifndef max
#define max(a,b)             \
({                           \
    __typeof__ (a) _a = (a); \
    __typeof__ (b) _b = (b); \
    _a > _b ? _a : _b;       \
})
#endif
/** @brief Minimum
 *
 * @param[in] a first value
 * @param[in] b second value
 *
 * @return a if a < b otherwise b
 */
#ifndef min
#define min(a,b)             \
({                           \
    __typeof__ (a) _a = (a); \
    __typeof__ (b) _b = (b); \
    _a < _b ? _a : _b;       \
})
#endif

#ifdef __cplusplus
extern "C" {
#endif

/** @brief Initialise the flexSPI interface to QSPI.
 *
 * @return Exit code
 */
exit_code_t C4_QSPI_init(void);

/** @brief Get the current config of the QSPI flash
 *
 * @param[out] pConfig Pointer to return the configuration.
 *
 * @return Exit code.
 */
exit_code_t C4_QSPI_getConfig(flexspi_nor_config_t *pConfig);

/** @brief Erase region in QSPI flash memory.
 *
 * The memory is erased page by page. Whole pages are erased.
 * Partial pages (at either end of the region are read and then updated before being
 * erased and reprogrammed.
 *
 * @warning Currently none of these QSPI functions are thread safe.
 *
 * @param[in] addr Start address to erase from.
 * @param[in] len  Number of bytes to erase.
 *
 * @return Exit code.
 */
exit_code_t C4_QSPI_erase(uintptr_t addr, size_t len);

/** @brief Read data from QSPI flash memory.
 *
 * Possibly nugatory as the QSPI can be read as if memory mapped.
 *
 * @warning Currently none of these QSPI functions are thread safe.
 *
 * @param[in]  addr  Start address to read from.
 * @param[out] pData Array to receive data. The caller ensures that this is
 * large enough to receive the specified number of bytes.
 * @param[in]  len   Number of bytes to read.
 *
 * @return Exit code.
 */
exit_code_t C4_QSPI_read(uintptr_t addr, uint8_t *pData, size_t len);


/** @brief Write data to QSPI flash memory.
 *
 * The data are written page by page. Whole pages are erased and programmed.
 * Partial pages (at either end of the region are read and then updated before being
 * erased and reprogrammed.
 *
 * @warning Currently none of these QSPI functions are thread safe.
 *
 * @param[in] addr  Start address to write to.
 * @param[in] pData Array containing data to be written.
 * @param[in] len   Number of bytes to write.
 *
 * @return Exit code.
 */
exit_code_t C4_QSPI_write(uintptr_t addr, const uint8_t *pData, size_t len);

#ifdef __cplusplus
}
#endif


#endif /* C4_QSPI_H_ */
