/*********************************************************************
 *                  Flowcode CAL IO File
 *
 * File: AVR_CAL_IO.c
 *
 * (c) 2011 Matrix Multimedia Ltd.
 * http://www.matrixmultimedia.com
 *
 * Software License Agreement
 *
 * The software supplied herewith by Matrix Multimedia Ltd (the
 * “Company”) for its Flowcode graphical programming language is
 * intended and supplied to you, the Company’s customer, for use
 * solely and exclusively on the Company's products. The software
 * is owned by the Company, and is protected under applicable
 * copyright laws. All rights are reserved. Any use in violation
 * of the foregoing restrictions may subject the user to criminal
 * sanctions under applicable laws, as well as to civil liability
 * for the breach of the terms and conditions of this licence.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 * Changelog:
 *
 *  date  | by | description
 * -------+----+-----------------------------------------------------
 * 010911 | SK | Created
 * 050911 | BR | Added 10F and 12F compatible I/O functions
 * 020312 | BR | Updated to v5.1 CAL Schema
 *
 */

#include "STARM_CAL_IO.h"

static void FC_CAL_Port_Out__x (GPIO_TypeDef *PORT, uint16_t OutMask, uint16_t OutValue)
{
	PORT->ODR = (PORT->ODR & ~OutMask) | (OutValue & OutMask);
}


static void FC_CAL_Port_Out_DDR__x (GPIO_TypeDef *PORT, MX_UINT16 OutMask, MX_UINT16 OutValue)
{
	GPIO_InitTypeDef  GPIO_InitStruct;

	// Configure outputs
	GPIO_InitStruct.Pin = OutMask;
	GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull  = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(PORT, &GPIO_InitStruct);

	PORT->ODR = (PORT->ODR & ~OutMask) | (OutValue & OutMask);
}


static MX_UINT8 FC_CAL_Port_In__x (GPIO_TypeDef *PORT, MX_UINT16 InMask, MX_UINT16 Shift)
{
	return (PORT->IDR & InMask) >> Shift;
}


static MX_UINT16 FC_CAL_Port_In_DDR__x (GPIO_TypeDef *PORT, MX_UINT16 InMask, MX_UINT16 Shift)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	
	// Configure inputs
	GPIO_InitStruct.Pin = InMask;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(PORT, &GPIO_InitStruct);
	
	return (PORT->IDR & InMask) >> Shift;
}


static MX_UINT16 FC_CAL_Bit_In__x(GPIO_TypeDef *PORT, MX_UINT16 Pin)
{
		return test_bit(PORT->IDR, Pin);
}

static MX_UINT16 FC_CAL_Bit_In_DDR__x(GPIO_TypeDef *PORT, MX_UINT16 Pin)
{
#if defined GPIO_MODER_MODER0
	PORT->MODER = PORT->MODER & ~(3<<((Pin)*2));
	return test_bit(PORT->IDR, Pin);
#elif defined GPIO_CRH_MODE
    if (Pin < 8)
	{
		PORT->CRL = PORT->CRL&~(3<<((Pin)*4));
	}
	else
	{
		PORT->CRH = PORT->CRH&~(3<<((Pin&7)*4));
	};
	return test_bit(PORT->IDR, Pin);
#else
	return FC_CAL_Port_In_DDR__x (PORT, (1 << Pin), (Pin));
#endif
}

