/*
Copyright (c) 2015, Dust Networks. All rights reserved.

Port of the endianness module to the ADuCM4050

\license See attached DN_LICENSE.txt.
*/

#include "dn_endianness.h"

//=========================== variables =======================================

//=========================== prototypes ======================================

//=========================== public ==========================================

//==== write operations
void dn_write_uint16_t(uint8_t* ptr, uint16_t val)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    ptr[0]     = (val>>8)  & 0xff;
    ptr[1]     = (val>>0)  & 0xff;
    __enable_irq();
}

void dn_write_uint24_t(uint8_t* ptr, uint32_t val)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    ptr[0]     = (val>>16) & 0xff;
    ptr[1]     = (val>>8)  & 0xff;
    ptr[2]     = (val>>0)  & 0xff;
    __enable_irq();
}

void dn_write_uint32_t(uint8_t* ptr, uint32_t val)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    ptr[0]     = (val>>24) & 0xff;
    ptr[1]     = (val>>16) & 0xff;
    ptr[2]     = (val>>8)  & 0xff;
    ptr[3]     = (val>>0)  & 0xff;
    __enable_irq();
}

void dn_write_int32_t(uint8_t* ptr,  int32_t val)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    ptr[0]     = (val>>24) & 0xff;
    ptr[1]     = (val>>16) & 0xff;
    ptr[2]     = (val>>8)  & 0xff;
    ptr[3]     = (val>>0)  & 0xff;
    __enable_irq();
}

void dn_write_float(uint8_t* ptr, float val)
{
    float *pVal = &val;

    __disable_irq();
    // float in reversed order
    ptr[0]     = *((uint8_t*)pVal + 3) & 0xff;
    ptr[1]     = *((uint8_t*)pVal + 2) & 0xff;
    ptr[2]     = *((uint8_t*)pVal + 1) & 0xff;
    ptr[3]     = *((uint8_t*)pVal)     & 0xff;
    __enable_irq();
}

//==== read operations
void dn_read_uint16_t(uint16_t* to, const uint8_t* from)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    *to        = 0;
    *to       |= (from[1]<<0);
    *to       |= (from[0]<<8);
    __enable_irq();
}

void dn_read_uint24_t(uint32_t* to, const uint8_t* from)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    *to        = 0;
    *to       |= ( ((uint32_t)from[2])<<0 );
    *to       |= ( ((uint32_t)from[1])<<8 );
    *to       |= ( ((uint32_t)from[0])<<16);
    __enable_irq();
}

void dn_read_uint32_t(uint32_t* to, const uint8_t* from)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    *to        = 0;
    *to       |= ( ((uint32_t)from[3])<<0 );
    *to       |= ( ((uint32_t)from[2])<<8 );
    *to       |= ( ((uint32_t)from[1])<<16);
    *to       |= ( ((uint32_t)from[0])<<24);
    __enable_irq();
}

void dn_read_int32_t(int32_t* to, const uint8_t* from)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    *to        = 0;
    *to       |= ( ((uint32_t)from[3])<<0 );
    *to       |= ( ((uint32_t)from[2])<<8 );
    *to       |= ( ((uint32_t)from[1])<<16);
    *to       |= ( ((uint32_t)from[0])<<24);
    __enable_irq();
}

void dn_read_float(float* to, const uint8_t* from)
{
    __disable_irq();
    // ADuCM4050 is a little-endian platform
    // float in reversed order
    *((uint8_t*)to + 3) = from[0];
    *((uint8_t*)to + 2) = from[1];
    *((uint8_t*)to + 1) = from[2];
    *((uint8_t*)to    ) = from[3];
    __enable_irq();
}

//=========================== private =========================================

//=========================== helpers =========================================
