/*
 * MikroSDK - MikroE Software Development Kit
 * Copyright© 2020 MikroElektronika d.o.o.
 * 
 * Permission is hereby granted, free of charge, to any person 
 * obtaining a copy of this software and associated documentation 
 * files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, 
 * publish, distribute, sublicense, and/or sell copies of the Software, 
 * and to permit persons to whom the Software is furnished to do so, 
 * subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be 
 * included in all copies or substantial portions of the Software.
 * 
 * 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. 
 */

/*!
 * \file
 *
 */

#include "diffpressure.h"

// ------------------------------------------------------------- PRIVATE MACROS 

#define DIFFPRESSURE_DUMMY 0

// ------------------------------------------------ PUBLIC FUNCTION DEFINITIONS

void diffpressure_cfg_setup ( diffpressure_cfg_t *cfg )
{
    // Communication gpio pins 

    cfg->sck = HAL_PIN_NC;
    cfg->miso = HAL_PIN_NC;
    cfg->mosi = HAL_PIN_NC;
    cfg->cs = HAL_PIN_NC;

    cfg->spi_mode = SPI_MASTER_MODE_0;
    cfg->cs_polarity = SPI_MASTER_CHIP_SELECT_POLARITY_ACTIVE_LOW;
    cfg->spi_speed = 100000; 
}

DIFFPRESSURE_RETVAL diffpressure_init ( diffpressure_t *ctx, diffpressure_cfg_t *cfg )
{
    spi_master_config_t spi_cfg;

    spi_master_configure_default( &spi_cfg );
    spi_cfg.speed     = cfg->spi_speed;
    spi_cfg.mode      = cfg->spi_mode;
    spi_cfg.sck       = cfg->sck;
    spi_cfg.miso      = cfg->miso;
    spi_cfg.mosi      = cfg->mosi;
    spi_cfg.default_write_data = DIFFPRESSURE_DUMMY;

//     digital_out_init( &ctx->cs, cfg->cs );
    ctx->chip_select = cfg->cs;

    if (  spi_master_open( &ctx->spi, &spi_cfg ) == SPI_MASTER_ERROR )
    {
        return DIFFPRESSURE_INIT_ERROR;
    }

    spi_master_deselect_device( &ctx->spi );
    spi_master_set_default_write_data( &ctx->spi, DIFFPRESSURE_DUMMY );
    spi_master_set_mode( &ctx->spi, spi_cfg.mode );
    spi_master_set_speed( &ctx->spi, spi_cfg.speed );
    spi_master_set_chip_select_polarity( cfg->cs_polarity );

    return DIFFPRESSURE_OK;
}

void diffpressure_generic_transfer ( diffpressure_t *ctx, uint8_t *wr_buf, 
                                    uint16_t wr_len, uint8_t *rd_buf, uint16_t rd_len )
{
    spi_master_select_device( ctx->chip_select );
    spi_master_write_then_read( &ctx->spi, wr_buf, wr_len, rd_buf, rd_len );
    spi_master_deselect_device( ctx->chip_select ); 
}

int32_t diffpressure_read_data ( diffpressure_t *ctx )
{
    uint8_t buffer[ 3 ] = { 0 };
    int32_t result = 0;

    spi_master_select_device( ctx->chip_select );
    Delay_100ms( );
    spi_master_read( &ctx->spi, buffer, 3 );
    spi_master_deselect_device( ctx->chip_select );  
    
    result = buffer[ 0 ];
    result <<= 8;
    result |= buffer[ 1 ];
    result <<= 8;
    result |= buffer[ 2 ];
    
    if ( ( buffer[ 0 ] & 0x20 ) >> 5 )       
    {
        result = result - 4194304;       
    }

    return result;
}

int32_t diffpressure_get_kpa_difference ( diffpressure_t *ctx, int32_t difference )
{
    float press;
    float volt;
    int32_t result;

    volt = ( 5.0f / 2097151.0f ) * ( float ) difference;
    press = ( volt / 0.45f ) - 0.45f;
    
    result = ( int32_t ) ( press * 1000.0f );

    return result;
}

status_t diffpressure_status_check ( diffpressure_t *ctx, int32_t result )
{
    if ( !result )
    { 
        return NOT_RDY;
    }

    if ( result > 0x00BFFFFE ) 
    {
        return OVH;
    }

    if ( result > 0x009FFFFF )
    {
        return OVL;
    }
    return OK;
}

// ------------------------------------------------------------------------- END

