/*
 * ADS7843.c
 *
 *  Created on: Aug 6, 2023
 *      Author: leo
 */

#include <stdio.h>
#include <stdint.h>

#include "ADS7843.h"


void ADS7843_Init(ADS7843_Def* def){
	uint8_t control = (0x80) | (ADS7843_X_CHANNEL << ADS7843_CHANNEL) | (ADS7843_12BIT << ADS7843_BIT_MODE) | (ADS7843_DFR << ADS7843_DIFF_MODE) | (ADS7843_POWER_PENIRQ << ADS7843_POW_MODE);
	ADS7843_GetData(def, control);
}

uint16_t ADS7843_GetData(ADS7843_Def* def, uint8_t control){
	uint16_t data = 0;

	HAL_GPIO_WritePin(def->CS_GPIO_Port, def->CS_GPIO_Pin, GPIO_PIN_RESET);

	for (uint8_t j = 0x80; j; j >>= 1) {
	  HAL_GPIO_WritePin(def->SCK_GPIO_Port, def->SCK_GPIO_Pin, GPIO_PIN_RESET);
	  HAL_GPIO_WritePin(def->MOSI_GPIO_Port, def->MOSI_GPIO_Pin, control & j);
	  HAL_GPIO_WritePin(def->SCK_GPIO_Port, def->SCK_GPIO_Pin, GPIO_PIN_SET);
	}

	for (uint16_t j = 0x8000; j; j >>= 1) {
	  HAL_GPIO_WritePin(def->SCK_GPIO_Port, def->SCK_GPIO_Pin, GPIO_PIN_RESET);
	  if (HAL_GPIO_ReadPin(def->MISO_GPIO_Port, def->MISO_GPIO_Pin) == GPIO_PIN_SET) data |= j;
	  HAL_GPIO_WritePin(def->SCK_GPIO_Port, def->SCK_GPIO_Pin, GPIO_PIN_SET);
	}
	HAL_GPIO_WritePin(def->SCK_GPIO_Port, def->SCK_GPIO_Pin, GPIO_PIN_RESET);
	data >>= 4;

	HAL_GPIO_WritePin(def->CS_GPIO_Port, def->CS_GPIO_Pin, GPIO_PIN_RESET);

	return data;
}

GPIO_PinState ADS7843_Touched(ADS7843_Def* def){
	return !HAL_GPIO_ReadPin(def->Int_GPIO_Port, def->Int_GPIO_Pin);
}

uint16_t ADS7843_GetX_Raw(ADS7843_Def* def){
	uint8_t control = (0x80) | (ADS7843_X_CHANNEL << ADS7843_CHANNEL) | (ADS7843_12BIT << ADS7843_BIT_MODE) | (ADS7843_DFR << ADS7843_DIFF_MODE) | (ADS7843_POWER_PENIRQ << ADS7843_POW_MODE);
	uint16_t data = ADS7843_GetData(def, control);
	return data;
}
uint16_t ADS7843_GetY_Raw(ADS7843_Def* def){
	uint8_t control = (0x80) | (ADS7843_Y_CHANNEL << ADS7843_CHANNEL) | (ADS7843_12BIT << ADS7843_BIT_MODE) | (ADS7843_DFR << ADS7843_DIFF_MODE) | (ADS7843_POWER_PENIRQ << ADS7843_POW_MODE);
	uint16_t data = ADS7843_GetData(def, control);
	return data;
}

int16_t ADS7843_GetX(ADS7843_Def* def){
	uint16_t raw = ADS7843_GetX_Raw(def);
	return (raw - ADS7843_X_MIN) / ((ADS7843_X_MAX - ADS7843_X_MIN) / ADS7843_WIDTH);
}
int16_t ADS7843_GetY(ADS7843_Def* def){
	uint16_t raw = ADS7843_GetY_Raw(def);
	return ADS7843_HEIGHT - (raw - ADS7843_Y_MIN) / ((ADS7843_Y_MAX - ADS7843_Y_MIN) / ADS7843_HEIGHT);
}
