/******************************************************************************
 *
 * Copyright 2017, Lattice Semiconductor, Inc. All rights reserved.
 * No part of this work may be reproduced, modified, distributed, transmitted,
 * transcribed, or translated into any language or computer format, in any form
 * or by any means without written permission of Lattice Semiconductor Inc.,
 * 111 SW 5th Ave, Suite 700, Portland, OR 97204.
 *
 *****************************************************************************/

#include "sii_datatypes.h"
#include "sii_platform_api.h"

static uint32_t (*block_write)(uint32_t dev_id, uint16_t addr,
		const uint8_t *p_data, uint16_t size) = NULL;
static uint32_t (*block_read)(uint32_t dev_id, uint16_t addr,
		UINT8 *p_data, uint16_t size) = NULL;
static void (*reset_set)(bool_t b_on) = NULL;
static uint32_t (*time_msec_query)(void) = NULL;
static void (*log_print)(const char *message) = NULL;
static void (*sleep_msec)(uint32_t millisec) = NULL;

void sii_platform_register_api(
		uint32_t (*in_block_write)(uint32_t dev_id, uint16_t addr, const uint8_t *p_data, uint16_t size),
		uint32_t (*in_block_read)(uint32_t dev_id, uint16_t addr, uint8_t *p_data, uint16_t size),
		void (*in_reset_set)(bool_t b_on),
		uint32_t (*in_time_msec_query)(void),
		void (*in_log_print)(const char *message),
		void (*in_sleep_msec)(uint32_t millisec)) {
	block_write = in_block_write;
	block_read = in_block_read;
	reset_set = in_reset_set;
	time_msec_query = in_time_msec_query;
	log_print = in_log_print;
	sleep_msec = in_sleep_msec;
}

uint32_t sii_platform_host_block_write(uint32_t dev_id, uint16_t addr,
		const uint8_t *p_data, uint16_t size) {
	if (NULL == block_write)
		return 1;
	return block_write(dev_id, addr, p_data, size);
}

uint32_t sii_platform_host_block_read(uint32_t dev_id, uint16_t addr,
		uint8_t *p_data, uint16_t size) {
	if (NULL == block_read)
		return 1;
	return block_read(dev_id, addr, p_data, size);
}

void sii_platform_device_reset_set(uint32_t dev_id, bool_t b_on) {
	if (NULL == reset_set)
		return;
	reset_set(b_on);
}

uint32_t sii_platform_time_msec_query(void) {
	if (NULL == time_msec_query)
		return 1;
	return time_msec_query();
}

void sii_platform_log_print(const char *message) {
	if (NULL == log_print)
		return;
	log_print(message);
}

/* Delay Function */
void sii_platform_sleep_msec(uint32_t millisec) {
	if (NULL == sleep_msec)
		return;
	sleep_msec(millisec);
}


static HANDLE_T sSemaphoreHdl = NULL_HANDLE;

HANDLE_T sii_platform_sema_create() {
	if(NULL_HANDLE == sSemaphoreHdl) {
		if(x_sema_create(&sSemaphoreHdl, X_SEMA_TYPE_MUTEX, X_SEMA_STATE_UNLOCK) != OSR_OK) {
			LOG(0, "[SalzCtrl] x_sema_create failed \n");
			sSemaphoreHdl = NULL_HANDLE;
		}
	}
	return sSemaphoreHdl;
}

void sii_platform_sema_delete() {
	if(NULL_HANDLE != sSemaphoreHdl) {
		x_sema_delete(sSemaphoreHdl);
		sSemaphoreHdl = NULL_HANDLE;
	}
}

void sii_platform_sema_lock() {
	if(NULL_HANDLE != sSemaphoreHdl) {
		x_sema_lock(sSemaphoreHdl, X_SEMA_OPTION_WAIT);
	}
}

void sii_platform_sema_unlock() {
	if(NULL_HANDLE != sSemaphoreHdl) {
		x_sema_unlock(sSemaphoreHdl);
	}
}
