Refactor pcf8574 code
This commit is contained in:
parent
1f76a72c2b
commit
4619d3819c
3 changed files with 175 additions and 162 deletions
104
pcf8574/main.c
Normal file
104
pcf8574/main.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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 <bhuvanchandradv@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <libsoc_i2c.h>
|
||||
|
||||
/* 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};
|
||||
|
||||
buf[0] = LED_ON;
|
||||
ret = libsoc_i2c_write(i2c, buf, 1);
|
||||
if (ret == EXIT_FAILURE)
|
||||
perror("I2C write failed");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pioneer600_led2_off(i2c *i2c)
|
||||
{
|
||||
uint8_t ret;
|
||||
uint8_t buf[1] = {0};
|
||||
|
||||
buf[0] = LED_OFF;
|
||||
ret = libsoc_i2c_write(i2c, buf, 1);
|
||||
if (ret == EXIT_FAILURE)
|
||||
perror("I2C write failed");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pioneer600_buzzer_on(i2c *i2c)
|
||||
{
|
||||
uint8_t ret;
|
||||
uint8_t buf[1] = {0};
|
||||
|
||||
buf[0] = BUZZER_ON;
|
||||
ret = libsoc_i2c_write(i2c, buf, 1);
|
||||
if (ret == EXIT_FAILURE)
|
||||
perror("I2C write failed");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pioneer600_buzzer_off(i2c *i2c)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void pioneer600_read_joystick(i2c *i2c)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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");
|
||||
uint8_t res;
|
||||
|
||||
if (libsoc_i2c_read(i2c, &res, 1))
|
||||
return 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t pcf8574_port_read_buf(i2c *i2c, void *buf, size_t len)
|
||||
{
|
||||
uint8_t *_buf = (uint8_t *)buf;
|
||||
|
||||
if (!len || !buf)
|
||||
return 0;
|
||||
|
||||
if (libsoc_i2c_read(i2c, _buf, len))
|
||||
return 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t pcf8574_port_write_buf(i2c *i2c, void *buf, size_t len)
|
||||
{
|
||||
uint8_t *_buf = (uint8_t *)buf;
|
||||
|
||||
if (!len || !buf)
|
||||
return 0;
|
||||
|
||||
if (libsoc_i2c_write(i2c, _buf, len))
|
||||
return 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void pcf8574_port_write(i2c *i2c, uint8_t value)
|
||||
{
|
||||
libsoc_i2c_write(i2c, &value, 1);
|
||||
}
|
||||
|
||||
bool pcf8574_gpio_read(i2c *i2c, uint8_t num)
|
||||
{
|
||||
return (bool)((pcf8574_port_read(i2c) >> num) & 1);
|
||||
}
|
||||
|
||||
void pcf8574_gpio_write(i2c *i2c, uint8_t num, bool value)
|
||||
{
|
||||
uint8_t bit = (uint8_t)!value << num;
|
||||
uint8_t mask = ~(1 << num);
|
||||
|
||||
pcf8574_port_write (i2c, (pcf8574_port_read(i2c) & mask) | bit);
|
||||
}
|
||||
|
|
29
pcf8574/pcf8574.h
Normal file
29
pcf8574/pcf8574.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* pcf8574.h
|
||||
*
|
||||
* Created on: Apr 28, 2017
|
||||
* Author: sanchayan
|
||||
*/
|
||||
|
||||
#ifndef PCF8574_H_
|
||||
#define PCF8574_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <libsoc_i2c.h>
|
||||
|
||||
/* 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_ */
|
Loading…
Reference in a new issue