| 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(); |
| } |