Rev 31 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| Download
| RSS feed
/**************************************************************************//**
* \brief MCP23008 library
* \author Copyright (C) 2012 Julien Le Sech - www.idreammicro.com
* \version 1.0
* \date 201201025
*
* This file is part of the iDreamMicro library.
*
* This library is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see http://www.gnu.org/licenses/
******************************************************************************/
/**************************************************************************//**
* \file mcp23008.c
******************************************************************************/
/******************************************************************************
* Header file inclusions.
******************************************************************************/
#include <mcp23008/mcp23008.h>
#include <twi/twi.h>
#include <useful/bits.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
/******************************************************************************
* Private macros.
******************************************************************************/
#define MCP23008__ADDRESS 0x20
#define MCP23008__REG_IODIR 0x00
#define MCP23008__REG_IPOL 0x01
#define MCP23008__REG_GPINTEN 0x02
#define MCP23008__REG_DEFVAL 0x03
#define MCP23008__REG_INTCON 0x04
#define MCP23008__REG_IOCON 0x05
#define MCP23008__REG_GPPU 0x06
#define MCP23008__REG_INTF 0x07
#define MCP23008__REG_INTCAP 0x08
#define MCP23008__REG_GPIO 0x09
#define MCP23008__REG_OLAT 0x0A
#define MCP23008__CLOCK_RATE 400000
/******************************************************************************
* Private function prototypes.
******************************************************************************/
/**************************************************************************//**
*
******************************************************************************/
static
uint8_t
mcp23008__read_register
(
uint8_t address
);
/**************************************************************************//**
*
******************************************************************************/
static
void
mcp23008__write_register
(
uint8_t address,
uint8_t value
);
/******************************************************************************
* Private variable declarations.
******************************************************************************/
static uint8_t mcp23008__twi_address = 0;
/******************************************************************************
* Public function definitions.
******************************************************************************/
/**************************************************************************//**
* \fn void mcp23008__initialize(uint8_t hardware_address)
*
* \brief Initialize MCP23008.
*
* \param hardware_address Hardware address defined by pins A0 to A2.
******************************************************************************/
void
mcp23008__initialize
(
uint8_t hardware_address
){
// Initialize TWI.
twi__initialize(MCP23008__CLOCK_RATE);
// Compute MCP23008 TWI address.
mcp23008__twi_address = (MCP23008__ADDRESS | hardware_address) << 1;
twi__start();
twi__send_slaw(mcp23008__twi_address);
twi__send_data(MCP23008__REG_IODIR);
twi__send_data(0xFF);
twi__send_data(0x00);
twi__send_data(0x00);
twi__send_data(0x00);
twi__send_data(0x00);
twi__send_data(0x00);
twi__send_data(0x00);
twi__send_data(0x00);
twi__send_data(0x00);
twi__send_data(0x00);
twi__stop();
}
/**************************************************************************//**
*
******************************************************************************/
void
mcp23008__configure_pin
(
mcp23008__gpio_t pin,
mcp23008__direction_t direction
){
uint8_t port_configuration = mcp23008__read_register(MCP23008__REG_IODIR);
if (MCP23008__DIRECTION__INPUT == direction)
{
BIT__SET(port_configuration, pin);
}
else
{
BIT__RST(port_configuration, pin);
}
mcp23008__write_register(MCP23008__REG_IODIR, port_configuration);
}
/**************************************************************************//**
*
******************************************************************************/
void
mcp23008__configure_port
(
mcp23008__direction_t direction
){
mcp23008__write_register(MCP23008__REG_IODIR, direction);
}
/**************************************************************************//**
*
******************************************************************************/
mcp23008__level_t
mcp23008__get_pin_level
(
mcp23008__gpio_t pin
){
uint8_t port_value = mcp23008__read_register(MCP23008__REG_GPIO);
mcp23008__level_t level = BIT__TST(port_value, pin);
return level;
}
/**************************************************************************//**
*
******************************************************************************/
void
mcp23008__set_pin_level
(
mcp23008__gpio_t pin,
mcp23008__level_t level
){
uint8_t port_value = mcp23008__read_register(MCP23008__REG_GPIO);
if (MCP23008__LEVEL__HIGH == level)
{
BIT__SET(port_value, pin);
}
else
{
BIT__RST(port_value, pin);
}
mcp23008__write_register(MCP23008__REG_GPIO, port_value);
}
/**************************************************************************//**
*
******************************************************************************/
uint8_t
mcp23008__get_port_value
(
void
){
uint8_t value = mcp23008__read_register(MCP23008__REG_GPIO);
return value;
}
/**************************************************************************//**
*
******************************************************************************/
void
mcp23008__set_port_value
(
uint8_t value
){
mcp23008__write_register(MCP23008__REG_GPIO, value);
}
/******************************************************************************
* Private function definitions.
******************************************************************************/
/**************************************************************************//**
*
******************************************************************************/
static
uint8_t
mcp23008__read_register
(
uint8_t address
){
uint8_t value = 0;
twi__start();
twi__send_slaw(mcp23008__twi_address);
twi__send_data(address);
twi__stop();
twi__start();
twi__send_slar(mcp23008__twi_address);
twi__receive_data_nack(&value);
twi__stop();
return value;
}
/**************************************************************************//**
*
******************************************************************************/
static
void
mcp23008__write_register
(
uint8_t address,
uint8_t value
){
twi__start();
twi__send_slaw(mcp23008__twi_address);
twi__send_data(address);
twi__send_data(value);
twi__stop();
}