blob: 7a3e5139cf6e540ad074cf263469f07f4f8bdae8 [file] [log] [blame]
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, Inc. All rights reserved.
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* \version 2016.05
* \date 2014-07-31
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \defgroup BOARD_EMSK_DRV_GPIO EMSK GPIO Driver
* \ingroup BOARD_EMSK_DRIVER
* \brief EMSK Onboard GPIO Peripherals Driver
* \details
* Implementation of EMSK on-board button, led, dip switch driver,
* this is for better use, you don't have to get a gpio object before operating
* led,button,switch, because some basic functions for usage are provided.
*/
/**
* \file
* \ingroup BOARD_EMSK_DRV_GPIO
* \brief all on emsk board gpio device init and operate functions
* \details this gpio devices are button, led, dip switch
*/
/**
* \addtogroup BOARD_EMSK_DRV_GPIO
* @{
*/
#include "inc/arc/arc.h"
#include "inc/arc/arc_builtin.h"
#include "inc/embARC_toolchain.h"
#include "inc/embARC_error.h"
#include "board/emsk/gpio/emsk_gpio.h"
#include "board/emsk/emsk.h"
static DEV_GPIO *led_port;
static DEV_GPIO *button_port;
static DEV_GPIO *switch_port;
#define EMSK_GPIO_CHECK_EXP_NORTN(EXPR) CHECK_EXP_NOERCD(EXPR, error_exit)
/** emsk on board gpio init */
void emsk_gpio_init(void)
{
emsk_led_init();
emsk_button_init();
emsk_switch_init();
}
/** emsk on-board led init, led default off */
void emsk_led_init(void)
{
led_port = gpio_get_dev(EMSK_LED_PORT);
EMSK_GPIO_CHECK_EXP_NORTN(led_port != NULL);
if (led_port->gpio_open(EMSK_LED_DIR) == E_OPNED)
{
led_port->gpio_control(GPIO_CMD_SET_BIT_DIR_OUTPUT, (void *)(EMSK_LED_MASK));
led_port->gpio_control(GPIO_CMD_DIS_BIT_INT, (void *)(EMSK_LED_MASK));
}
led_write(0, BOARD_LED_MASK);
error_exit:
return;
}
/** emsk on-board button init */
void emsk_button_init(void)
{
button_port = gpio_get_dev(EMSK_BUTTON_PORT);
EMSK_GPIO_CHECK_EXP_NORTN(button_port != NULL);
if (button_port->gpio_open(EMSK_BUTTON_DIR) == E_OPNED)
{
button_port->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)(EMSK_BUTTON_MASK));
button_port->gpio_control(GPIO_CMD_DIS_BIT_INT, (void *)(EMSK_BUTTON_MASK));
}
error_exit:
return;
}
/** emsk on-board switch init */
void emsk_switch_init(void)
{
switch_port = gpio_get_dev(EMSK_SWITCH_PORT);
EMSK_GPIO_CHECK_EXP_NORTN(switch_port != NULL);
if (switch_port->gpio_open(EMSK_SWITCH_DIR) == E_OPNED)
{
switch_port->gpio_control(GPIO_CMD_SET_BIT_DIR_INPUT, (void *)(EMSK_SWITCH_MASK));
switch_port->gpio_control(GPIO_CMD_DIS_BIT_INT, (void *)(EMSK_SWITCH_MASK));
}
error_exit:
return;
}
/**
* workaround for get led value
* because gpio read return is not right
*/
static uint32_t g_led_val;
/** write 1 to light on led bit, else light off led */
void led_write(uint32_t led_val, uint32_t mask)
{
EMSK_GPIO_CHECK_EXP_NORTN(led_port != NULL);
led_val = (~led_val) & mask;
led_val = led_val << EMSK_LED_OFFSET;
mask = (mask << EMSK_LED_OFFSET) & EMSK_LED_MASK;
led_port->gpio_write(led_val, mask);
g_led_val = led_val;
error_exit:
return;
}
/** read led value, on for 1, off for 0 */
/** \todo need to find why when led set to output then can't get the right value of led */
uint32_t led_read(uint32_t mask)
{
uint32_t value;
EMSK_GPIO_CHECK_EXP_NORTN(led_port != NULL);
mask = (mask << EMSK_LED_OFFSET) & EMSK_LED_MASK;
led_port->gpio_read(&value, mask);
value = (~value) & EMSK_LED_MASK;
return (value >> EMSK_LED_OFFSET);
error_exit:
return 0;
}
/** Pull down switch return 1, else 0 */
uint32_t switch_read(uint32_t mask)
{
uint32_t value;
EMSK_GPIO_CHECK_EXP_NORTN(switch_port != NULL);
mask = (mask << EMSK_SWITCH_OFFSET) & EMSK_SWITCH_MASK;
switch_port->gpio_read(&value, mask);
value = (~value) & mask;
return (value >> EMSK_SWITCH_OFFSET);
error_exit:
return 0;
}
/** Press down bit set to 1 else 0 */
uint32_t button_read(uint32_t mask)
{
uint32_t value;
EMSK_GPIO_CHECK_EXP_NORTN(button_port != NULL);
mask = (mask << EMSK_BUTTON_OFFSET) & EMSK_BUTTON_MASK;
button_port->gpio_read(&value, mask);
value = (~value) & mask;
return (value >> EMSK_BUTTON_OFFSET);
error_exit:
return 0;
}
/** @} end of group BOARD_EMSK_DRV_GPIO */