PMT9123 OTS on Nucleo (Initial Release)
Dependencies: Pixart_9123_Nucleo_Library mbed
Fork of PMT9123_OTS_NUCLEO_Program by
Diff: main.cpp
- Revision:
- 0:384ce9819ea6
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu May 11 17:32:14 2017 +0000 @@ -0,0 +1,270 @@ +/* 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; +} +