esp-open-rtosを使ってみる

IO-Expander(PCF8574)

こちらで、HD44780のサンプルを調べていた時に、PCF8574でディジタルポー トを拡張するAPIが有ることが分かりました。
以下のコードで、PCF8574のP0からP7に接続したLEDがLチカします。

pcf8574_port_write()を使うと、8ビットを一度に指定したパラレル出力を行うことができます。
pcf8574_gpio_write()を使うと、指定したビットだけをON/OFFすることができます。
指定していないビットは、直前の値を保持します。
但し、PCF8574は3.3V駆動、i2cアドレスを指定するA0/A1/A2も3.3Vでないと、正しく動きません。
/* The example of esp-free-rtos
 *
 * This sample code is in the public domain.
 */
#include <stdlib.h>
#include <string.h>
#include "espressif/esp_common.h"
#include "esp/uart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "esp8266.h"

#include "pcf8574/pcf8574.h"

#define I2C_BUS 0
#define SCL_PIN 5
#define SDA_PIN 4
#define ADDR 0x27

static void task(void *pvParameters)
{
    i2c_dev_t dev = {
        .addr = ADDR,
        .bus = I2C_BUS,
    };

  TickType_t nowTick;
  uint8_t value;
  uint8_t ret;
  nowTick = xTaskGetTickCount();
  printf("[%s:%d] Start\n",pcTaskGetName(0),nowTick);

  pcf8574_port_write(&dev, 0);
  for(int i=0;i<5;i++) {
    pcf8574_port_write(&dev, 0xff);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    pcf8574_port_write(&dev, 0);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }

  value = 0x01;
  for(int num=0;num<8;num++) {
    //printf("value=%02x\n",value);
    pcf8574_port_write(&dev, value);
    vTaskDelay(100 / portTICK_PERIOD_MS);
    ret=pcf8574_port_read(&dev);
    printf("value=%02x ret=%02x\n",value,ret);
    value = (value << 1) + 1;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }

  value = 0x7f;
  for(int num=0;num<8;num++) {
    pcf8574_port_write(&dev, value);
    vTaskDelay(100 / portTICK_PERIOD_MS);
    ret=pcf8574_port_read(&dev);
    printf("value=%02x ret=%02x\n",value,ret);
    value = value >> 1;
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }

  for(int num=0;num<8;num++) {
    pcf8574_gpio_write(&dev, num, 1);
    vTaskDelay(100 / portTICK_PERIOD_MS);
    ret=pcf8574_port_read(&dev);
    printf("ret=%02x\n",ret);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }

  for(int num=0;num<8;num++) {
    pcf8574_gpio_write(&dev, num, 0);
    vTaskDelay(100 / portTICK_PERIOD_MS);
    ret=pcf8574_port_read(&dev);
    printf("ret=%02x\n",ret);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
  vTaskDelete(NULL);
}

void user_init(void)
{
    uart_set_baud(0, 115200);
    printf("SDK version:%s\n", sdk_system_get_sdk_version());
    printf("pcTaskGetName=%s\n",pcTaskGetName(0));

    i2c_init(I2C_BUS, SCL_PIN, SDA_PIN, I2C_FREQ_100K);

    xTaskCreate(task, "PCF8575_GPIO", 256, NULL, 2, NULL);
}

続く....