//////////////////////////////////////////////////////////////////////////////////////////
//
//  Demo code for the MAX30003 breakout board
//
//  Arduino connections:
//
//  |MAX30003 pin label| Pin Function         |Arduino Connection|
//  |----------------- |:--------------------:|-----------------:|
//  | MISO             | Slave Out            |  D12             |
//  | MOSI             | Slave In             |  D11             |
//  | SCLK             | Serial Clock         |  D13             |
//  | CS               | Chip Select          |  D7              |
//  | VCC              | Digital VDD          |  +5V             |
//  | GND              | Digital Gnd          |  Gnd             |
//  | FCLK             | 32K CLOCK            |  -               |
//  | INT1             | Interrupt1           |  02               |
//  | INT2             | Interrupt2           |  -               |
//
//  This software is licensed under the MIT License(http://opensource.org/licenses/MIT).
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
//  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
//  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
//  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//  For information on how to use, visit https://github.com/Protocentral/protocentral-max30003-arduino
//
/////////////////////////////////////////////////////////////////////////////////////////


#ifndef _MAX30003_H
#define _MAX30003_H

#include "main.h"
#include "cmsis_os.h"
#include "delay.h"

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>

#define MAX_SPIx                            SPI2

#define MAX_SPI_SCK_PIN						GPIO_PIN_13
#define MAX_SPI_SCK_GPIO_PORT				GPIOB
#define MAX_SPI_SCK_GPIO_CLK				RCC_AHB1Periph_GPIOB
#define MAX_SPI_SCK_SOURCE					GPIO_PinSource13
#define MAX_SPI_SCK_AF						GPIO_AF5_SPI2

#define MAX_SPI_MISO_PIN					GPIO_PIN_14
#define MAX_SPI_MISO_GPIO_PORT				GPIOB
#define MAX_SPI_MISO_GPIO_CLK				RCC_AHB1Periph_GPIOB
#define MAX_SPI_MISO_SOURCE					GPIO_PinSource14
#define MAX_SPI_MISO_AF						GPIO_AF5_SPI2

#define MAX_SPI_MOSI_PIN					GPIO_PIN_15
#define MAX_SPI_MOSI_GPIO_PORT				GPIOB
#define MAX_SPI_MOSI_GPIO_CLK             	RCC_AHB1Periph_GPIOB
#define MAX_SPI_MOSI_SOURCE					GPIO_PinSource15
#define MAX_SPI_MOSI_AF               	    GPIO_AF5_SPI2

#define MAX_POWER_PIN						GPIO_PIN_10
#define MAX_POWER_GPIO_PORT        			GPIOB
#define MAX_POWER_GPIO_CLK      			RCC_AHB1Periph_GPIOB

#define MAX_CS_PIN							GPIO_PIN_12
#define MAX_CS_GPIO_PORT					GPIOB
#define MAX_CS_GPIO_CLK						RCC_AHB1Periph_GPIOB

#define MAX_IRQ_PIN							GPIO_PIN_7
#define MAX_IRQ_GPIO_PORT					GPIOC
#define MAX_IRQ_GPIO_CLK					RCC_AHB1Periph_GPIOC

// CE Pin  IRQ Pin
#define MAX_CS(x)					x ? HAL_GPIO_WritePin(MAX_CS_GPIO_PORT, MAX_CS_PIN, GPIO_PIN_SET): HAL_GPIO_WritePin(MAX_CS_GPIO_PORT, MAX_CS_PIN, GPIO_PIN_RESET);
#define MAX_IRQ					    (GPIO_ReadInputDataBit(MAX_IRQ_Port,MAX_IRQ_Pin))




#define   NO_OP           0x00
#define   STATUS          0x01
#define   EN_INT          0x02
#define   EN_INT2         0x03
#define   MNGR_INT        0x04
#define   MNGR_DYN        0x05
#define   SW_RST          0x08
#define   SYNCH           0x09
#define   FIFO_RST        0x0A
#define   INFO            0x0F
#define   CNFG_GEN        0x10
#define   CNFG_CAL        0x12
#define   CNFG_EMUX       0x14
#define   CNFG_ECG        0x15
#define   CNFG_RTOR1      0x1D
#define   CNFG_RTOR2      0x1E
#define   ECG_FIFO_BURST  0x20
#define   ECG_FIFO        0x21
#define   RTOR            0x25
//#define   NO_OP           0x7F

#define MAX30003_CS_PIN   7
#define CLK_PIN           6
#define RTOR_INTR_MASK    0x04

#define CHEST_WAIT		  2000//5 примерно ждем устаканивания сигнала
#define HR_ERROR		  777777

#define MAX_HR_HIGH 		  16000
#define MAX_HR_LOW			  4000
#define MAX_HR_WAIT			  750//3c примерно ждем устаканивания сигнала

typedef struct max30003
{
	bool ready;//флаг говорящий что можно читать данные
	bool mode_set; //режим работы прибора выставленный
	bool mode_now; //режим работы прибора текущий
	HAL_StatusTypeDef error;//флаг говорящий об ошибке во время работы требует перезагрузки

	bool 	on_chest;//Флаг говорящий что устройство находится на груди
	bool 	ecg_ok;	 //Флаг говорящий что ЭКГ можно анализировать
	int32_t on_chest_Tim;//таймер

	bool 	hr_to_high;//Флаг говорящий что ЭКГ флаг говорящий что ПУЛЬС выше границы
	int32_t hr_to_high_Tim;//таймер для отправки ошибок

	bool 	hr_to_low;//Флаг говорящий что ЭКГ флаг говорящий что ПУЛЬС ниже границы
	int32_t hr_to_low_Tim;//таймер для отправки ошибок

	int32_t ecg_raw;
	int32_t ecg_f;
	uint32_t heartRate;
	uint32_t RRinterval;
	uint32_t reg_stat;
}max30003_str;

typedef enum
{
  SAMPLINGRATE_128 = 128, SAMPLINGRATE_256 = 256, SAMPLINGRATE_512 = 512
}sampRate;

//моё для настройки коэффициента усиления
typedef enum
{
	Gain20v = 0x00,
	Gain40v = 0x01,
	Gain80v = 0x10,
	Gain160v = 0x11
}ampGain;



void max30003_ready(void);
void max30003_Init_hard(void);
void max30003_Control(max30003_str* MAX);

void SPI_Send_byteMAX(uint8_t data);
uint8_t SPI_Receive_byteMAX(uint8_t data);
void max30003_init(void);
void TIM_init(void);
void max30003Begin(void);
void max30003BeginRtorMode(void);
void max30003SwReset(void);
void getHRandRR(void);
void getEcgSamples(void);
int32_t  getEcgSamples_int(void);
void getEcgSamples_my(void);
int16_t  getEcgSamples_my16(void);
int32_t  getEcgSamples_my32(void);
bool max30003ReadInfo(void);
void max30003SetsamplingRate(uint16_t samplingRate);
void max30003RegRead(uint8_t Reg_address, uint8_t * buff);
uint32_t max30003RegRead_hex(uint8_t Reg_address);
void max30003ReadData(int num_samples, uint8_t * readBuffer);
void max30003Synch(void);
void max30003RegWrite(uint8_t WRITE_ADDRESS, unsigned long data);
void max30003_HR_RR(max30003_str* max30003);
uint32_t max30003_REG(uint8_t Reg_address);
void max30003_GET_ALL(max30003_str* max30003);
void ecg_struct_tres_update(int32_t hr_sig_wait,int32_t hr_high_tres,int32_t hr_low_tres,int32_t hr_Alarm_Tim,int32_t hr_extra);
#endif
