0,0 → 1,269 |
/**************************************************************************//** |
* \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(); |
} |