From fed13089ed131057b684c3569cfc8dc0234440ac Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Mon, 24 Apr 2017 15:34:29 +0530 Subject: [PATCH] Rewrite PCF8574 code enabling all functionality for Pioneer 600 --- pcf8574/pcf8574.c | 272 +++++++++++++++++++++++++++++----------------- 1 file changed, 172 insertions(+), 100 deletions(-) diff --git a/pcf8574/pcf8574.c b/pcf8574/pcf8574.c index cc6a2ea..40564ae 100644 --- a/pcf8574/pcf8574.c +++ b/pcf8574/pcf8574.c @@ -10,111 +10,41 @@ /* PCF8574 I2C Address on Pioneer 600 */ #define PCF8574_ADDRESS 0x20 -static uint8_t RS = 0x01; -static uint8_t EN = 0x04; -static uint8_t BL = 0x08; +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 */ -int pulse_enable(i2c *i2c, uint8_t data) -{ - uint32_t ret; - uint8_t buf[4] = {0}; - - buf[0] = data | EN; - ret = libsoc_i2c_write(i2c, buf, 1); - if (ret == EXIT_FAILURE) - return ret; - - usleep(1); - - buf[0] = data & ~EN; - ret = libsoc_i2c_write(i2c, buf, 1); - - return ret; -} - -int pcf8574_write_cmd4(i2c *i2c, uint8_t command) -{ - uint32_t ret; - uint8_t buf[4] = {0}; - - buf[0] = command | BL; - ret = libsoc_i2c_write(i2c, buf, 1); - if (ret == EXIT_FAILURE) - return ret; - - ret = pulse_enable(i2c, command | BL); - if (ret == EXIT_FAILURE) - perror("Pulse enable failed\n"); - - return ret; -} - -int pcf8574_write_cmd8(i2c *i2c, uint8_t command) -{ - uint32_t ret; - uint8_t command_H = command & 0xf0; - uint8_t command_L = (command << 4) & 0xf0; - - ret = pcf8574_write_cmd4(i2c, command_H); - if (ret == EXIT_FAILURE) { - perror("Failed to write command high 4 bits"); - return ret; - } - - ret = pcf8574_write_cmd4(i2c, command_L); - if (ret == EXIT_FAILURE) { - perror("Failed to write command low 4 bits"); - return ret; - } - - return EXIT_SUCCESS; -} - -int pcf8574_write_data4(i2c *i2c, uint8_t data) -{ - uint32_t ret; - uint8_t buf[4] = {0}; - - buf[0] = data | RS | BL; - ret = libsoc_i2c_write(i2c, buf, 1); - if (ret == EXIT_FAILURE) - return ret; - - ret = pulse_enable(i2c, data | RS | BL); - if (ret == EXIT_FAILURE) - perror("Pulse enable failed\n"); - - return ret; -} - -int pcf8574_write_data8(i2c *i2c, uint8_t data) -{ - uint8_t ret; - uint8_t data_H = data & 0xf0; - uint8_t data_L = (data << 4) & 0xf0; - - ret = pcf8574_write_data4(i2c, data_H); - if (ret == EXIT_FAILURE) { - perror("Failed to write data high 4 bits"); - return ret; - } - - ret = pcf8574_write_data4(i2c, data_L); - if (ret == EXIT_FAILURE) { - perror("Failed to write data low 4 bits"); - return ret; - } - - return ret; -} - i2c* pcf8574_init(uint8_t i2c_bus, uint8_t i2c_address) { - return libsoc_i2c_init(i2c_bus, i2c_address); + i2c *i2c; + uint8_t ret; + uint8_t buf[1] = {0}; + + 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) @@ -122,14 +52,156 @@ int pcf8574_close(i2c *i2c) return libsoc_i2c_free(i2c); } +int pioneer600_led2_on(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); - pcf8574_write_data8(i2c_pcf8574, 0xff); + if (i2c_pcf8574 == NULL) + return EXIT_FAILURE; - pcf8574_close(i2c_pcf8574); + 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; }