Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: TPS92520/TPS92520.cpp
- Revision:
- 7:a52c300451ed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TPS92520/TPS92520.cpp Mon Dec 10 09:19:37 2018 +0000
@@ -0,0 +1,355 @@
+/***************************************************************************//**
+* @file TPS92520.c
+* @brief TPS92520 implementation file.
+* @devices TPS92520-Q1
+*
+********************************************************************************
+* Copyright 2018(c) Automotive Lighting
+*
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+* - Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+* - Neither the name of Automotive Lighting nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+* - The use of this software may or may not infringe the patent rights
+* of one or more patent holders. This license does not release you
+* from the requirement that you obtain separate licenses from these
+* patent holders to use this software.
+* - Use of the software either in source or binary form, must be run
+* on or directly connected to an Automotive Lighting component.
+*
+* THIS SOFTWARE IS PROVIDED BY AUTOMOTIVE LIGHTING "AS IS" AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL AUTOMOTIVE LIGHTING BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+* INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+#include "mbed.h"
+#include "TPS92520.h"
+
+
+/* Error codes */
+#define INVALID_VAL -1 /* Invalid argument */
+#define COMM_ERR -2 /* Communication error on receive */
+#define TIMEOUT -3 /* A timeout has occured */
+
+/* SPI CLK Frequency */
+#if not definated
+ #define SPI_CLK 100000
+#endif
+
+TPS92520::TPS92520(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName pwr_en) : my_spi(mosi, miso, sclk), my_pin( cs), pwr_en_pin(pwr_en) { }
+
+TPS92520::~TPS92520() { }
+
+
+/***************************************************************************//**
+* @brief Reads the junction temperature
+*
+* @return pointer to string message.
+*******************************************************************************/
+char* TPS92520::temp(void) {
+ int ret;
+ int low,high = 0;
+ static char buffer[20];
+ sprintf(buffer, "\0");
+
+ /* TEMPL Register */
+ ret = readRegs(TEMPL,&low);
+ if(ret<0) {
+ sprintf(buffer, "COMM ERROR\n\r");
+ return buffer; }
+ low = low & 0x0003;
+
+ /* TEMPH Register */
+ ret = readRegs(TEMPH,&high);
+ if(ret<0) {
+ sprintf(buffer, "COMM ERROR\n\r");
+ return buffer; }
+ high = high & 0x00FF;
+
+ high = high << 2;
+ high = high + low;
+
+ float temp = 0.7168*high-274.51;
+ sprintf(buffer, "Temp Junction: %0.1f\r\n", temp);
+
+ return buffer;
+}
+
+/***************************************************************************//**
+* @brief Reads value from all status registers and create message with all
+* errors
+*
+* @return pointer to string message.
+*******************************************************************************/
+char* TPS92520::status(void) {
+ int ret;
+ int raw_data,c = 0;
+ static char buffer[200];
+ sprintf(buffer, "\0");
+
+ char *reports1[8] = {"CH2LSILIM", "CH2HSILIM", "CH2SHORT", "CH2COMPOV",
+ "CH1LSILIM", "CH1HSILIM", "CH1SHORT", "CH1COMPOV"};
+
+ char *reports2[6] = {"CH2TP", "CH2BSTUV", "CH2TOFFMIN",
+ "CH1TP", "CH1BSTUV", "CH1TOFFMIN"};
+
+ char *reports3[7] = {"V5AUV", "Watchdog Expired", "Watchdog Expired",
+ "TW", "PC", "CH2STATUS","CH1STATUS"};
+
+ readRegs(STATUS3,&raw_data);
+
+ /* STATUS 1 Register */
+ ret = readRegs(STATUS1,&raw_data);
+ if(ret<0) {
+ sprintf(buffer, "COMM ERROR\n\r");
+ return buffer; }
+ raw_data = raw_data & 0x00FF;
+ for(int i = 0; i<8; i++) {
+ c = raw_data & 1 <<i;
+ if(c>0) {
+ strcat(buffer, reports1[7-i]);
+ strcat(buffer, "\r\n");
+ }
+ }
+
+ /* STATUS 2 Register */
+ ret = readRegs(STATUS2,&raw_data);
+ if(ret<0) {
+ sprintf(buffer, "COMM ERROR\n\r");
+ return buffer; }
+ raw_data = raw_data & 0x00FF;
+ for(int i = 0; i<6; i++) {
+ c = raw_data & 1 <<i;
+ if(c>0) {
+ strcat(buffer, reports2[5-i]);
+ strcat(buffer, "\r\n");
+ }
+ }
+
+ /* STATUS 3 Register */
+ ret = readRegs(STATUS3,&raw_data);
+ if(ret<0) {
+ sprintf(buffer, "COMM ERROR\n\r");
+ return buffer; }
+ raw_data = raw_data & 0x00FF;
+ for(int i = 0; i<7; i++) {
+ c = raw_data & 1 <<i;
+ if(c>0) {
+ strcat(buffer, reports3[6-i]);
+ strcat(buffer, "\r\n");
+ }
+ }
+
+ if(buffer[0] == '\0') sprintf(buffer, "OK\r\n");
+
+ return buffer;
+}
+
+/***************************************************************************//**
+* @brief Init SPI periphery
+*
+*******************************************************************************/
+void TPS92520::init(void) {
+ // Setup the spi for 16 bit data, Mode 0 CLK polarity 0, Phase 0
+ my_spi.format(16,0);
+ my_spi.frequency(SPI_CLK);
+ // Enable 5VA PWR supply
+ pwr_en_pin = 1;
+
+ int data;
+ /* Check STATUS3 Register */
+ readRegs(STATUS3,&data);
+
+
+}
+
+
+/***************************************************************************//**
+* @brief Read register value.
+*
+* @param addr - The address of the register.
+* @param pData - Pointer to the data which hold readed register data
+*
+* @return Returns 0 for success or negative error code.
+*
+*******************************************************************************/
+int TPS92520::readRegs(int addr, int *pData) {
+ uint8_t CMD = 0;
+ uint16_t frame = 0;
+
+ frame = CMD<<15 | addr<<9 | 0x00;
+ frame = frame | parity(frame)<<8;
+
+ /* First Frame */
+ my_pin = 0;
+ my_spi.write(frame);
+ my_pin = 1;
+ wait_us(10);
+
+ /* Second Frame */
+ my_pin = 0;
+ uint16_t rx_buffer = my_spi.write(frame);
+ my_pin = 1;
+
+ /* Response is valid in the second frame @ Datasheet */
+ *pData = rx_buffer;
+
+ if(rx_buffer & SPI_ERROR == TRUE) return COMM_ERR;
+
+ if((rx_buffer & 0x7C00)>>10 != 24) return COMM_ERR;
+
+ return 0;
+
+ }
+
+/***************************************************************************//**
+* @brief Write register value.
+*
+* @param addr - The address of the register.
+* @param data - The data to be writen.
+* @param response - Pointer to the data which hold writen register data
+*
+* @return Returns 0 for success or negative error code.
+*
+*******************************************************************************/
+int TPS92520::writeRegs(int addr, int data, int *response) {
+ uint8_t CMD = 1;
+ uint16_t frame = 0;
+
+ frame = CMD<<15 | addr<<9 | data;
+ frame = frame | parity(frame)<<8;
+
+ /* First Frame */
+ my_pin = 0;
+ my_spi.write(frame);
+ my_pin = 1;
+ wait_us(10);
+
+ /* Second Frame */
+ my_pin = 0;
+ uint16_t rx_buffer = my_spi.write(frame);
+ my_pin = 1;
+
+ /* Response is valid in the second frame @ Datasheet */
+ *response = rx_buffer;
+
+ if(rx_buffer & SPI_ERROR == TRUE) return COMM_ERR;
+
+ if((rx_buffer & 0x00FF) != data) return COMM_ERR;
+
+ if((rx_buffer & 0x3F00)>>8 != addr) return COMM_ERR;
+
+ return 0;
+
+ }
+
+/***************************************************************************//**
+* @brief Reset device. This function clear all writeable register to their
+* default value.
+*
+* @return Returns 0.
+*
+*******************************************************************************/
+int TPS92520::reset() {
+ int data;
+
+ // Disable 5VA PWR supply
+ pwr_en_pin = 0;
+ wait_ms(350);
+
+ // Enable 5VA PWR supply
+ pwr_en_pin = 1;
+
+ wait_ms(50);
+ /* Check STATUS3 Register */
+ readRegs(STATUS3,&data);
+
+ return 0;
+ }
+
+/***************************************************************************//**
+* @brief Calculate parity bit.
+*
+* @param frame - The frame for which we want to calculate parity bit.
+*
+* @return Returns parity bit value.
+*
+*******************************************************************************/
+int TPS92520::parity(uint16_t frame) {
+ uint8_t XNOR = 0;
+
+ for(int i = 15; i >= 0; i--){
+ if((frame & (1 << i)) != 0){
+ XNOR = !(XNOR^1);
+ if(i == 15){
+ XNOR = 1; }
+ }
+ else{
+ XNOR = !(XNOR^0);
+ if(i == 15){
+ XNOR = 0; }
+ }
+ }
+ return XNOR;
+ }
+
+/***************************************************************************//**
+* @brief Set the PWM duty.
+*
+* @param
+*
+* @return
+*
+*******************************************************************************/
+int TPS92520::setPWMduty(uint8_t channel,uint16_t duty) {
+ uint8_t CMD = 1;
+
+ if(duty> 1023 == 1) return INVALID_VAL;
+
+ uint16_t data = (uint16_t)duty/100*1023;
+ uint16_t frame = 0;
+
+ // First SPI frame
+ uint8_t addr = CH1PWMH;
+ if (channel == 2) addr +=2;
+
+ frame = CMD<<15 | addr<<9 | data&0x0300>>8;
+ frame = frame | parity(frame)<<8;
+
+ my_pin = 0;
+ uint16_t rx_buffer = my_spi.write(frame);
+ my_pin = 1;
+
+ // Second SPI frame
+ addr = CH1PWML;
+ if (channel == 2) addr +=2;
+
+ frame = CMD<<15 | addr<<9 | data&0x00FF;
+ frame = frame | parity(frame)<<8;
+
+ my_pin = 0;
+ rx_buffer = my_spi.write(frame);
+ my_pin = 1;
+
+ return 0;
+
+ }
\ No newline at end of file