class pah8011 for mbed
pixart_pah8011.cpp
- Committer:
- bell_huang
- Date:
- 2019-01-23
- Revision:
- 6:d196b612b14a
- Parent:
- 5:37451de228e4
File content as of revision 6:d196b612b14a:
#include "pixart_pah8011.h"
extern "C" {
#include "pah_comm.h"
#include "pah_driver.h"
#include "pah_platform_functions.h"
#include <string.h>
void disable_debug_printf(const char *fmt, ...)
{
// do nothing
}
DEBUG_PRINT_HANDLE debug_printf = disable_debug_printf;
void delay_ms(uint64_t ms)
{
wait_ms(ms);
}
} // extern "C"
namespace pixart {
static pah_ret mbed_i2c_write(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t data)
{
pah8011 *pah8011_state = (pah8011*)comm->user_data;
I2C *i2c = pah8011_state->get_i2c();
int rc = 0;
char data_write[2];
data_write[0] = addr;
data_write[1] = data;
rc = i2c->write((pah8011_state->get_i2c_slave_id() << 1), data_write, 2, 0);
if (rc != 0)
return PAH_RET_PLAT_FAILED;
return PAH_RET_SUCCESS;
}
static pah_ret mbed_i2c_burst_read(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t *data, uint32_t rx_size)
{
pah8011 *pah8011_state = (pah8011*)comm->user_data;
I2C *i2c = pah8011_state->get_i2c();
int rc = 0;
rc = i2c->write((pah8011_state->get_i2c_slave_id() << 1), (const char*)&addr, 1, 1);
if (rc != 0)
return PAH_RET_PLAT_FAILED;
rc = i2c->read((pah8011_state->get_i2c_slave_id() << 1), (char*)data, rx_size, 0);
if (rc != 0)
return PAH_RET_PLAT_FAILED;
return PAH_RET_SUCCESS;
}
static pah_ret mbed_i2c_read(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t *data)
{
return mbed_i2c_burst_read(comm, addr, data, 1);
}
static pah_ret mbed_spi_write(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t data)
{
pah8011 *pah8011_state = (pah8011*)comm->user_data;
SPI *spi = pah8011_state->get_spi();
DigitalOut *spi_cs = pah8011_state->get_spi_cs();
*spi_cs = 1;
char data_write[2];
data_write[0] = addr;
data_write[1] = data;
spi->write(data_write, 2, NULL, 0);
*spi_cs = 0;
return PAH_RET_SUCCESS;
}
static pah_ret mbed_spi_burst_read(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t *data, uint32_t rx_size)
{
pah8011 *pah8011_state = (pah8011*)comm->user_data;
SPI *spi = pah8011_state->get_spi();
DigitalOut *spi_cs = pah8011_state->get_spi_cs();
*spi_cs = 1;
/*
spi->write(addr);
for (uint32_t i = 0; i < rx_size; ++i)
data[i] = spi->write(0x00);
*/
static char buf[256];
buf[0] = addr;
static const uint8_t WRITE_LENGTH = 1;
spi->write(buf, WRITE_LENGTH, buf, WRITE_LENGTH + rx_size);
memcpy(data, &buf[WRITE_LENGTH], rx_size);
*spi_cs = 0;
return PAH_RET_SUCCESS;
}
static pah_ret mbed_spi_read(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t *data)
{
return mbed_spi_burst_read(comm, addr, data, 1);
}
pah8011::pah8011(I2C &i2c, uint8_t slave_id)
: m_i2c(&i2c)
, m_i2c_slave_id(slave_id)
, m_spi(NULL)
, m_spi_cs(NULL)
, m_is_ppg_enabled(false)
, m_is_touch_enabled(false)
{
pah_drv_comm_s pah_drv_comm = {
.type = pah_drv_comm_i2c,
.user_data = this,
.max_length = 256,
.write = mbed_i2c_write,
.write_delay = NULL,
.read = mbed_i2c_read,
.burst_read = mbed_i2c_burst_read,
};
pah_comm_set_drv_comm(&pah_drv_comm);
}
pah8011::pah8011(SPI &spi, DigitalOut &cs)
: m_i2c(NULL)
, m_i2c_slave_id(0x15)
, m_spi(&spi)
, m_spi_cs(&cs)
, m_is_ppg_enabled(false)
, m_is_touch_enabled(false)
{
m_spi->format(8, 3);
pah_drv_comm_s pah_drv_comm = {
.type = pah_drv_comm_spi,
.user_data = this,
.max_length = 256,
.write = mbed_spi_write,
.write_delay = NULL,
.read = mbed_spi_read,
.burst_read = mbed_spi_burst_read,
};
pah_comm_set_drv_comm(&pah_drv_comm);
}
pah8011::~pah8011()
{
pah_deinit();
}
void pah8011::enable_debug_print(DEBUG_PRINT_HANDLE handler)
{
if (handler)
debug_printf = handler;
else
debug_printf = disable_debug_printf;
}
bool pah8011::init()
{
pah_flags_s flags;
memset(&flags, 0, sizeof(flags));
flags.intshape_pulse_type = pah_intshape_pulse_type_level;
if (!pah_init_with_flags(&flags))
return false;
return true;
}
bool pah8011::enable_ppg()
{
m_is_ppg_enabled = true;
return select_mode();
}
bool pah8011::disable_ppg()
{
m_is_ppg_enabled = false;
return select_mode();
}
bool pah8011::enable_touch()
{
m_is_touch_enabled = true;
return select_mode();
}
bool pah8011::disable_touch()
{
m_is_touch_enabled = false;
return select_mode();
}
bool pah8011::task()
{
pah_ret ret = pah_task();
return ret == pah_success
|| ret == pah_no_interrupt;
}
bool pah8011::get_result(task_result &result)
{
if (!pah_has_fifo_data())
return false;
result.data = (int32_t*)pah_get_fifo_data();
result.num_per_ch = pah_fifo_data_num_per_ch();
result.ch_num = pah_get_fifo_ch_num();
result.is_touched = pah_is_touched();
return true;
}
I2C* pah8011::get_i2c() const
{
return m_i2c;
}
uint8_t pah8011::get_i2c_slave_id() const
{
return m_i2c_slave_id;
}
SPI* pah8011::get_spi() const
{
return m_spi;
}
DigitalOut* pah8011::get_spi_cs() const
{
return m_spi_cs;
}
bool pah8011::select_mode()
{
pah_mode mode = pah_stop_mode;
if (m_is_ppg_enabled)
{
if (m_is_touch_enabled)
mode = pah_ppg_touch_mode;
else
mode = pah_ppg_mode;
}
else if (m_is_touch_enabled)
{
mode = pah_touch_mode;
}
else
{
mode = pah_stop_mode;
}
return pah_enter_mode(mode);
}
}