PMT9123 OTS on Nucleo (Initial Release)

Dependencies:   Pixart_9123_Nucleo_Library mbed

Fork of PMT9123_OTS_NUCLEO_Program by PixArt Imaging

main.cpp

Committer:
pixus_mbed
Date:
2017-05-11
Revision:
1:66afdef90518
Parent:
0:384ce9819ea6

File content as of revision 1:66afdef90518:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mbed.h"
#include "OTC.h"
#include <string>
#include <ctype.h>
using namespace std;

// Function prototypes
void serialEvent();
void serialProcess(string input);
bool IsParamValid(char *param, bool hex = true);
bool IsDigit(char *p, bool hex);
void Hex8(uint8_t data);
void PrintHex8(uint8_t data);

Serial pc(USBTX,USBRX);//tx, rx
I2C i2c(I2C_SDA, I2C_SCL);

DigitalOut led1(LED1);
DigitalOut pwm(D9);
PwmOut mypwm(D9);

// OTS object declaration
Pixart_OTS *m_OTS = NULL;

// Serial string
string strRead = "";

// LED PWM setting
#define LED_PERIOD_US  3000    // 3ms
#define LED_MAX_DC      100
// LED brightness control value in us
int16_t LED_on_time_us = 0;
int16_t Counts;
int16_t max_on_period;

// LED control
void LED_control(int16_t value)
{
    int16_t led_on_time;
    
    LED_on_time_us += value;
    led_on_time = LED_on_time_us;
    
    if (LED_on_time_us < 5)     // hysterisis so that the LED stay off
        led_on_time = 0;
    else if (LED_on_time_us > max_on_period)
        led_on_time = LED_on_time_us = max_on_period;
    
    mypwm.pulsewidth_us(led_on_time);
}

// Reset count and LED
void ClearCount()
{
   Counts = 0;
   pc.printf("Count = 0\n");
   LED_on_time_us = 0;
   LED_control(0);
}

void GetData(int16_t value)
{
    Counts += value;
    pc.printf("Count = %d\n", Counts);
    
    // Change brightness
    LED_control(value);
}

// main() runs in its own thread in the OS
// (note the calls to Thread::wait below for delays)
int main() {

    pc.format(8, Serial::None, 1);
    pc.baud(115200);
    pc.attach(&serialEvent);
    i2c.frequency(400000);    
    
    // LED control 
    max_on_period = LED_MAX_DC*LED_PERIOD_US/100;
    mypwm.period_us(LED_PERIOD_US);
    LED_on_time_us = 0;   // start with 0, which is off
    LED_control(0);
    
    Counts = 0;     // restart count to zero
    
    bool Result = false;
    // Set to polling at 4ms
    m_OTS = new Pixart_OTS(&i2c,4,GetData,Result);
    
    if(Result == true)
    {
        pc.printf("Initial Pixart OTS successful\n\r");
    }
    else
    {
        pc.printf("Initial Pixart OTS fail\n\r");    
    }
        
        
    while (true)
    {
       ;
   }
}

void serialEvent() {
  char inChar;

  while (pc.readable())
  {
    // get the new byte:
    inChar = (char)pc.getc();
    //pc.putc(inChar);
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if ((inChar == '\n') || (inChar == '\r'))
    {
      //strRead.trim();
      strRead += " ";  // for tokenizing
      serialProcess(strRead);
      strRead = "";
    }
    else if (inChar != 0xf0)
      // add it to the strRead
      strRead += inChar;
  }
}

// Macro define for easily reading
#define IsEqual(a,b)  (!strcmp((a),(b)))

void serialProcess(string input)
{
  int val;
  unsigned char Address,Value;

  //pc.printf("cmd = %s\n", input);
  // ====================================================
  //  Single command goes here
  //  NOTE: All command compare must have " " at the back
  // ====================================================
  if (input == "c ")
  {
    ClearCount();
  }
  // ====================================================
  //  Command with parameters goes here, like r 00, w 48 00
  // ====================================================
  else if (input != " ")    // not empty string, then proceed to decode the command
  {
    char buff[40];
    size_t l = input.copy(buff, input.length(), 0);
    buff[l] = '\0';
    
    // Get the command
    char *tok = strtok(buff, " ");
    if (!tok)
    {
      pc.printf("empty command\n");
      return;
    }
    
    // Get parameters, up to 4 parameters, if more than that, individual command will need to extract it on their own
    char *param[4];
    for (val = 0; val < 4; val++)
    {
      param[val] = strtok(NULL, " ");
      if (!param[val])  // break if we reach the end
        break;
    }

    // convert the first parameter into decimal first, as it is most commonly used
    val = strtol(param[0], NULL, 10);

    // switch for command
    if ((IsEqual(tok,"r")) || (IsEqual(tok,"w")))
    {
      // Address is the first byte
      if (!IsParamValid(param[0]))
      {
        return;
      }
      // convert to integer
      Address = strtol(param[0], NULL, 16);
      if (Address > 0x7F)
      {
        pc.printf("Error (r/w): address > 0x7F\n");
        return;
      }
      
      if ((IsEqual(tok,"w")))
      {
        // Value is second byte
        if (!IsParamValid(param[1]))
        {
          return;
        }
        // convert to integer
        Value = strtol(param[1], NULL, 16);
        if (Value > 0xFF)
        {
          pc.printf("Error (w): value > 0xFF\n");
          return;
        }
        
        val = m_OTS->Register_Write(Address, Value);
      }
      else
      {
        val = m_OTS->Register_Read(Address);
      }
      
      pc.printf("ADDR %02X %02X\n", Address, val);
    }
    else
    {
      pc.printf("Bad command : ");
      pc.printf("%s\n", tok);
    }
  }
}

// Check if param is not given or not hexa, print the error as well
bool IsParamValid(char *param, bool hex)
{
  if (!param)
  {
    return false;
  }
  if (!IsDigit(param, hex))
  {
    pc.printf("Error : arg invalid\n");
    return false;
  }
  return true;
}

// Check whether is hexa for given char
bool IsDigit(char *p, bool hex)
{
  for (int i; i < strlen(p); i++)
  {
    if (hex)
    {
      if (!isxdigit(p[i]))
        return false;
    }
    else if (!isdigit(p[i]))
        return false;
  }
  return true;
}