/*
 * i2c.c
 *
 *  Created on: Jun 8, 2021
 *      Author: user
 */

#include "i2c.h"
#include "stm32l0xx_ll_lpuart.h"

i2c_context_t *i2c_context;

int i2c_init(i2c_context_t *context)
{
	if (context == NULL) {
		return I2C_ERROR;
	}
	i2c_context = context;
	return I2C_OK;
}

int i2c_transmit(uint8_t address, uint8_t *buffer, int len)
{
	/* prevent interrupts during I2C communication (e.g. collision with MODBUS) */
//	LL_LPUART_Disable(LPUART1);
//	LL_LPUART_DisableIT_RXNE(LPUART1);
//	__disable_irq();
	LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len,
			LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
	int i = 0;
	// Autoend mode will raise STOP flag if NACK is detected
	// (or if desired number of bytes is transmitted)
	while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
		if (LL_I2C_IsActiveFlag_TXE(i2c_context->i2c)) {
			if (i < len) {
				LL_I2C_TransmitData8(i2c_context->i2c, buffer[i++]);
			}
		}
	}
	LL_I2C_ClearFlag_STOP(i2c_context->i2c);
	if (LL_I2C_IsActiveFlag_NACK(i2c_context->i2c)) {
		return I2C_ERROR_NACK;
	}
	if (len != i) {
		// this will probably never happen, as NACK flag
		// is raised everytime len != number of TXed bytes
		return I2C_ERROR_TX_INCOMPLETE;
	}
//	__enable_irq();
//	LL_LPUART_Enable(LPUART1);
//	LL_LPUART_EnableIT_RXNE(LPUART1);
	return I2C_OK;
}

int i2c_receive(uint8_t address, uint8_t *buffer, int len)
{
//	__disable_irq();
//	LL_LPUART_Disable(LPUART1);
//	LL_LPUART_DisableIT_RXNE(LPUART1);
	LL_I2C_HandleTransfer(i2c_context->i2c, address, LL_I2C_ADDRSLAVE_7BIT, len,
				LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
	int i = 0;
	while (!LL_I2C_IsActiveFlag_STOP(i2c_context->i2c)) {
		if (LL_I2C_IsActiveFlag_RXNE(i2c_context->i2c)) {
			if (i < len) {
				buffer[i++] = LL_I2C_ReceiveData8(i2c_context->i2c);
			}
		}
	}
	LL_I2C_ClearFlag_STOP(i2c_context->i2c);
	if (len != i) {
		return I2C_ERROR_RX_INCOMPLETE;
	}
//	__enable_irq();
//	LL_LPUART_Enable(LPUART1);
//	LL_LPUART_EnableIT_RXNE(LPUART1);
	return I2C_OK; // TODO error detection
}
