From 4619d3819c44f9a6bd64969bec068340250204c6 Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Fri, 28 Apr 2017 11:25:01 +0530 Subject: [PATCH] Refactor pcf8574 code --- pcf8574/main.c | 104 +++++++++++++++++++++++ pcf8574/pcf8574.c | 204 ++++++++++------------------------------------ pcf8574/pcf8574.h | 29 +++++++ 3 files changed, 175 insertions(+), 162 deletions(-) create mode 100644 pcf8574/main.c create mode 100644 pcf8574/pcf8574.h diff --git a/pcf8574/main.c b/pcf8574/main.c new file mode 100644 index 0000000..d6aa114 --- /dev/null +++ b/pcf8574/main.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include + +#include "pcf8574.h" + +/* See the Pioneer 600 Schematic */ +static uint8_t LED_ON = 0xEF; +static uint8_t LED_OFF = 0xFF; +static uint8_t BUZZER_ON = 0x7F; +static uint8_t BUZZER_OFF = 0xFF; + +void pioneer600_led2_on(i2c *i2c) +{ + pcf8574_port_write(i2c, LED_ON); +} + +void pioneer600_led2_off(i2c *i2c) +{ + pcf8574_port_write(i2c, LED_OFF); +} + +void pioneer600_buzzer_on(i2c *i2c) +{ + pcf8574_port_write(i2c, BUZZER_ON); +} + +void pioneer600_buzzer_off(i2c *i2c) +{ + pcf8574_port_write(i2c, BUZZER_OFF); +} + +void pioneer600_read_joystick(i2c *i2c) +{ + uint8_t port; + port = pcf8574_port_read(i2c); + + if (!(port & 0x01)) + printf("Key A pressed\n"); + else if (!(port & 0x02)) + printf("Key B pressed\n"); + else if (!(port & 0x04)) + printf("Key C pressed\n"); + else if (!(port & 0x08)) + printf("Key D pressed\n"); + else if (port & 0x0F) + printf("No keys pressed\n"); +} + +int main(void) +{ + i2c *i2c_pcf8574; + uint8_t led_status = LED_OFF; + uint8_t buzzer_status = BUZZER_OFF; + uint32_t input; + uint8_t ret = 0; + + i2c_pcf8574 = pcf8574_init(0, PCF8574_ADDRESS); + if (i2c_pcf8574 == NULL) + return EXIT_FAILURE; + + while (true) { + printf("\nEnter choice: 1. Joy stick status 2. Led On/Off 3. Buzzer On/Off 4. Exit\n"); + scanf("%d", &input); + switch (input) { + case 1: + pioneer600_read_joystick(i2c_pcf8574); + break; + case 2: + if (led_status == LED_OFF) { + pioneer600_led2_on(i2c_pcf8574); + led_status = LED_ON; + } else { + pioneer600_led2_off(i2c_pcf8574); + led_status = LED_OFF; + } + break; + case 3: + if (buzzer_status == BUZZER_OFF) { + pioneer600_buzzer_on(i2c_pcf8574); + buzzer_status = BUZZER_ON; + } else { + pioneer600_buzzer_off(i2c_pcf8574); + buzzer_status = BUZZER_OFF; + } + break; + case 4: + goto exit; + break; + default: + printf("Enter valid input\n"); + break; + } + } + +exit: + ret = pcf8574_free(i2c_pcf8574); + if (ret == EXIT_FAILURE) + perror("Failed to close I2C port"); + + return 0; +} diff --git a/pcf8574/pcf8574.c b/pcf8574/pcf8574.c index 40564ae..51ec15c 100644 --- a/pcf8574/pcf8574.c +++ b/pcf8574/pcf8574.c @@ -1,207 +1,87 @@ +/* + * pcf8574.c + * PCF8574 IO expander helper functions using libsoc API. + * + * libsoc i2c API Documentation: http://jackmitch.github.io/libsoc/c/i2c/#i2c + * + * Copyright (C) 2017 - BhuvanChandra DV + * + */ + #include #include #include #include -#include -#include -#include -#include -/* PCF8574 I2C Address on Pioneer 600 */ -#define PCF8574_ADDRESS 0x20 - -static uint8_t LED_ON = 0xEF; -static uint8_t LED_OFF = 0xFF; -static uint8_t BUZZER_ON = 0x7F; -static uint8_t BUZZER_OFF = 0xFF; - -/* - * libsoc i2c API Documentation: http://jackmitch.github.io/libsoc/c/i2c/#i2c - */ +#include "pcf8574.h" i2c* pcf8574_init(uint8_t i2c_bus, uint8_t i2c_address) { - i2c *i2c; - uint8_t ret; - uint8_t buf[1] = {0}; + i2c *i2c = libsoc_i2c_init(i2c_bus, i2c_address); - i2c = libsoc_i2c_init(i2c_bus, i2c_address); if (i2c == NULL) { perror("libsoc_i2c_init failed"); return i2c; } - /* - * http://cache.nxp.com/documents/data_sheet/PCF8574_PCF8574A.pdf - * See Page 7 of the data sheet Quasi-bidirectional I/Os - * Default all expander pins as input - */ - buf[0] = 0xff; - ret = libsoc_i2c_write(i2c, buf, 1); - if (ret == EXIT_FAILURE) { - perror("PCF8574 initialization failed"); - libsoc_i2c_free(i2c); - return NULL; - } - return i2c; } -int pcf8574_close(i2c *i2c) +int pcf8574_free(i2c *i2c) { return libsoc_i2c_free(i2c); } -int pioneer600_led2_on(i2c *i2c) +uint8_t pcf8574_port_read(i2c *i2c) { - uint8_t ret; - uint8_t buf[1] = {0}; + uint8_t res; - buf[0] = LED_ON; - ret = libsoc_i2c_write(i2c, buf, 1); - if (ret == EXIT_FAILURE) - perror("I2C write failed"); + if (libsoc_i2c_read(i2c, &res, 1)) + return 0; - return ret; + return res; } -int pioneer600_led2_off(i2c *i2c) +size_t pcf8574_port_read_buf(i2c *i2c, void *buf, size_t len) { - uint8_t ret; - uint8_t buf[1] = {0}; + uint8_t *_buf = (uint8_t *)buf; - buf[0] = LED_OFF; - ret = libsoc_i2c_write(i2c, buf, 1); - if (ret == EXIT_FAILURE) - perror("I2C write failed"); + if (!len || !buf) + return 0; - return ret; + if (libsoc_i2c_read(i2c, _buf, len)) + return 0; + + return len; } -int pioneer600_buzzer_on(i2c *i2c) +size_t pcf8574_port_write_buf(i2c *i2c, void *buf, size_t len) { - uint8_t ret; - uint8_t buf[1] = {0}; + uint8_t *_buf = (uint8_t *)buf; - buf[0] = BUZZER_ON; - ret = libsoc_i2c_write(i2c, buf, 1); - if (ret == EXIT_FAILURE) - perror("I2C write failed"); + if (!len || !buf) + return 0; - return ret; + if (libsoc_i2c_write(i2c, _buf, len)) + return 0; + + return len; } -int pioneer600_buzzer_off(i2c *i2c) +void pcf8574_port_write(i2c *i2c, uint8_t value) { - uint8_t ret; - uint8_t buf[1] = {0}; - - buf[0] = BUZZER_OFF; - ret = libsoc_i2c_write(i2c, buf, 1); - if (ret == EXIT_FAILURE) - perror("I2C write failed"); - - return ret; + libsoc_i2c_write(i2c, &value, 1); } -void pioneer600_read_joystick(i2c *i2c) +bool pcf8574_gpio_read(i2c *i2c, uint8_t num) { - uint8_t ret; - uint8_t buf[1] = {0}; - - ret = libsoc_i2c_read(i2c, buf, 1); - if (ret == EXIT_FAILURE) - perror("I2C read failed"); - else { - if (buf[0] & 0x0F) - printf("No keys pressed\n"); - - if (!(buf[0] & 0x01)) - printf("Key A pressed\n"); - - if (!(buf[0] & 0x02)) - printf("Key B pressed\n"); - - if (!(buf[0] & 0x04)) - printf("Key C pressed\n"); - - if (!(buf[0] & 0x08)) - printf("Key D pressed\n"); - } - - return; + return (bool)((pcf8574_port_read(i2c) >> num) & 1); } -int main(void) +void pcf8574_gpio_write(i2c *i2c, uint8_t num, bool value) { - i2c *i2c_pcf8574; - uint8_t led_status = LED_OFF; - uint8_t buzzer_status = BUZZER_OFF; - uint32_t input; - uint8_t ret = 0; + uint8_t bit = (uint8_t)!value << num; + uint8_t mask = ~(1 << num); - i2c_pcf8574 = pcf8574_init(0, PCF8574_ADDRESS); - if (i2c_pcf8574 == NULL) - return EXIT_FAILURE; - - while (true) { - printf("\nEnter choice: 1. Joy stick status 2. Led On/Off 3. Buzzer On/Off 4. Exit\n"); - scanf("%d", &input); - switch (input) { - case 1: - pioneer600_read_joystick(i2c_pcf8574); - break; - case 2: - if (led_status == LED_OFF) { - ret = pioneer600_led2_on(i2c_pcf8574); - if (ret == EXIT_FAILURE) - printf("Led turn on failed\n"); - else { - led_status = LED_ON; - printf("Led On\n"); - } - } else { - ret = pioneer600_led2_off(i2c_pcf8574); - if (ret == EXIT_FAILURE) - printf("Led turn off failed\n"); - else { - led_status = LED_OFF; - printf("Led Off\n"); - } - } - break; - case 3: - if (buzzer_status == BUZZER_OFF) { - ret = pioneer600_buzzer_on(i2c_pcf8574); - if (ret == EXIT_FAILURE) - printf("Buzzer turn on failed\n"); - else { - buzzer_status = BUZZER_ON; - printf("Buzzer On\n"); - } - } else { - ret = pioneer600_buzzer_off(i2c_pcf8574); - if (ret == EXIT_FAILURE) - printf("Buzzer turn off failed\n"); - else { - buzzer_status = BUZZER_OFF; - printf("Buzzer Off\n"); - } - } - break; - case 4: - goto exit; - break; - default: - printf("Enter valid input\n"); - break; - } - } - -exit: - ret = pcf8574_close(i2c_pcf8574); - if (ret == EXIT_FAILURE) - perror("Failed to close I2C port"); - - return 0; + pcf8574_port_write (i2c, (pcf8574_port_read(i2c) & mask) | bit); } diff --git a/pcf8574/pcf8574.h b/pcf8574/pcf8574.h new file mode 100644 index 0000000..88537fa --- /dev/null +++ b/pcf8574/pcf8574.h @@ -0,0 +1,29 @@ +/* + * pcf8574.h + * + * Created on: Apr 28, 2017 + * Author: sanchayan + */ + +#ifndef PCF8574_H_ +#define PCF8574_H_ + +#include +#include +#include + +#include + +/* PCF8574 I2C Address on Pioneer 600 */ +#define PCF8574_ADDRESS 0x20 + +i2c* pcf8574_init(uint8_t i2c_bus, uint8_t i2c_address); +int pcf8574_free(i2c *i2c); +uint8_t pcf8574_port_read(i2c *i2c); +size_t pcf8574_port_read_buf(i2c *i2c, void *buf, size_t len); +void pcf8574_port_write(i2c *i2c, uint8_t value); +size_t pcf8574_port_write_buf(i2c *i2c, void *buf, size_t len); +bool pcf8574_gpio_read(i2c *i2c, uint8_t num); +void pcf8574_gpio_write(i2c *i2c, uint8_t num, bool value); + +#endif /* PCF8574_H_ */