Bell Huang / pixart_pah8011
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pixart_pah8011.cpp Source File

pixart_pah8011.cpp

00001 #include "pixart_pah8011.h"
00002 
00003 
00004 extern "C" {
00005     
00006     
00007     #include "pah_comm.h"
00008     #include "pah_driver.h"
00009     #include "pah_platform_functions.h"
00010     #include <string.h>
00011     
00012     
00013     void disable_debug_printf(const char *fmt, ...)
00014     {
00015         // do nothing
00016     }
00017 
00018     DEBUG_PRINT_HANDLE debug_printf = disable_debug_printf;
00019     
00020     void delay_ms(uint64_t ms)
00021     {
00022         wait_ms(ms);
00023     }
00024 
00025 } // extern "C"
00026 
00027 
00028 namespace pixart {
00029     
00030     
00031     static pah_ret mbed_i2c_write(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t data)
00032     {
00033         pah8011 *pah8011_state = (pah8011*)comm->user_data;
00034         I2C *i2c = pah8011_state->get_i2c();
00035         int rc = 0;
00036         char data_write[2];
00037     
00038         data_write[0] = addr;
00039         data_write[1] = data;
00040         
00041         rc = i2c->write((pah8011_state->get_i2c_slave_id() << 1), data_write, 2, 0);
00042         if (rc != 0)
00043             return PAH_RET_PLAT_FAILED;
00044         
00045         return PAH_RET_SUCCESS;
00046     }
00047     
00048     static pah_ret mbed_i2c_burst_read(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t *data, uint32_t rx_size)
00049     {
00050         pah8011 *pah8011_state = (pah8011*)comm->user_data;
00051         I2C *i2c = pah8011_state->get_i2c();
00052         int rc = 0;
00053         
00054         rc = i2c->write((pah8011_state->get_i2c_slave_id() << 1), (const char*)&addr, 1, 1);
00055         if (rc != 0)
00056             return PAH_RET_PLAT_FAILED;
00057         
00058         rc = i2c->read((pah8011_state->get_i2c_slave_id() << 1), (char*)data, rx_size, 0);
00059         if (rc != 0)
00060             return PAH_RET_PLAT_FAILED;
00061         
00062         return PAH_RET_SUCCESS;
00063     }
00064     
00065     static pah_ret mbed_i2c_read(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t *data)
00066     {
00067         return mbed_i2c_burst_read(comm, addr, data, 1);
00068     }
00069     
00070     static pah_ret mbed_spi_write(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t data)
00071     {
00072         pah8011 *pah8011_state = (pah8011*)comm->user_data;
00073         SPI *spi = pah8011_state->get_spi();
00074         DigitalOut *spi_cs = pah8011_state->get_spi_cs();
00075         
00076         *spi_cs = 1;
00077         
00078         char data_write[2];
00079         data_write[0] = addr;
00080         data_write[1] = data;
00081         
00082         spi->write(data_write, 2, NULL, 0);
00083         
00084         *spi_cs = 0;
00085         return PAH_RET_SUCCESS;
00086     }
00087     
00088     static pah_ret mbed_spi_burst_read(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t *data, uint32_t rx_size)
00089     {
00090         pah8011 *pah8011_state = (pah8011*)comm->user_data;
00091         SPI *spi = pah8011_state->get_spi();
00092         DigitalOut *spi_cs = pah8011_state->get_spi_cs();
00093         
00094         *spi_cs = 1;
00095         /*
00096         spi->write(addr);
00097         
00098         for (uint32_t i = 0; i < rx_size; ++i)
00099             data[i] = spi->write(0x00);
00100         */
00101         
00102         static char buf[256];
00103         buf[0] = addr;
00104         
00105         static const uint8_t WRITE_LENGTH = 1;
00106         spi->write(buf, WRITE_LENGTH, buf, WRITE_LENGTH + rx_size);
00107         
00108         memcpy(data, &buf[WRITE_LENGTH], rx_size);
00109         
00110         *spi_cs = 0;
00111         return PAH_RET_SUCCESS;
00112     }
00113     
00114     static pah_ret mbed_spi_read(struct pah_drv_comm_s *comm, uint8_t addr, uint8_t *data)
00115     {
00116         return mbed_spi_burst_read(comm, addr, data, 1);
00117     }
00118     
00119     
00120     pah8011::pah8011(I2C &i2c, uint8_t slave_id)
00121         : m_i2c(&i2c)
00122         , m_i2c_slave_id(slave_id)
00123         , m_spi(NULL)
00124         , m_spi_cs(NULL)
00125         , m_is_ppg_enabled(false)
00126         , m_is_touch_enabled(false)
00127     {
00128         pah_drv_comm_s pah_drv_comm = {
00129             .type           = pah_drv_comm_i2c,
00130             .user_data      = this,
00131             .max_length     = 256,
00132             .write          = mbed_i2c_write,
00133             .write_delay    = NULL,
00134             .read           = mbed_i2c_read,
00135             .burst_read     = mbed_i2c_burst_read,
00136         };
00137         pah_comm_set_drv_comm(&pah_drv_comm);
00138     }
00139     
00140     pah8011::pah8011(SPI &spi, DigitalOut &cs)
00141         : m_i2c(NULL)
00142         , m_i2c_slave_id(0x15)
00143         , m_spi(&spi)
00144         , m_spi_cs(&cs)
00145         , m_is_ppg_enabled(false)
00146         , m_is_touch_enabled(false)
00147     {
00148         m_spi->format(8, 3);
00149         
00150         pah_drv_comm_s pah_drv_comm = {
00151             .type           = pah_drv_comm_spi,
00152             .user_data      = this,
00153             .max_length     = 256,
00154             .write          = mbed_spi_write,
00155             .write_delay    = NULL,
00156             .read           = mbed_spi_read,
00157             .burst_read     = mbed_spi_burst_read,
00158         };
00159         pah_comm_set_drv_comm(&pah_drv_comm);
00160     }
00161     
00162     pah8011::~pah8011()
00163     {
00164         pah_deinit();
00165     }
00166     
00167     void pah8011::enable_debug_print(DEBUG_PRINT_HANDLE handler)
00168     {
00169         if (handler)
00170             debug_printf = handler;
00171         else
00172             debug_printf = disable_debug_printf;
00173     }
00174     
00175     bool pah8011::init()
00176     {
00177         pah_flags_s flags;
00178         memset(&flags, 0, sizeof(flags));
00179         
00180         flags.intshape_pulse_type = pah_intshape_pulse_type_level;
00181         
00182         if (!pah_init_with_flags(&flags))
00183             return false;
00184         
00185         return true;
00186     }
00187     
00188     bool pah8011::enable_ppg()
00189     {
00190         m_is_ppg_enabled = true;
00191         
00192         return select_mode();
00193     }
00194     
00195     bool pah8011::disable_ppg()
00196     {
00197         m_is_ppg_enabled = false;
00198         
00199         return select_mode();
00200     }
00201     
00202     bool pah8011::enable_touch()
00203     {
00204         m_is_touch_enabled = true;
00205         
00206         return select_mode();
00207     }
00208     
00209     bool pah8011::disable_touch()
00210     {
00211         m_is_touch_enabled = false;
00212         
00213         return select_mode();
00214     }
00215     
00216     bool pah8011::task()
00217     {
00218         pah_ret ret = pah_task();
00219         
00220         return ret == pah_success
00221             || ret == pah_no_interrupt;
00222     }
00223     
00224     bool pah8011::get_result(task_result &result)
00225     {
00226         if (!pah_has_fifo_data())
00227             return false;
00228             
00229         result.data         = (int32_t*)pah_get_fifo_data();
00230         result.num_per_ch   = pah_fifo_data_num_per_ch();
00231         result.ch_num       = pah_get_fifo_ch_num();
00232         result.is_touched   = pah_is_touched();
00233             
00234         return true;
00235     }
00236     
00237     I2C* pah8011::get_i2c() const
00238     {
00239         return m_i2c;
00240     }
00241     uint8_t pah8011::get_i2c_slave_id() const
00242     {
00243         return m_i2c_slave_id;
00244     }
00245     SPI* pah8011::get_spi() const
00246     {
00247         return m_spi;
00248     }
00249     DigitalOut* pah8011::get_spi_cs() const
00250     {
00251         return m_spi_cs;
00252     }
00253  
00254     bool pah8011::select_mode()
00255     {
00256         pah_mode mode = pah_stop_mode;
00257         
00258         if (m_is_ppg_enabled)
00259         {
00260             if (m_is_touch_enabled)
00261                 mode = pah_ppg_touch_mode;
00262             else
00263                 mode = pah_ppg_mode;
00264         }
00265         else if (m_is_touch_enabled)
00266         {
00267             mode = pah_touch_mode;
00268         }
00269         else
00270         {
00271             mode = pah_stop_mode;
00272         }
00273         
00274         return pah_enter_mode(mode);
00275     }
00276     
00277 }
00278