Other Parts Discussed in Thread: LMP90100
Tool/software: Code Composer Studio
Dear all,
We are trying to establish a SPI communication between LMP90100 and MSP430f5529. We have an example code from TI but could not make it work. We have gone through the code and did not come across anything related to clock settings in MSP430. We are trying to get a clock signal from P2.7 of MSP430. Any suggestions?
Kind Regards,
//****************************************************************************** // Demo Application03 for MSP430/LMP90100 Interface Code Library v1.0 // Normal Stream Read ADC Data (1 channel) with interrupt // // MSP430F5528 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | P3.3/UCA0SIMO|--> SDI // | P3.4/UCA0SOMI|<-- SDO // | P2.7/UCA0CLK|--> CLK // | P2.5|--> CSB // | P2.4|<-- DRDYB // | | // // Vishy Natarajan // Texas Instruments Inc. // October 2011 // Built with CCE Version: 4.2 and IAR Embedded Workbench Version: 5.3x //****************************************************************************** /* Copyright 2011-2012 Texas Instruments Incorporated. All rights reserved. IMPORTANT: Your use of this Software is limited to those specific rights granted under the terms of a software license agreement between the user who downloaded the software, his/her employer (which must be your employer) and Texas Instruments Incorporated (the "License"). You may not use this Software unless you agree to abide by the terms of the License. The License limits your use, and you acknowledge, that the Software may not be modified, copied or distributed unless embedded on a Texas Instruments microcontroller which is integrated into your product. Other than for the foregoing purpose, you may not use, reproduce, copy, prepare derivative works of, modify, distribute, perform, display or sell this Software and/or its documentation for any purpose. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. Should you have any questions regarding your right to use this Software, contact Texas Instruments Incorporated at www.TI.com. *******************************************************************************/ #include <stdint.h> #include "TI_LMP90100.h" #include "TI_LMP90100_register_settings.h" #include "TI_MSP430.h" #include "TI_MSP430_hardware_board.h" #include "TI_MSP430_spi.h" void TI_LMP90100_WriteRegSettings(uint8_t *); // Configure LMP90100 registers void process_adc_output(uint32_t *); // dummy adc data process function: toggles LED volatile uint8_t LMP90100_ADCDataReady = 0; // set to 1 in DRDYB interrupt service routine #define SAMPLE_ARRAY_SIZE 16 // Store last 16 ADC samples for processing #define CH_DATA_SIZE 3 // 3 bytes: ADC_DOUT2, ADC_DOUT1, ADC_DOUT0 //****************************************************************************** void main(void) { uint8_t prev_URA; // Previous Upper Register Address (URA) uint8_t count, addr, i; uint8_t read_buf[CH_DATA_SIZE]; uint32_t adc_data, adc_sample_array[SAMPLE_ARRAY_SIZE]; WDTCTL = WDTPW+WDTHOLD; // Stop WDT TI_LMP90100_LED_PxOUT |= TI_LMP90100_LED_PIN; // Set LED ON TI_LMP90100_LED_PxDIR |= TI_LMP90100_LED_PIN; // Set pin direction is output // configure Port Pin to handle Data Ready Bar Output (DRDYB) from LMP90100 TI_LMP90100_DRDYB_PxDIR &= ~TI_LMP90100_DRDYB_PIN; // Set up port pin for DRDYB TI_LMP90100_DRDYB_PxIES |= TI_LMP90100_DRDYB_PIN; // Interrupt Edge Select TI_LMP90100_DRDYB_PxIFG &= ~TI_LMP90100_DRDYB_PIN; // Clear Interrupt Flag TI_LMP90100_DRDYB_PxIE |= TI_LMP90100_DRDYB_PIN; // Enable Port interrupt TI_LMP90100_SPISetup(); // Initilaize MSP430 SPI Block prev_URA = LMP90100_URA_END; // Initialize prev_URA to invalid segment TI_LMP90100_WriteRegSettings(&prev_URA); // Set up LMP90100 for Channel 0 Scan addr = TI_LMP90100_ADC_DOUT2_REG; // Start Reading from ADC_DOUT2 Register count = CH_DATA_SIZE; // bytes to read: ADC_DOUT2 - ADCDOUT0 i = 0; while (1) { if (LMP90100_ADCDataReady) { LMP90100_ADCDataReady = 0; // clear flag TI_LMP90100_SPINormalStreamReadADC(addr, read_buf, count, &prev_URA); // read adc output into read_buf adc_data = ((uint32_t) read_buf[0] << 16) | ((uint16_t) read_buf[1] << 8) | read_buf[2]; // form raw adc output data adc_sample_array[i] = adc_data; if (++i == SAMPLE_ARRAY_SIZE) // sample array is full { process_adc_output(adc_sample_array); // dummy app function: no error toggles led i = 0; } } __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts __no_operation(); // For debugger } } //****************************************************************************** // void TI_LMP90100_WriteRegSettings(uint8_t *) // // DESCRIPTION: // LMP90100 registers are configured to the values defined LMP90100_register_settings.h // These register settings can easily be obtained from the "Register configuration file" // saved from Sensor AFE Software // // ARGUMENTS: // pURA indicating the previous register segment that was accessed //****************************************************************************** void TI_LMP90100_WriteRegSettings(uint8_t *pURA) { TI_LMP90100_SPIWriteReg(TI_LMP90100_RESETCN_REG, TI_LMP90100_RESETCN_REG_VALUE, pURA); // register and conversion reset TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_HANDSHAKECN_REG, TI_LMP90100_SPI_HANDSHAKECN_REG_VALUE, pURA); // SDO high z delayed TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_STREAMCN_REG, TI_LMP90100_SPI_STREAMCN_REG_VALUE, pURA); // normal streaming TI_LMP90100_SPIWriteReg(TI_LMP90100_PWRCN_REG, TI_LMP90100_PWRCN_REG_VALUE, pURA); // active mode TI_LMP90100_SPIWriteReg(TI_LMP90100_ADC_RESTART_REG, TI_LMP90100_ADC_RESTART_REG_VALUE, pURA); // disable restart conversion TI_LMP90100_SPIWriteReg(TI_LMP90100_GPIO_DIRCN_REG, TI_LMP90100_GPIO_DIRCN_REG_VALUE, pURA); // D6 is an output, D1-D5 are inputs TI_LMP90100_SPIWriteReg(TI_LMP90100_GPIO_DAT_REG, TI_LMP90100_GPIO_DAT_REG_VALUE, pURA); // Set D6 high TI_LMP90100_SPIWriteReg(TI_LMP90100_BGCALCN_REG, TI_LMP90100_BGCALCN_REG_VALUE, pURA); // Background calibration off TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_DRDYBCN_REG, TI_LMP90100_SPI_DRDYBCN_REG_VALUE, pURA); // enable DRDYB on D6 TI_LMP90100_SPIWriteReg(TI_LMP90100_ADC_AUXCN_REG, TI_LMP90100_ADC_AUXCN_REG_VALUE, pURA); // disable external clock detection, internal clock TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_CRC_CN_REG, TI_LMP90100_SPI_CRC_CN_REG_VALUE, pURA); // Disable CRC TI_LMP90100_SPIWriteReg(TI_LMP90100_SENDIAG_THLDH_REG, TI_LMP90100_SENDIAG_THLDH_REG_VALUE, pURA); // Sensor Diagnostic Threshold High TI_LMP90100_SPIWriteReg(TI_LMP90100_SENDIAG_THLDL_REG, TI_LMP90100_SENDIAG_THLDL_REG_VALUE, pURA); // Sensor Diagnostic Threshold Low TI_LMP90100_SPIWriteReg(TI_LMP90100_SCALCN_REG, TI_LMP90100_SCALCN_REG_VALUE, pURA); // Normal mode TI_LMP90100_SPIWriteReg(TI_LMP90100_ADC_DONE_REG, TI_LMP90100_ADC_DONE_REG_VALUE, pURA); // ADC Data unavailable // Set up scan register for conversion while (TI_LMP90100_SPIReadReg((TI_LMP90100_CH_STS_REG & TI_LMP90100_CH_SCAN_NRDY), pURA)); // wait if CH_SCAN_NRDY TI_LMP90100_SPIWriteReg(TI_LMP90100_CH_SCAN_REG, TI_LMP90100_CH_SCAN_REG_VALUE, pURA); // single CH continuous scan, ch# = 0 // CH0 in use TI_LMP90100_SPIWriteReg(TI_LMP90100_CH0_INPUTCN_REG, TI_LMP90100_CH0_INPUTCN_REG_VALUE, pURA); // diable sensor diagnostics, default ref, vinp0 vinn1 TI_LMP90100_SPIWriteReg(TI_LMP90100_CH0_CONFIG_REG, TI_LMP90100_CH0_CONFIG_REG_VALUE, pURA); // 26.83SPS, FGA off, buffer in signal path // CH1 not used TI_LMP90100_SPIWriteReg(TI_LMP90100_CH1_INPUTCN_REG, TI_LMP90100_CH1_INPUTCN_REG_VALUE, pURA); // disable sensor diagnostics, default ref, vinp2 vinn3 TI_LMP90100_SPIWriteReg(TI_LMP90100_CH1_CONFIG_REG, TI_LMP90100_CH1_CONFIG_REG_VALUE, pURA); // 26.83SPS, FGA off, buffer in signal path // CH2 not used TI_LMP90100_SPIWriteReg(TI_LMP90100_CH2_INPUTCN_REG, TI_LMP90100_CH2_INPUTCN_REG_VALUE, pURA); // disable sensor diagnostics, default ref, vinp4 vinn5 TI_LMP90100_SPIWriteReg(TI_LMP90100_CH2_CONFIG_REG, TI_LMP90100_CH2_CONFIG_REG_VALUE, pURA); // 214.65SPS, FGA off, buffer in signal path // CH3 not used TI_LMP90100_SPIWriteReg(TI_LMP90100_CH3_INPUTCN_REG, TI_LMP90100_CH3_INPUTCN_REG_VALUE, pURA); // disable sensor diagnostics, default ref, vinp6 vinn7 TI_LMP90100_SPIWriteReg(TI_LMP90100_CH3_CONFIG_REG, TI_LMP90100_CH3_CONFIG_REG_VALUE, pURA); // 214.65SPS, FGA off, buffer in signal path // CH4 not used TI_LMP90100_SPIWriteReg(TI_LMP90100_CH4_INPUTCN_REG, TI_LMP90100_CH4_INPUTCN_REG_VALUE, pURA); // diable sensor diagnostics, default ref, vinp0 vinn1 TI_LMP90100_SPIWriteReg(TI_LMP90100_CH4_CONFIG_REG, TI_LMP90100_CH4_CONFIG_REG_VALUE, pURA); // 214.65SPS, FGA off, buffer in signal path // CH5 not used TI_LMP90100_SPIWriteReg(TI_LMP90100_CH5_INPUTCN_REG, TI_LMP90100_CH5_INPUTCN_REG_VALUE, pURA); // disable sensor diagnostics, default ref, vinp2 vinn3 TI_LMP90100_SPIWriteReg(TI_LMP90100_CH5_CONFIG_REG, TI_LMP90100_CH5_CONFIG_REG_VALUE, pURA); // 214.65SPS, FGA off, buffer in signal path // CH6 not used TI_LMP90100_SPIWriteReg(TI_LMP90100_CH6_INPUTCN_REG, TI_LMP90100_CH6_INPUTCN_REG_VALUE, pURA); // disable sensor diagnostics, default ref, vinp4 vinn5 TI_LMP90100_SPIWriteReg(TI_LMP90100_CH6_CONFIG_REG, TI_LMP90100_CH6_CONFIG_REG_VALUE, pURA); // 214.65SPS, FGA off, buffer in signal path } //****************************************************************************** // void process_adc_output(uint32_t *) // // DESCRIPTION: // Dummy ADC data process function: Toggles LED //****************************************************************************** void process_adc_output(uint32_t *data) { TI_LMP90100_LED_PxOUT ^= TI_LMP90100_LED_PIN; // Toggle LED } //****************************************************************************** // TI_LMP90100_SPI_DRDYB_PIN interrupt service routine #pragma vector=TI_LMP90100_DRDYB_VECTOR __interrupt void TI_LMP90100_DRDY_PORTx(void) { TI_LMP90100_DRDYB_PxIFG &= ~TI_LMP90100_DRDYB_PIN; // IFG cleared LMP90100_ADCDataReady = 1; // set flag __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU } //******************************************************************************
//****************************************************************************** // Description: This file contains functions that allow the MSP430 device to // access the SPI interface of the LMP90100. There are multiple // instances of each function; the one to be compiled is selected by the // system variable TI_LMP90100_SER_INTF, defined in "TI_LMP90100_hardware_board.h". // // MSP430/LMP90100 Interface Code Library v1.0 // // // Vishy Natarajan // Texas Instruments Inc. // October 2011 // Built with CCE Version: 4.2 and IAR Embedded Workbench Version: 5.3x //****************************************************************************** // Change Log: //****************************************************************************** // Version: 1.00 // Comments: Initial Release Version //****************************************************************************** /* Copyright 2011-2012 Texas Instruments Incorporated. All rights reserved. IMPORTANT: Your use of this Software is limited to those specific rights granted under the terms of a software license agreement between the user who downloaded the software, his/her employer (which must be your employer) and Texas Instruments Incorporated (the "License"). You may not use this Software unless you agree to abide by the terms of the License. The License limits your use, and you acknowledge, that the Software may not be modified, copied or distributed unless embedded on a Texas Instruments microcontroller which is integrated into your product. Other than for the foregoing purpose, you may not use, reproduce, copy, prepare derivative works of, modify, distribute, perform, display or sell this Software and/or its documentation for any purpose. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. Should you have any questions regarding your right to use this Software, contact Texas Instruments Incorporated at www.TI.com. *******************************************************************************/ #include <stdint.h> #include "TI_LMP90100.h" #include "TI_MSP430.h" #include "TI_MSP430_hardware_board.h" #include "TI_MSP430_spi.h" //****************************************************************************** // Support for 552x USCI_B0 //****************************************************************************** #if TI_LMP90100_SER_INTF == TI_LMP90100_SER_INTF_USCIB0_5xx //------------------------------------------------------------------------------ // void TI_LMP90100_SPISetup(void) // // DESCRIPTION: // Configures the assigned interface to function as a SPI port and // initializes it. //------------------------------------------------------------------------------ void TI_LMP90100_SPISetup(void) { TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; TI_LMP90100_CSn_PxDIR |= TI_LMP90100_CSn_PIN; // /CS disable UCB0CTL1 |= UCSWRST; // **Disable USCI state machine** UCB0CTL0 |= UCMST+UCCKPH+UCMSB+UCSYNC; // 3-pin, 8-bit SPI master UCB0CTL1 |= UCSSEL_2; // SMCLK UCB0BR0 = 0x04; // UCLK/4 UCB0BR1 = 0; TI_LMP90100_SPI_USCIB0_PxSEL1 |= TI_LMP90100_SPI_USCIB0_SIMO | TI_LMP90100_SPI_USCIB0_SOMI; TI_LMP90100_SPI_USCIB0_PxSEL2 |= TI_LMP90100_SPI_USCIB0_UCLK; // SPI option select TI_LMP90100_SPI_USCIB0_PxDIR1 |= TI_LMP90100_SPI_USCIB0_SIMO; TI_LMP90100_SPI_USCIB0_PxDIR2 |= TI_LMP90100_SPI_USCIB0_UCLK; // SPI TXD out direction UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** } //------------------------------------------------------------------------------ // void TI_LMP90100_SPIWriteReg(uint8_t addr, uint8_t value, uint8_t *pURA) // // DESCRIPTION: // Writes "value" to a single configuration register at address "addr". If // "addr" lies within the same segment as "*pURA", it takes 1 less transaction // to write the value. //------------------------------------------------------------------------------ void TI_LMP90100_SPIWriteReg(uint8_t addr, uint8_t value, uint8_t *pURA) { uint8_t new_URA, inst; new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send instruction while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = new_URA; // Send upper register address *pURA = new_URA; // save new URA } inst = LMP90100_WRITE_BIT | LMP90100_SIZE_1B |(addr & LMP90100_LRA_MASK); // lower register address while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send lower register address while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = value; // Send data value while (UCB0STAT & UCBUSY); // Wait for TX complete TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable } //------------------------------------------------------------------------------ // uint8_t TI_LMP90100_SPIReadReg(uint8_t addr, unit8_t *pURA) // // DESCRIPTION: // Reads a single configuration register at address "addr" and returns the // value read. If "addr" lies within the same segment as "*pURA", it takes 1 // less transaction to read the value. //------------------------------------------------------------------------------ uint8_t TI_LMP90100_SPIReadReg(uint8_t addr, uint8_t *pURA) { uint8_t x, new_URA, inst; new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send instruction while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = new_URA; // Send upper register address *pURA = new_URA; // save new URA } inst = LMP90100_READ_BIT | LMP90100_SIZE_1B | (addr & LMP90100_LRA_MASK); // Transaction-2 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send lower register address while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = 0; // Dummy write so we can read data while (UCB0STAT & UCBUSY); // Wait for TX complete x = UCB0RXBUF; // Read data TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable return x; } //------------------------------------------------------------------------------ // void TI_LMP90100_SPINormalStreamWriteReg(uint8_t addr, uint8_t *buffer, uint8_t count, uint8_t *pURA) // // DESCRIPTION: // Writes values to multiple configuration registers, the first register being // at address "addr". First data byte is at "buffer", and both addr and // buffer are incremented sequentially (within the LMP90100 and MSP430, // respectively) until "count" writes have been performed. If "addr" lies within // the same segment as "*pURA", it takes 1 less transaction to write the value. //------------------------------------------------------------------------------ void TI_LMP90100_SPINormalStreamWriteReg(uint8_t addr, uint8_t *buffer, uint8_t count, uint8_t *pURA) { uint8_t new_URA, inst, i; new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send instruction while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = new_URA; // Send upper register address *pURA = new_URA; // save new URA } inst = LMP90100_WRITE_BIT | LMP90100_SIZE_STREAM | (addr & LMP90100_LRA_MASK); // lower register address while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send lower register address for(i= 0; i < count; i++) { while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = *(buffer+i); // Send data value } while (UCB0STAT & UCBUSY); // Wait for TX complete TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable } //------------------------------------------------------------------------------ // void TI_LMP90100_SPIReadNormalStreamReg(uint8_t addr, unit8_t *buffer, uint8_t count, uint8_t *pURA) // // DESCRIPTION: // Reads multiple configuration registers, the first register being at address // "addr". Values read are deposited sequentially starting at address // "buffer", until "count" registers have been read. If "addr" lies within // the same segment as "*pURA", it takes 1 less transaction to read the value. //------------------------------------------------------------------------------ void TI_LMP90100_SPINormalStreamReadReg(uint8_t addr, uint8_t *buffer, uint8_t count, uint8_t *pURA) { uint8_t i, new_URA, inst; new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send instruction while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = new_URA; // Send upper register address *pURA = new_URA; // save new URA } inst = LMP90100_READ_BIT | LMP90100_SIZE_STREAM | (addr & LMP90100_LRA_MASK); // Transaction-2 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send lower register address for(i=0; i < count; i++) { while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = 0; // Dummy write so we can read data while (UCB0STAT & UCBUSY); // Wait for TX complete *(buffer+i) = UCB0RXBUF; // Read data } TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable } //------------------------------------------------------------------------------ // void TI_LMP90100_SPICRCCheck(uint8_t *buffer, uint8_t count) // // DESCRIPTION: Checks if CRC read from the device matches computed result. // CRC is computed for "count" bytes at address "buffer" and compared against CRC // stored in "buffer[count]" and returns "CRC_PASS" or "CRC_FAIL" accordingly. // //------------------------------------------------------------------------------ uint8_t TI_LMP90100_SPICRCCheck (uint8_t *buffer, uint8_t count) { uint8_t crc_data, crc_calc; crc_data = buffer[count]; // extract CRC data crc_calc = TI_LMP90100_crc8MakeBitwise2(CRC8_INIT_REM, CRC8_POLY, buffer, count); // calculate CRC for the adc output (size 3 bytes) if (crc_data == crc_calc) return CRC_PASS; else return CRC_FAIL; } //------------------------------------------------------------------------------ // void TI_LMP90100_SPINormalStreamReadADC(uint8_t addr, uint8_t *buffer, uint8_t count, uint8_t *pURA) // // DESCRIPTION: // Special read function for reading ADC data registers. Reads multiple registers, // the first register being at address"addr". Values read are deposited sequentially // starting at address "buffer", until "count" registers have been read. If "addr" lies // within the same segment as "*pURA", it takes 1 less transaction to read the value. //------------------------------------------------------------------------------ void TI_LMP90100_SPINormalStreamReadADC(uint8_t addr, uint8_t *buffer, uint8_t count, uint8_t *pURA) { uint8_t i, new_URA, inst; new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send instruction while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = new_URA; // Send upper register address *pURA = new_URA; // save new URA } inst = LMP90100_READ_BIT | LMP90100_SIZE_STREAM | (addr & LMP90100_LRA_MASK); // Transaction-2 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send lower register address for(i=0; i<count; i++) { while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = 0; // Dummy write so we can read data while (UCB0STAT & UCBUSY); // Wait for TX complete *(buffer+i) = UCB0RXBUF; // Read register data } TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable } //------------------------------------------------------------------------------ // void TI_LMP90100_SPIControlledStreamReadADC(uint8_t addr, uint8_t *buffer, uint8_t count, uint8_t *pURA) // // DESCRIPTION: // Special read function for reading ADC data registers in Controlled Stream Mode. // Reads multiple registers, the first register being at address"addr". Values read // are deposited sequentiallystarting at address "buffer", until "count" registers // have been read. If "addr" lies within the same segment as "*pURA", it takes 1 less // transaction to read the value. //------------------------------------------------------------------------------ void TI_LMP90100_SPIControlledStreamReadADC(uint8_t addr, uint8_t *buffer, uint8_t count, uint8_t *pURA) { uint8_t i, new_URA, inst; static uint8_t repeat_controlled = 0; // if set, LRA transaction is skipped new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address // CS Enable/Disable done outside so it is for entire controlled stream transaction // TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable if (*pURA != new_URA) // if new and previous URA not same, add transaction 1 { inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send instruction while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = new_URA; // Send upper register address *pURA = new_URA; // save new URA if (repeat_controlled) repeat_controlled = 0; } if (!repeat_controlled) { inst = LMP90100_READ_BIT | LMP90100_SIZE_STREAM | (addr & LMP90100_LRA_MASK); // Transaction-2 while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = inst; // Send lower register address repeat_controlled = 1; } for(i=0; i<count; i++) { while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = 0; // Dummy write so we can read data while (UCB0STAT & UCBUSY); // Wait for TX complete *(buffer+i) = UCB0RXBUF; // Read register data } // TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable } //------------------------------------------------------------------------------ // void TI_LMP90100_SPIDataOnlyReadADC(uint8_t addr, uint8_t *buffer, uint8_t count, uint8_t *pURA) // // DESCRIPTION: // Special read function for reading ADC data registers in Data only read mode. Values read // deposited sequentialy starting at address "buffer", until "count" registers have been read. // In order to use the data only read transaction capability of the LMP90100, the data first // mode must be enabled by calling TI_LMP90100_SPIEnableDataFirstMode() function. //------------------------------------------------------------------------------ void TI_LMP90100_SPIDataOnlyReadADC(uint8_t *buffer, uint8_t count) { uint8_t i; TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable for(i=0; i<count; i++) { while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF =0; // Dummy write so we can read data while (UCB0STAT & UCBUSY); // Wait for TX complete *(buffer+i) = UCB0RXBUF; // Read register data } TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable } //------------------------------------------------------------------------------ // void TI_LMP90100_crc8MakeBitwise2(uint8_t crc, uint8_t poly, uint8_t *pmsg, uint8_t msg_size) // // DESCRIPTION: Compute 8bit CRC of data "*pmsg" of size "msg_size" bytes using polynomial "poly" and init value "crc" // // //------------------------------------------------------------------------------ uint8_t TI_LMP90100_crc8MakeBitwise2(uint8_t crc, uint8_t poly, uint8_t *pmsg, uint8_t msg_size) { uint8_t i, j; uint8_t msg; for(i = 0 ; i < msg_size ; i ++) { msg = (*pmsg++ << 0); for(j = 0 ; j < 8 ; j++) { if((msg ^ crc) >> 7) crc = (crc << 1) ^ poly; else crc <<= 1; msg <<= 1; } } return(crc ^ CRC8_FINAL_XOR); } //------------------------------------------------------------------------------ // void TI_LMP90100_SPIEnableDataFirstMode(uint8_t addr, uint8_t count, uint8_t *pURA) // // DESCRIPTION: // Enables the data first mode of LMP90100. DATA_ONLY_1 and DATA_ONLY_2 registers are initialized // to "addr" and "count-1" and the LMP90100 is placed in the data first mode. In order to use the // data only read transaction capability of the LMP90100, the data first mode must be enabled. // //------------------------------------------------------------------------------ void TI_LMP90100_SPIEnableDataFirstMode(uint8_t addr, uint8_t count, uint8_t *pURA) { TI_LMP90100_SPIWriteReg(TI_LMP90100_DATA_ONLY_1_REG, addr, pURA); // Load DATA_ONLY_1 register with address TI_LMP90100_SPIWriteReg(TI_LMP90100_DATA_ONLY_2_REG, count-1, pURA); // Load DATA_ONLY_2 register with count-1 TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = LMP90100_DATA_FIRST_MODE_INSTRUCTION_ENABLE; // write Data First mode instruction while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = LMP90100_DATA_FIRST_MODE_INSTRUCTION_READ_MODE_STATUS; // Write read mode status instruction while (UCB0STAT & UCBUSY); // Wait for TX complete while (!(UCB0RXBUF & LMP90100_DATA_FIRST_MODE_STATUS_FLAG)) // wait for device to enter data first mode { UCB0TXBUF = LMP90100_DATA_FIRST_MODE_INSTRUCTION_READ_MODE_STATUS; // Write device read mode status instruction while (UCB0STAT & UCBUSY); // Wait for TX complete } TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable } //------------------------------------------------------------------------------ // void TI_LMP90100_SPIDisableDataFirstMode(uint8_t *buffer, uint8_t count) // // DESCRIPTION: // Disables the data first mode of LMP90100. Reads data bytes of the data only transaction // and then disables the data first mode of LMP90100. The data only transaction bytes are // deposited sequentially starting at address "buffer", until "count" registers have been read. // //------------------------------------------------------------------------------ void TI_LMP90100_SPIDisableDataFirstMode(uint8_t *buffer, uint8_t count) { uint8_t i; TI_LMP90100_CSn_PxOUT &= ~TI_LMP90100_CSn_PIN; // /CS enable // Method to disable data first mode: First read the data & then disable for(i=0; i<count; i++) { while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF =0; // Dummy write so we can read data while (UCB0STAT & UCBUSY); // Wait for TX complete *(buffer+i) = UCB0TXBUF; // Read register data } while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = LMP90100_DATA_FIRST_MODE_INSTRUCTION_DISABLE; // Disable Data First Mode while (!(UCB0IFG&UCTXIFG)); // Wait for TXBUF ready UCB0TXBUF = LMP90100_DATA_FIRST_MODE_INSTRUCTION_READ_MODE_STATUS; // Write device read mode status instruction while (UCB0STAT & UCBUSY); // Wait for TX complete while (UCB0RXBUF & LMP90100_DATA_FIRST_MODE_STATUS_FLAG) // wait for device to exit data first mode { UCB0TXBUF = LMP90100_DATA_FIRST_MODE_INSTRUCTION_READ_MODE_STATUS; // Write device read mode status instruction while (UCB0STAT & UCBUSY); // Wait for TX complete } TI_LMP90100_CSn_PxOUT |= TI_LMP90100_CSn_PIN; // /CS disable } //------------------------------------------------------------------------------ #endif