Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Project Overview
Have you ever felt frustrated by cumbersome wires or pesky dying batteries? Us too. That's why we have designed a Booster Pack that can power itself and the MSP432 Launchpad using only NFC! Our BoosterPack utilizes an RF430 to harness the energy from and communicate over any active NFC field. Using the standard pin-out for a Launchpad Booster Pack, we built the circuitry for the NFC reader, energy harvesting, and local temperature sensor using Altium PCB Design Tools.
On the Booster Pack, the RF430 is connected to a large antenna (a large loop of copper trace), and stores the harvested energy in a super capacitor. When a phone is brought near the booster pack, while your phone's NFC field charges up a super capacitor, the BoosterPack will also simultaneously transmit data collected by the temperature sensor to your phone. All of this is controlled by the Launchpad's MSP432 via i2C communication.
__________________________________________________
Design and Testing
The board design captures an NFC signal through the antenna which induces an AC voltage and current into the RF430 for data transfer and communication.That same AC signal is converted to DC through half-wave bridge rectifier - parallel diodes that only allow positive current to flow - and serves as VCC to the BoosterPack and Launchpad. The newly rectified DC signal both provides direct power to the system and charges up the super capacitor. Charging the super capacitor is controlled by the MSP432 via a GPIO pin. When the launchpad sends a high signal to the proper GPIO pin, that high voltage signal is passed to a bipolar junction capacitor which switches on. This allows current from the rectified DC signal to flow through the 'Super Capacitor Charger' circuitry (see image below) and store energy in the super cap for future use.
Data from a sensor can be transmitted through the RF430 to the phone via this NFC connection as well. To show this utility, the board features a local temperature sensor chip that is connected to the RF430. Any and all communication and data transmission between the booster pack, the launchpad or the phone is done through the 'I2C pull up' pins (see image below).
Once the schematic and PCB layout were completed using Altium, we sent the design to Seeed to be printed.
Upon receiving the boards, the first step was to 'tune' the antenna, by measuring its inductance with a network analyzer. With these measurements we calculated a necessary parallel capacitance (C10 on the PCB layout) of 2.4 pF that would make the antenna resonate at about 13.5MHz - the standard resonant frequency of NFC fields.
***For more information on NFC antenna design and tuning please see the following TI Application Note by Eddie LaCost
After tuning, we soldered all the components onto the board. Once the board was fully assembled, we tested it's NFC capabilities using a MSP430G2xx launchpad to test a ready-made CCS code example for I2C communication. A phone was able to successfully read "Hello World!" from the launchpad via our booster pack.
Next, we mapped the working I2C code from the MSP43G2 launchpad over to the MSP432 launchpad. Next, we tested the functionality of the super capacitor. The test consisted of bringing a phone near the booster pack, holding for 10 seconds, then pulling it away and see that a blinking LED continued to blink with only the energy stored in the super cap.
Now that the booster pack's NFC communication and energy harvesting/storing capabilities are confirmed, we programmed MSP432 was to take a temperature reading from the TMP103 and send that reading to an Android phone.
Our BoosterPack was able to pass all proof-of-concept tests and is ready to be implemented to fit any user's needs.
Welcome to the world of wireless power!
________________________________________________________________
Many thanks from team Energy Boost!
RF430_example.c
C/C++/*
* {RF430_example.c}
*
* {Functions}
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
*
*
* 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 Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, 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.
*
*/
/*
* RF430_example.c
*
* Created on: Feb 6, 2013
* Author: JD Crutchfield
*/
//#include "msp430.h"
#include "msp.h"
#include "RF430_example.h"
unsigned char RxData[2] = {0,0};
unsigned char TxData[2] = {0,0};
unsigned char TxAddr[2] = {0,0};
/* --COPYRIGHT--,BSD
* Copyright (c) 2015, Texas Instruments Incorporated
* 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 Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* 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.
* --/COPYRIGHT--*/
//****************************************************************************
//
// HAL_I2C.c - Hardware abstraction layer for I2C with MSP432P401R
//
//****************************************************************************
#include <driverlib.h>
/* I2C Master Configuration Parameter */
const eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
48000000, // SMCLK = 48MHz
EUSCI_B_I2C_SET_DATA_RATE_400KBPS, // Desired I2C Clock of 100khz
0, // No byte counter threshold
EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
};
void Init_I2C_GPIO()
{
/* Select I2C function for I2C_SCL(P6.5) & I2C_SDA(P6.4) */
GPIO_setAsPeripheralModuleFunctionOutputPin(
GPIO_PORT_P6,
GPIO_PIN5,
GPIO_PRIMARY_MODULE_FUNCTION);
GPIO_setAsPeripheralModuleFunctionOutputPin(
GPIO_PORT_P6,
GPIO_PIN4,
GPIO_PRIMARY_MODULE_FUNCTION);
}
/***************************************************************************//**
* @brief Configures I2C
* @param none
* @return none
******************************************************************************/
void I2C_init(void)
{
/* Initialize USCI_B0 and I2C Master to communicate with slave devices*/
I2C_initMaster(EUSCI_B1_MODULE, &i2cConfig);
/* Disable I2C module to make changes */
I2C_disableModule(EUSCI_B1_MODULE);
/* Enable I2C Module to start operations */
I2C_enableModule(EUSCI_B1_BASE);
return;
}
/***************************************************************************//**
* @brief Reads data from the sensor
* @param writeByte Address of register to read from
* @return Register contents
******************************************************************************/
int I2C_read16(unsigned int writeByte)
{
volatile int val = 0;
volatile int valScratch = 0;
/* Set master to transmit mode PL */
I2C_setMode(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_MODE);
/* Clear any existing interrupt flag PL */
I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Wait until ready to write PL */
while (I2C_isBusBusy(EUSCI_B1_BASE));
/* Initiate start and send first character */
I2C_masterSendMultiByteStart(EUSCI_B1_BASE, (unsigned char)(writeByte>>8));
/* Wait for TX to finish */
while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));
/* Send the MSB to SENSOR */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
(unsigned char)(writeByte));
/* Wait for TX to finish */
while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));
/* Initiate stop only */
I2C_masterSendMultiByteStop(EUSCI_B1_BASE);
/* Wait for Stop to finish */
while(!I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_STOP_INTERRUPT));
/*
* Generate Start condition and set it to receive mode.
* This sends out the slave address and continues to read
* until you issue a STOP
*/
I2C_masterReceiveStart(EUSCI_B1_BASE);
/* Wait for RX buffer to fill */
while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0)));
/* Read from I2C RX register */
valScratch = I2C_masterReceiveMultiByteNext(EUSCI_B1_BASE);
/* Receive second byte then send STOP condition */
val = I2C_masterReceiveMultiByteFinish(EUSCI_B1_BASE);
/* Shift val to top MSB */
val = (val << 8);
/* Read from I2C RX Register and write to LSB of val */
val |= valScratch;
/* Return temperature value */
return (int16_t)val;
}
/***************************************************************************//**
* @brief Writes data to the sensor
* @param pointer Address of register you want to modify
* @param writeByte Data to be written to the specified register
* @return none
******************************************************************************/
void I2C_write16 (unsigned int pointer, unsigned int writeByte)
{
/* Set master to transmit mode PL */
I2C_setMode(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_MODE);
/* Clear any existing interrupt flag PL */
I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Wait until ready to write PL */
while (I2C_isBusBusy(EUSCI_B1_BASE));
/* Initiate start and send MSB first character */
I2C_masterSendMultiByteStart(EUSCI_B1_BASE,
(unsigned char)(pointer>>8));
/* Send the LSB of pointer */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
(unsigned char)(pointer));
/* Send the MSB to SENSOR */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
(unsigned char)(writeByte>>8));
I2C_masterSendMultiByteFinish(EUSCI_B1_BASE,
(unsigned char)(writeByte&0xFF));
}
void I2C_setslave(unsigned int slaveAdr)
{
/* Specify slave address for I2C */
I2C_setSlaveAddress(EUSCI_B1_BASE,
slaveAdr);
/* Enable and clear the interrupt flag */
I2C_clearInterruptFlag(EUSCI_B1_MODULE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
return;
}
unsigned int Read_Register(unsigned int reg_addr)
{
volatile int val = 0;
volatile int valScratch = 0;
/* Set master to transmit mode PL */
I2C_setMode(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_MODE);
/* Clear any existing interrupt flag PL */
I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Wait until ready to write PL */
while (I2C_isBusBusy(EUSCI_B1_BASE));
/* Initiate start and send first character */
I2C_masterSendMultiByteStart(EUSCI_B1_BASE, (unsigned char)(reg_addr>>8));
/* Wait for TX to finish */
while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));
/* Send the MSB to SENSOR */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
(unsigned char)(reg_addr));
/* Wait for TX to finish */
while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));
/* Initiate stop only */
I2C_masterSendMultiByteStop(EUSCI_B1_BASE);
/* Wait for Stop to finish */
while(!I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_STOP_INTERRUPT));
/*
* Generate Start condition and set it to receive mode.
* This sends out the slave address and continues to read
* until you issue a STOP
*/
I2C_masterReceiveStart(EUSCI_B1_BASE);
/* Wait for RX buffer to fill */
while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0)));
/* Read from I2C RX register */
valScratch = I2C_masterReceiveMultiByteNext(EUSCI_B1_BASE);
/* Receive second byte then send STOP condition */
val = I2C_masterReceiveMultiByteFinish(EUSCI_B1_BASE);
/* Shift val to top MSB */
val = (val << 8);
/* Read from I2C RX Register and write to LSB of val */
val |= valScratch;
/* Return temperature value */
return (int16_t)val;
// TxAddr[0] = reg_addr >> 8; //MSB of address
// TxAddr[1] = reg_addr & 0xFF; //LSB of address
//
// UCB1CTL1 &= ~UCSWRST;
// UCB1CTL1 |= UCTXSTT + UCTR; //start i2c write operation
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = TxAddr[0];
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = TxAddr[1];
// while(!(UCB1IFG & UCTXIFG0));
// UCB1CTL1 &= ~UCTR; //i2c read operation
// UCB1CTL1 |= UCTXSTT; //repeated start
// while(!(UCB1IFG & UCRXIFG0));
// RxData[0] = UCB1RXBUF;
// UCB1CTL1 |= UCTXSTP; //send stop after next RX
// while(!(UCB1IFG & UCRXIFG0));
// RxData[1] = UCB1RXBUF;
// while((UCB1STAT & UCBBUSY)); // Ensure stop condition got sent
// UCB1CTL1 |= UCSWRST;
//
// return RxData[1] << 8 | RxData[0];
}
//reads the register at reg_addr, returns the result
//unsigned int Read_Register_BIP8(unsigned int reg_addr)
//{
// unsigned char BIP8 = 0;
// TxAddr[0] = reg_addr >> 8; //MSB of address
// TxAddr[1] = reg_addr & 0xFF; //LSB of address
//
// UCB0CTL1 &= ~UCSWRST;
// UCB0CTL1 |= UCTXSTT + UCTR; //start i2c write operation
//
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = TxAddr[0];
// BIP8 ^= TxAddr[0];
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = TxAddr[1];
// BIP8 ^= TxAddr[1];
//
// while(!(IFG2 & UCB0TXIFG)); // Waiting for TX to finish on bus
// UCB0CTL1 &= ~UCTR; //i2c read operation
// UCB0CTL1 |= UCTXSTT; //repeated start
//
// while(!(IFG2 & UCB0RXIFG));
// RxData[0] = UCB0RXBUF;
// BIP8 ^= RxData[0];
// while(!(IFG2 & UCB0RXIFG));
// RxData[1] = UCB0RXBUF;
// BIP8 ^= RxData[1];
//
// UCB0CTL1 |= UCTXSTP; //send stop after next RX
// while(!(IFG2 & UCB0RXIFG));
// if(BIP8 != UCB0RXBUF){
// __no_operation();
// }
//
// while((UCB0STAT & UCBBUSY)); // Ensure stop condition got sent
// UCB0CTL1 |= UCSWRST;
//
// return RxData[0] << 8 | RxData[1];
//}
//void Read_Continuous(unsigned int reg_addr, unsigned char* read_data, unsigned int data_length)
//{
// unsigned int i;
//
// TxAddr[0] = reg_addr >> 8; //MSB of address
// TxAddr[1] = reg_addr & 0xFF; //LSB of address
//
// UCB0CTL1 &= ~UCSWRST;
// UCB0CTL1 |= UCTXSTT + UCTR; //start i2c write operation. Sending Slave address
//
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = TxAddr[0];
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = TxAddr[1];
// while(!(IFG2 & UCB0TXIFG)); // Waiting for TX to finish on bus
// UCB0CTL1 &= ~UCTR; //i2c read operation
// UCB0CTL1 |= UCTXSTT; //repeated start
// while(!(IFG2 & UCB0RXIFG));
//
// for(i = 0; i < data_length-1; i++)
// {
// while(!(IFG2 & UCB0RXIFG));
// read_data[i] = UCB0RXBUF;
// }
//
// UCB0CTL1 |= UCTXSTP; //send stop after next RX
// while(!(IFG2 & UCB0RXIFG));
// read_data[i] = UCB0RXBUF;
// while((UCB0STAT & UCBBUSY)); // Ensure stop condition got sent
// UCB0CTL1 |= UCSWRST;
//}
//writes the register at reg_addr with value
void Write_Register(unsigned int reg_addr, unsigned int value)
{
// TxAddr[0] = reg_addr >> 8; //MSB of address
// TxAddr[1] = reg_addr & 0xFF; //LSB of address
// TxData[0] = value >> 8;
// TxData[1] = value & 0xFF;
/* Set master to transmit mode PL */
I2C_setMode(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_MODE);
/* Clear any existing interrupt flag PL */
I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Wait until ready to write PL */
while (I2C_isBusBusy(EUSCI_B1_BASE));
/* Initiate start and send MSB first character */
I2C_masterSendMultiByteStart(EUSCI_B1_BASE,
(unsigned char)(reg_addr>>8));
/* Send the LSB of pointer */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
(unsigned char)(reg_addr));
/* Send the MSB to SENSOR */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
(unsigned char)(value&0xFF));
I2C_masterSendMultiByteFinish(EUSCI_B1_BASE,
(unsigned char)(value>>8));
// TxAddr[0] = reg_addr >> 8; //MSB of address
// TxAddr[1] = reg_addr & 0xFF; //LSB of address
// TxData[0] = value >> 8;
// TxData[1] = value & 0xFF;
//
// UCB1CTL1 &= ~UCSWRST;
// UCB1CTL1 |= UCTXSTT + UCTR; //start i2c write operation CHECK THIS
// //write the address
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = TxAddr[0];
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = TxAddr[1];
// //write the data
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = TxData[1];
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = TxData[0];
// while(!(UCB1IFG & UCTXIFG0));
// UCB1CTL1 |= UCTXSTP;
// while((UCB0STAT & UCBBUSY)); // Ensure stop condition got sent
// UCB1CTL1 |= UCSWRST;
}
//writes the register at reg_addr with value
//void Write_Register_BIP8(unsigned int reg_addr, unsigned int value)
//{
// unsigned char BIP8 = 0;
//
// TxAddr[0] = reg_addr >> 8; //MSB of address
// TxAddr[1] = reg_addr & 0xFF; //LSB of address
// TxData[0] = value >> 8;
// TxData[1] = value & 0xFF;
//
// UCB0CTL1 &= ~UCSWRST;
// UCB0CTL1 |= UCTXSTT + UCTR; //start i2c write operation
//
// //write the address
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = TxAddr[0];
// BIP8 ^= TxAddr[0];
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = TxAddr[1];
// BIP8 ^= TxAddr[1];
//
// //write the data
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = TxData[0];
// BIP8 ^= TxData[0];
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = TxData[1];
// BIP8 ^= TxData[1];
//
// //send BIP8 byte
// while(!(IFG2 & UCB0TXIFG));
// UCB0TXBUF = BIP8;
//
// while(!(IFG2 & UCB0TXIFG));
// UCB0CTL1 |= UCTXSTP;
// while((UCB0STAT & UCBBUSY));; // Ensure stop condition got sent
// UCB0CTL1 |= UCSWRST;
//
//}
//writes the register at reg_addr and incrementing addresses with the data at "write_data" of length data_length
void Write_Continuous(unsigned int reg_addr, unsigned char* write_data, unsigned int data_length)
{
// I2C_write16()
unsigned int i;
I2C_setMode(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_MODE);
/* Clear any existing interrupt flag PL */
I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Wait until ready to write PL */
while (I2C_isBusBusy(EUSCI_B1_BASE));
/* Initiate start and send MSB first character */
I2C_masterSendMultiByteStart(EUSCI_B1_BASE,
(unsigned char)(reg_addr>>8));
/* Send the LSB of pointer */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
(unsigned char)(reg_addr));
for(i = 0; i < data_length-1; i++)
{
/* Send the MSB to SENSOR */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
write_data[i]);
}
i++;
I2C_masterSendMultiByteFinish(EUSCI_B1_BASE,
write_data[i]);
// TxAddr[0] = reg_addr >> 8; //MSB of address
// TxAddr[1] = reg_addr & 0xFF; //LSB of address
//
// UCB1CTL1 &= ~UCSWRST;
// UCB1CTL1 |= UCTXSTT + UCTR; //start i2c write operation
// //write the address
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = TxAddr[0];
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = TxAddr[1];
//
// for(i = 0; i < data_length; i++)
// {
// while(!(UCB1IFG & UCTXIFG0));
// UCB1TXBUF = write_data[i];
// }
//
// while(!(UCB1IFG & UCTXIFG0));
// UCB1CTL1 |= UCTXSTP;
// while((UCB1STAT & UCBBUSY)); // Ensure stop condition got sent
// UCB1CTL1 |= UCSWRST;
}
main.c
C/C++/*
* {main.c}
*{main application}
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
*
*
* 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 Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, 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.
*
*/
//******************************************************************************
// RF430 NFC Booster Pack (Host/Master)
//
// RF430 User Address Map
// -----------------------------------------
// Address | Size | Description |
// -----------------------------------------
// 0xFFFE | 2B | Control Register |
// 0xFFFC | 2B | Status Register |
// 0xFFFA | 2B | Interrupt Enable |
// 0xFFF8 | 2B | Interrupt Flags |
// 0xFFF6 | 2B | CRC Result |
// 0xFFF4 | 2B | CRC Length |
// 0xFFF2 | 2B | CRC Start Address |
// 0xFFF0 | 2B | Comm WD Ctrl Reg |
// -----------------------------------------
// 0x0000 - | 2kB | NDEF App Memory |
// 0x07FF | | |
//
// Description: This demo demonstrates RF430 read/write accesses via the I2C bus.
// This is the code for the tester/host processor, which is the MASTER. This master
// can send read and write commands over I2C to access the data structure in the
// RF430 device. The following formats are used:
//
// Write Access:
// The master transmits a 2 byte address, then transmits N 16 bit values MSB first
// to be stored by RF430 in locations starting at this address and incrementing.
//
// Read Access:
// The master transmits a 2 byte address, then receives back from RF430
// the two bytes RF430 has stored at this location, MSB first.
//
// Continuous Read Access:
// The master receives the N bytes stored in RF430 starting at the next address
// (next address = the last accessed address + 2) and incrementing, MSB first.
//
//
// /|\ /|\ (Host/Tester)
// RF430 10k 10k MSP430G2553
// (Slave) | | Master
// _________________ | | _________________
// | SDA|<-|----+->|P1.7/UCB0SDA XIN|-+
// | | | I2C | |
// | SCL|<-+------>|P1.6/UCB0SCL XOUT|-
// | | | |
// GND<--|E(2-0) /RST|<---------|P1.3* | (* NOTE: Will be moved on next hardware revision.)
// | INTO|--------->|P2.7* |
// | | | P1.0|---->LED1
// | | | |
// |_________________| |_________________|
//
// Built with CCSv5.2
//******************************************************************************
#include "driverlib.h"
#include "msp.h"
#include "RF430_example.h"
unsigned char NDEF_Application_Data[] = RF430_DEFAULT_DATA;
unsigned char test_data[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
unsigned char CRC_Data[] = {1,2,3,4,5,6,7,8,9};
unsigned char Cmd = 0; //Command byte for SPI mode
unsigned char read_complete = 0;
unsigned char rx_byte_count = 0;
unsigned char tx_byte_count = 0;
unsigned int Results[11] = {0,0,0,0,0,0,0,0,0,0,0};
//const eUSCI_I2C_MasterConfig i2cConfig =
//{
// EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
// 48000000, // SMCLK = 48MHz
// EUSCI_B_I2C_SET_DATA_RATE_400KBPS, // Desired I2C Clock of 100khz
// 0, // No byte counter threshold
// EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
//};
//void Init_I2C_GPIO()
//{
// /* Select I2C function for I2C_SCL(P6.5) & I2C_SDA(P6.4) */
// GPIO_setAsPeripheralModuleFunctionOutputPin(
// GPIO_PORT_P6,
// GPIO_PIN5,
// GPIO_SECONDARY_MODULE_FUNCTION );
//
// GPIO_setAsPeripheralModuleFunctionOutputPin(
// GPIO_PORT_P6,
// GPIO_PIN4,
// GPIO_SECONDARY_MODULE_FUNCTION );
//}
//
//void I2C_init(void)
//{
// /* Initialize USCI_B0 and I2C Master to communicate with slave devices*/
// I2C_disableModule(EUSCI_B1_MODULE);
//
// I2C_initMaster(EUSCI_B1_MODULE, &i2cConfig);
//
// /* Disable I2C module to make changes */
// //I2C_disableModule(EUSCI_B1_MODULE);
//
// /* Enable I2C Module to start operations */
// I2C_enableModule(EUSCI_B1_BASE);
//
// return;
//}
/****************************************************************************/
/* Code-binary that opens on ETW and re-trims LF oscillator to below 280kHz */
/****************************************************************************/
unsigned char func_retrim_osc[] = {
0xB2, 0x40, 0x11, 0x96, 0x10, 0x01,
0xB2, 0x40, 0x60, 0x03, 0x18, 0x01,
0x30, 0x41
};
unsigned char into_fired = 0;
unsigned char read_data[200];
void main (void)
{
unsigned int flags = 0;
unsigned int temp = 0;
volatile unsigned int test = 0;
//unsigned char read_data[200];
//WDTCTL = WDTPW + WDTHOLD; // Turn off Watch Dog
MAP_WDT_A_holdTimer();
MAP_Interrupt_disableMaster();
/* Initializes Clock System */
MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1 );
MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
// if (CALBC1_8MHZ==0xFF) // If calibration constant erased
// {
// while(1); // Do not load, trap CPU!!
// }
// BCSCTL1 = CALBC1_8MHZ; // Set range
// DCOCTL = CALDCO_8MHZ; // SMCLK = MCLK = DCO = 8 MHz ACLK = LF oscillator
/* Initialize I2C communication */
Init_I2C_GPIO();
I2C_init();
I2C_setslave(0x0028);
TMP006_init();
// // Configure pins for I2C
// PORT_I2C_SEL0 |= (SCL + SDA); // Selecting I2C pin function
// PORT_I2C_SEL1 |= (SCL + SDA);
//
// //configure USCI for I2C
// UCB0CTL1 |= UCSWRST; // Software reset enabled
// UCB0CTL0 |= UCMODE_3 + UCMST + UCSYNC; // I2C mode, Master mode, sync
// UCB0CTL1 |= UCSSEL_3 + UCTR; // SMCLK = 8MHz, transmitter
// UCB0BR0 = 80; // Baudrate = SMLK/80 = 100kHz
// UCB0I2CSA = 0x0028; // slave address - determined by pins E0, E1, and E2 on the RF430CL330H
// UCB0CTL1 &= ~UCSWRST; // Software reset released
// RST RF430 (in case board remained powered but the MSP430 reset for some reason - MSP430 RST button pushed for example)
PORT_RST_SEL0 &= ~RST; // Setting as GPIO pin functionality
PORT_RST_SEL1 &= ~RST;
PORT_RST_OUT &= ~RST;
PORT_RST_DIR |= RST; // RF430CL330H device in Reset
__delay_cycles(1000);
PORT_RST_OUT |= RST; // Release the RF430CL330H from Reset
//configure LED1
PORT_LED_SEL0 &= ~LED1; // Confirming GPIO pin functionality
PORT_LED_SEL1 &= ~LED1;
PORT_LED_DIR |= LED1; // Set as Output
PORT_LED_OUT &= ~LED1; // Start LED off
//configure pin for INTO interrupt
PORT_INTO_SEL0 &= ~INTO; // Confirming GPIO pin functionality
PORT_INTO_SEL1 &= ~INTO;
PORT_INTO_DIR &= ~INTO; // Set as Input
PORT_INTO_OUT |= INTO; // Set output register high
PORT_INTO_REN |= INTO; // Internal pull-up resistor
PORT_INTO_IFG &= ~INTO; // Clear interrupt flag
PORT_INTO_IES |= INTO; // Set interrupt trigger as high-to-low transition, since INTO will be setup active low below
__delay_cycles(4000000); // Leave time for the RF430CL33H to get itself initialized; should be 20ms or greater
while(!(Read_Register(STATUS_REG) & READY)); // Wait until READY bit has been set
//Turn on GPIO for supercap
P5OUT |= BIT6;
for(i=100000; i>0; i--);
P1OUT |= BIT0;
for(i=2000; i>0; i--);
P1OUT ^= BIT0;
for(i=200000; i>0; i--);
//get temperature
temp = TMP006_getTemp();
/****************************************************************************/
/* This code is used to change data rate capability */
/****************************************************************************/
// Write_Register(TEST_MODE_REG, TEST_MODE_KEY); //unlock test mode
// Write_Register(CONTROL_REG, TEST430_ENABLE); //enable test mode, now have to use actual addresses
// Write_Register(0x2a7C, 0xF7); //the bit rate capability setting, 0xF7=848kbits
// Write_Register(0x2814, 0); //exit test mode (CONTROL_REG is at real address 0x2814)
// Write_Register(TEST_MODE_REG, 0); //exiting this mode, RF is disabled as Control register is set to 0
// Write_Register(CONTROL_REG, INT_ENABLE + INTO_DRIVE + RF_ENABLE);
//while(1);
/****************************************************************************/
/* Configure RF430CL330H for Typical Usage Scenario */
/****************************************************************************/
//write NDEF memory with Capability Container + NDEF message
Write_Continuous(0, NDEF_Application_Data, 48);
//Enable interrupts for End of Read and End of Write
// Write_Register(INT_ENABLE_REG, EOW_INT_ENABLE + EOR_INT_ENABLE);
//Configure INTO pin for active low and enable RF
Write_Register(CONTROL_REG, INT_ENABLE + INTO_DRIVE + RF_ENABLE);
PORT_INTO_IFG &= ~INTO; //clear any pending flags
PORT_INTO_IE |= INTO; //enable interrupt
while (1);
{
// __bis_SR_register(LPM3_bits + GIE); //go to low power mode and enable interrupts. We are waiting for an NFC read or write of/to the RF430
__no_operation();
//device has woken up, check status
if(into_fired)
{
//before we read/write to RF430CL330H we should disable RF
Write_Register(CONTROL_REG, INT_ENABLE + INTO_DRIVE); //clear control reg to disable RF
__delay_cycles(750000);
flags = Read_Register(INT_FLAG_REG); //read the flag register to check if a read or write occurred
Write_Register(INT_FLAG_REG, EOW_INT_FLAG + EOR_INT_FLAG); //ACK the flags to clear
Write_Register(INT_ENABLE_REG, 0);
PORT_LED_OUT &= ~LED1; //clear LEDs
if(flags & EOW_INT_FLAG) //check if the tag was written
{
//tag was updated, so we should read out the new data
//read out the data
//Read_Continuous(0, read_data, 200);
__no_operation(); //breakpoint here to examine the data
//show that tag was written by blinking LED 3 times
for(temp = 0; temp < 3; temp++){
PORT_LED_OUT |= LED1;
__delay_cycles(3000000);
PORT_LED_OUT &= ~LED1;//clear LED
__delay_cycles(3000000);
}
}
else if(flags & EOR_INT_FLAG) //check if the tag was read
{
__no_operation();
//show that tag was read with LED by holding it on for 1 second
PORT_LED_OUT |= LED1;
__delay_cycles(8000000);
PORT_LED_OUT &= ~LED1;//clear LED
}
flags = 0;
into_fired = 0; //we have serviced INTO
//Enable interrupts for End of Read and End of Write
Write_Register(INT_ENABLE_REG, EOW_INT_ENABLE + EOR_INT_ENABLE);
test = Read_Register(INT_ENABLE_REG);
//Configure INTO pin for active low and re-enable RF
Write_Register(CONTROL_REG, INT_ENABLE + INTO_DRIVE + RF_ENABLE);
//re-enable INTO
PORT_INTO_IFG &= ~INTO;
PORT_INTO_IE |= INTO;
__no_operation();
}
}
}
//#pragma vector=PORT2_VECTOR
//__interrupt void PORT2_ISR(void)
//{
// //INTO interrupt fired
// if(PORT_INTO_IFG & INTO)
// {
//
// into_fired = 1;
//
// PORT_INTO_IE &= ~INTO; //disable INTO
// PORT_INTO_IFG &= ~INTO; //clear interrupt flag
//
// __bic_SR_register_on_exit(RSTCTL_PCMRESET_STAT_LPM35); //wake up to handle INTO
// }
//}
////
//#pragma vector = PORT1_VECTOR,ADC10_VECTOR,WDT_VECTOR,NMI_VECTOR,TIMER0_A1_VECTOR, \
// TIMER0_A0_VECTOR, COMPARATORA_VECTOR, TIMER1_A1_VECTOR, TIMER1_A0_VECTOR, \
// USCIAB0TX_VECTOR, USCIAB0RX_VECTOR
// __interrupt void ISR_trap(void)
// {
// while(1); // IT'S A TRAP!!!
// }
RF430_example.h
C/C++/*
* {RF430_example.h}
*
* {RF430 header}
*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
*
*
* 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 Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, 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.
*
*/
/*
* RF430_example.h
*
* Created on: Feb 6, 2013
* Author: JD Crutchfield
*/
#ifndef RF430_EXAMPLE_H_
#define RF430_EXAMPLE_H_
//#include "RF430_example.c"
unsigned int Read_Register(unsigned int reg_addr);
unsigned int Read_Register_BIP8(unsigned int reg_addr);
void Read_Continuous(unsigned int reg_addr, unsigned char* read_data, unsigned int data_length);
void Write_Register(unsigned int reg_addr, unsigned int value);
void Write_Continuous(unsigned int reg_addr, unsigned char* write_data, unsigned int data_length);
void Write_Register_BIP8(unsigned int reg_addr, unsigned int value);
void Init_I2C_GPIO(void);
void I2C_init(void);
int I2C_read16(unsigned int);
void I2C_write16(unsigned int pointer, unsigned int writeByte);
void I2C_setslave(unsigned int slaveAdr);
//MSP-EXP430G2 port definitions
//I2C
#define PORT_I2C_OUT P6OUT
#define PORT_I2C_DIR P6DIR
#define PORT_I2C_SEL0 P6SEL0
#define PORT_I2C_SEL1 P6SEL1
#define SCL BIT5 // Also Tied to LED2 but jumper must be removed
#define SDA BIT4
//INTO
#define PORT_INTO_IN P2IN
#define PORT_INTO_OUT P2OUT
#define PORT_INTO_DIR P2DIR
#define PORT_INTO_SEL0 P2SEL0
#define PORT_INTO_SEL1 P2SEL1
#define PORT_INTO_REN P2REN
#define PORT_INTO_IE P2IE
#define PORT_INTO_IES P2IES
#define PORT_INTO_IFG P2IFG
#define INTO BIT4
//RST
#define PORT_RST_OUT P2OUT
#define PORT_RST_DIR P2DIR
#define PORT_RST_SEL0 P2SEL0
#define PORT_RST_SEL1 P2SEL1
#define RST BIT0
//LEDs
#define PORT_LED_OUT P1OUT
#define PORT_LED_DIR P1DIR
#define PORT_LED_SEL0 P1SEL0
#define PORT_LED_SEL1 P1SEL1
#define LED1 BIT0
#define LED2 BIT6
//define the values for Granite's registers we want to access
#define CONTROL_REG 0xFFFE
#define STATUS_REG 0xFFFC
#define INT_ENABLE_REG 0xFFFA
#define INT_FLAG_REG 0xFFF8
#define CRC_RESULT_REG 0xFFF6
#define CRC_LENGTH_REG 0xFFF4
#define CRC_START_ADDR_REG 0xFFF2
#define COMM_WD_CTRL_REG 0xFFF0
#define VERSION_REG 0xFFEE //contains the software version of the ROM
#define TEST_FUNCTION_REG 0xFFE2
#define TEST_MODE_REG 0xFFE0
//define the different virtual register bits
//CONTROL_REG bits
#define SW_RESET BIT0
#define RF_ENABLE BIT1
#define INT_ENABLE BIT2
#define INTO_HIGH BIT3
#define INTO_DRIVE BIT4
#define BIP8_ENABLE BIT5
#define STANDBY_ENABLE BIT6
#define TEST430_ENABLE BIT7
//STATUS_REG bits
#define READY BIT0
#define CRC_ACTIVE BIT1
#define RF_BUSY BIT2
//INT_ENABLE_REG bits
#define EOR_INT_ENABLE BIT1
#define EOW_INT_ENABLE BIT2
#define CRC_INT_ENABLE BIT3
#define BIP8_ERROR_INT_ENABLE BIT4
#define NDEF_ERROR_INT_ENABLE BIT5
#define GENERIC_ERROR_INT_ENABLE BIT7
//INT_FLAG_REG bits
#define EOR_INT_FLAG BIT1
#define EOW_INT_FLAG BIT2
#define CRC_INT_FLAG BIT3
#define BIP8_ERROR_INT_FLAG BIT4
#define NDEF_ERROR_INT_FLAG BIT5
#define GENERIC_ERROR_INT_FLAG BIT7
//COMM_WD_CTRL_REG bits
#define WD_ENABLE BIT0
#define TIMEOUT_PERIOD_2_SEC 0
#define TIMEOUT_PERIOD_32_SEC BIT1
#define TIMEOUT_PERIOD_8_5_MIN BIT2
#define TIMEOUT_PERIOD_MASK BIT1 + BIT2 + BIT3
#define TEST_MODE_KEY 0x004E
#define RF430_DEFAULT_DATA { \
/*NDEF Tag Application Name*/ \
0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, \
\
/*Capability Container ID*/ \
0xE1, 0x03, \
0x00, 0x0F, /* CCLEN */ \
0x20, /* Mapping version 2.0 */ \
0x00, 0xF9, /* MLe (49 bytes); Maximum R-APDU data size */ \
0x00, 0xF6, /* MLc (52 bytes); Maximum C-APDU data size */ \
0x04, /* Tag, File Control TLV (4 = NDEF file) */ \
0x06, /* Length, File Control TLV (6 = 6 bytes of data for this tag) */ \
0xE1, 0x04, /* File Identifier */ \
0x0B, 0xDF, /* Max NDEF size (3037 bytes of useable memory) */ \
0x00, /* NDEF file read access condition, read access without any security */ \
0x00, /* NDEF file write access condition; write access without any security */ \
\
/* NDEF File ID */ \
0xE1, 0x04, \
\
/* NDEF File for Hello World */ \
0x00, 0x20, /* NLEN: NDEF length (20 byte long message, max. length for RF430CL) */ \
\
/* NDEF Record (refer to NFC Data Exchange Format specifications)*/ \
0xD1, /*MB(Message Begin), SR(Short Record) flags set, ME(Message End), IL(ID length field present) flags cleared; TNF(3bits) = 1; */ \
0x01, 0x1c, /*Type Length = 0x01; Payload Length = 0x10 */ \
0x54, /* Type = T (text) */ \
0x02, /* 1st payload byte: "Start of Text", as specified in ASCII Tables */ \
0x65, 0x6E, /* 'e', 'n', (2nd, 3rd payload bytes*/ \
\
/* 'Hello, world!' NDEF data*/ \
0x54,0x65,0x6d,0x70,0x3a,0x20,0x37,0x32,0x2c,0x20,0x68,0x6f,0x6c,0x64,0x20,0x66,0x6f,0x72,0x20,0x31,0x30,0x20,0x73,0x65,0x63 \
}//0x48, 0x65, 0x6C, 0x6C, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21 \
} /* End of data */
#endif /* RF430_EXAMPLE_H_ */
/* --COPYRIGHT--,BSD
* Copyright (c) 2015, Texas Instruments Incorporated
* 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 Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* 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.
* --/COPYRIGHT--*/
//****************************************************************************
//
// HAL_TMP006.c - Hardware abstraction layer for interfacing TMP006
//
//****************************************************************************
#include "HAL_TMP006.h"
#include "HAL_I2C.h"
#include <driverlib.h>
#include "math.h"
/* Calibration constant for TMP006 */
static long double S0 = 0;
/***************************************************************************//**
* @brief Configures the TMP006 Infrared Thermopile Sensor
* @param none
* @return none
******************************************************************************/
void TMP006_init(void)
{
/* Specify slave address for TMP006 */
I2C_setslave(TMP006_SLAVE_ADDRESS);
/* Reset TMP006 */
I2C_write16(TMP006_WRITE_REG, TMP006_RST);
volatile int i;
for (i=10000; i>0;i--);
/* Power-up and re-enable device */
I2C_write16(TMP006_WRITE_REG, TMP006_POWER_UP | TMP006_CR_2);
}
int TMP006_readDeviceId(void)
{
/* Specify slave address for TMP006 */
I2C_setslave(TMP006_SLAVE_ADDRESS);
return I2C_read16(TMP006_P_DEVICE_ID);
}
int TMP006_readObjectVoltage(void)
{
/* Specify slave address for TMP006 */
I2C_setslave(TMP006_SLAVE_ADDRESS);
return I2C_read16(TMP006_P_VOBJ);
}
int TMP006_readAmbientTemperature(void)
{
/* Specify slave address for TMP006 */
I2C_setslave(TMP006_SLAVE_ADDRESS);
return I2C_read16(TMP006_P_TABT);
}
/***************************************************************************//**
* @brief Reads data from the sensor and calculates the object temperature
* @param none
* @return Object temperature in degrees fahrenheit
******************************************************************************/
long double TMP006_getTemp(void)
{
volatile int Vobj = 0;
volatile int Tdie = 0;
Vobj = TMP006_readDeviceId();
/* Read the object voltage */
Vobj = TMP006_readObjectVoltage();
/* Read the ambient temperature */
Tdie = TMP006_readAmbientTemperature();
Tdie = Tdie >> 2;
/* Calculate TMP006. This needs to be reviewed and calibrated */
long double Vobj2 = (double)Vobj*.00000015625;
long double Tdie2 = (double)Tdie*.03525 + 273.15;
/* Initialize constants */
S0 = 6 * pow(10, -14);
long double a1 = 1.75*pow(10, -3);
long double a2 = -1.678*pow(10, -5);
long double b0 = -2.94*pow(10, -5);
long double b1 = -5.7*pow(10, -7);
long double b2 = 4.63*pow(10, -9);
long double c2 = 13.4;
long double Tref = 298.15;
/* Calculate values */
long double S = S0*(1+a1*(Tdie2 - Tref)+a2*pow((Tdie2 - Tref),2));
long double Vos = b0 + b1*(Tdie2 - Tref) + b2*pow((Tdie2 - Tref),2);
volatile long double fObj = (Vobj2 - Vos) + c2*pow((Vobj2 - Vos),2);
volatile long double Tobj = pow(pow(Tdie2,4) + (fObj/S),.25);
Tobj = (9.0/5.0)*(Tobj - 273.15) + 32;
/* Return temperature of object */
return (Tobj);
}
/* --COPYRIGHT--,BSD
* Copyright (c) 2015, Texas Instruments Incorporated
* 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 Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* 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.
* --/COPYRIGHT--*/
//****************************************************************************
//
// HAL_I2C.h - Prototypes of hardware abstraction layer for I2C between
// MSP432P401R and OPT3001
//
//****************************************************************************
#ifndef __HAL_I2C_H_
#define __HAL_I2C_H_
void Init_I2C_GPIO(void);
void I2C_init(void);
int I2C_read16(unsigned char);
void I2C_write16(unsigned char pointer, unsigned int writeByte);
void I2C_setslave(unsigned int slaveAdr);
#endif /* __HAL_I2C_H_ */
/* --COPYRIGHT--,BSD
* Copyright (c) 2015, Texas Instruments Incorporated
* 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 Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* 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.
* --/COPYRIGHT--*/
//****************************************************************************
//
// HAL_TMP006.h - Prototypes of hardware abstraction layer for interfacing TMP006
//
//****************************************************************************
#ifndef HAL_TMP006_H_
#define HAL_TMP006_H_
/* CONSTANTS */
#define TMP006_SLAVE_ADDRESS 0x40
/* TEMPERATURE SENSOR REGISTER DEFINITIONS */
#define TMP006_P_VOBJ 0x00
#define TMP006_P_TABT 0x01
#define TMP006_WRITE_REG 0x02
#define TMP006_P_MAN_ID 0xFE
#define TMP006_P_DEVICE_ID 0xFF
/* CONFIGURATION REGISTER SETTINGS */
#define TMP006_RST 0x8000
#define TMP006_POWER_DOWN 0x0000
#define TMP006_POWER_UP 0x7000
#define TMP006_CR_4 0x0000
#define TMP006_CR_2 0x0200
#define TMP006_CR_1 0x0400
#define TMP006_CR_0_5 0x0600
#define TMP006_CR_0_25 0x0800
#define TMP006_EN 0x0100
#define TMP006_DRDY 0x0080
#define I2C_SCL BIT7;
#define I2C_SDA BIT6;
void TMP006_init(void);
long double TMP006_getTemp(void);
int TMP006_readDeviceId(void);
int TMP006_readObjectVoltage(void);
int TMP006_readAmbientTemperature(void);
int TMP006_read(unsigned char);
void TMP006_write(unsigned char pointer, unsigned int writeByte);
#endif /* HAL_TMP006_H_ */
/* --COPYRIGHT--,BSD
* Copyright (c) 2015, Texas Instruments Incorporated
* 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 Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* 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.
* --/COPYRIGHT--*/
//****************************************************************************
//
// HAL_I2C.c - Hardware abstraction layer for I2C with MSP432P401R
//
//****************************************************************************
#include <driverlib.h>
#include <HAL_I2C.h>
/* I2C Master Configuration Parameter */
const eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
48000000, // SMCLK = 48MHz
EUSCI_B_I2C_SET_DATA_RATE_400KBPS, // Desired I2C Clock of 100khz
0, // No byte counter threshold
EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
};
void Init_I2C_GPIO()
{
/* Select I2C function for I2C_SCL(P6.5) & I2C_SDA(P6.4) */
GPIO_setAsPeripheralModuleFunctionOutputPin(
GPIO_PORT_P6,
GPIO_PIN5,
GPIO_PRIMARY_MODULE_FUNCTION);
GPIO_setAsPeripheralModuleFunctionOutputPin(
GPIO_PORT_P6,
GPIO_PIN4,
GPIO_PRIMARY_MODULE_FUNCTION);
}
/***************************************************************************//**
* @brief Configures I2C
* @param none
* @return none
******************************************************************************/
void I2C_init(void)
{
/* Initialize USCI_B0 and I2C Master to communicate with slave devices*/
I2C_initMaster(EUSCI_B1_MODULE, &i2cConfig);
/* Disable I2C module to make changes */
I2C_disableModule(EUSCI_B1_MODULE);
/* Enable I2C Module to start operations */
I2C_enableModule(EUSCI_B1_BASE);
return;
}
/***************************************************************************//**
* @brief Reads data from the sensor
* @param writeByte Address of register to read from
* @return Register contents
******************************************************************************/
int I2C_read16(unsigned char writeByte)
{
volatile int val = 0;
volatile int valScratch = 0;
/* Set master to transmit mode PL */
I2C_setMode(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_MODE);
/* Clear any existing interrupt flag PL */
I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Wait until ready to write PL */
while (I2C_isBusBusy(EUSCI_B1_BASE));
/* Initiate start and send first character */
I2C_masterSendMultiByteStart(EUSCI_B1_BASE, writeByte);
/* Wait for TX to finish */
while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));
/* Initiate stop only */
I2C_masterSendMultiByteStop(EUSCI_B1_BASE);
/* Wait for Stop to finish */
while(!I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_STOP_INTERRUPT));
/*
* Generate Start condition and set it to receive mode.
* This sends out the slave address and continues to read
* until you issue a STOP
*/
I2C_masterReceiveStart(EUSCI_B1_BASE);
/* Wait for RX buffer to fill */
while(!(I2C_getInterruptStatus(EUSCI_B1_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0)));
/* Read from I2C RX register */
val = I2C_masterReceiveMultiByteNext(EUSCI_B1_BASE);
/* Receive second byte then send STOP condition */
valScratch = I2C_masterReceiveMultiByteFinish(EUSCI_B1_BASE);
/* Shift val to top MSB */
val = (val << 8);
/* Read from I2C RX Register and write to LSB of val */
val |= valScratch;
/* Return temperature value */
return (int16_t)val;
}
/***************************************************************************//**
* @brief Writes data to the sensor
* @param pointer Address of register you want to modify
* @param writeByte Data to be written to the specified register
* @return none
******************************************************************************/
void I2C_write16 (unsigned char pointer, unsigned int writeByte)
{
/* Set master to transmit mode PL */
I2C_setMode(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_MODE);
/* Clear any existing interrupt flag PL */
I2C_clearInterruptFlag(EUSCI_B1_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
/* Wait until ready to write PL */
while (I2C_isBusBusy(EUSCI_B1_BASE));
/* Initiate start and send first character */
I2C_masterSendMultiByteStart(EUSCI_B1_BASE,
pointer);
/* Send the MSB to SENSOR */
I2C_masterSendMultiByteNext(EUSCI_B1_BASE,
(unsigned char)(writeByte>>8));
I2C_masterSendMultiByteFinish(EUSCI_B1_BASE,
(unsigned char)(writeByte&0xFF));
}
void I2C_setslave(unsigned int slaveAdr)
{
/* Specify slave address for I2C */
I2C_setSlaveAddress(EUSCI_B1_BASE,
slaveAdr);
/* Enable and clear the interrupt flag */
I2C_clearInterruptFlag(EUSCI_B1_MODULE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
return;
}
Comments