OBJS+=CB_functions.o
OBJS+=usart1.o
OBJS+=spi2.o
+OBJS+=ltc1867l.o
# OBJS+=keypins.o
--- /dev/null
+
+/*!
+LTC1867: 16-Bit 8-Channel 200ksps ADC
+
+The LTC1863/LTC1867 are pin-compatible, 8-channel 12-/16-bit A/D converters with
+serial I/O, and an internal reference. The ADCs typically draw only 1.3mA from a
+single 5V supply. The 8-channel input multiplexer can be configured for either
+single-ended or differential inputs and unipolar or bipolar conversions (or
+combinations thereof). The automatic nap and sleep modes benefit power sensitive
+applications.
+
+The LTC1867's DC performance is outstanding with a +/-2LSB INL specification and
+no missing codes over temperature. The signal-to-noise ratio (SNR) for the
+LTC1867 is typically 89dB, with the internal reference.
+
+*/
+
+#include <stdint.h>
+#include "ltc1867l.h"
+#include "spi.h"
+
+
+// Reads the ADC and returns 16-bit data
+void LTC1867_read(uint8_t adc_command, uint16_t *adc_code)
+{
+ spi_writeTwoBytes((uint8_t)(adc_command & 0xFF), 0x00);
+ *adc_code = 0;
+}
+
+// Calculates the LTC1867 input's unipolar voltage given the binary data and lsb weight.
+float LTC1867_unipolar_code_to_voltage(uint16_t adc_code, float LTC1867_lsb, int32_t LTC1867_offset_unipolar_code)
+{
+ float adc_voltage;
+ adc_voltage=((float)(adc_code+LTC1867_offset_unipolar_code))*LTC1867_lsb; //! 1) Calculate voltage from ADC code, lsb, offset.
+ return(adc_voltage);
+}
+
+// Calculates the LTC1867 input's bipolar voltage given the two's compliment data and lsb weight
+float LTC1867_bipolar_code_to_voltage(uint16_t adc_code, float LTC1867_lsb, int32_t LTC1867_offset_bipolar_code)
+{
+ float adc_voltage, sign = 1.0;
+ if (adc_code>>15)
+ {
+ adc_code = (adc_code ^ 0xFFFF)+1; //! 1) Convert ADC code from two's complement to binary
+ sign = -1;
+ }
+ adc_voltage=((float)(adc_code+LTC1867_offset_bipolar_code))*LTC1867_lsb*sign; //! 2) Calculate voltage from ADC code, lsb, offset.
+ return(adc_voltage);
+}
+
+// Calibrate the lsb
+void LTC1867_cal_voltage(uint16_t zero_unipolar_code, uint16_t zero_bipolar_code, uint16_t fs_code, float zero_voltage, float fs_voltage, float *LTC1867_lsb, int32_t *LTC1867_offset_unipolar_code, int32_t *LTC1867_offset_bipolar_code)
+{
+ float temp_offset;
+ *LTC1867_lsb = (fs_voltage-zero_voltage)/((float)(fs_code - zero_unipolar_code)); //! 1) Calculate the LSB
+
+ temp_offset = (zero_voltage/ *LTC1867_lsb) - zero_unipolar_code; //! 2) Calculate Unipolar offset
+ //temp_offset = (temp_offset > (floor(temp_offset) + 0.5)) ? ceil(temp_offset) : floor(temp_offset); //! 3) Round
+ *LTC1867_offset_unipolar_code = (int32_t)temp_offset; //! 4) Cast as int32_t
+
+ temp_offset = (zero_voltage / *LTC1867_lsb) - zero_bipolar_code ; //! 5) Calculate Bipolar offset
+ //temp_offset = (temp_offset > (floor(temp_offset) + 0.5)) ? ceil(temp_offset) : floor(temp_offset); //! 6) Round
+ *LTC1867_offset_bipolar_code = (int32_t)temp_offset; //! 7) cast as int32_t
+}
--- /dev/null
+
+/*!
+LTC1867: 16-bit 8-channel 200ksps ADC
+
+The LTC1863/LTC1867 are pin-compatible, 8-channel 12-/16-bit A/D converters
+with serial I/O, and an internal reference. The ADCs typically draw only 1.3mA
+from a single 5V supply. The 8-channel input multiplexer can be configured for
+either single-ended or differential inputs and unipolar or bipolar conversions
+(or combinations thereof). The automatic nap and sleep modes benefit power
+sensitive applications.
+
+The LTC1867's DC performance is outstanding with a +/-2LSB INL specification and
+no missing codes over temperature. The signal-to-noise ratio (SNR) for the
+LTC1867 is typically 89dB, with the internal reference.
+
+SPI DATA FORMAT (MSB First):
+
+ Byte #1 Byte #2
+Data Out : D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
+Data In : SD OS S1 S0 COM UNI SLP X X X X X X X X X
+
+SD : Single/Differential Bit
+OS : ODD/Sign Bit
+Sx : Address Select Bit
+COM : CH7/COM Configuration Bit
+UNI : Unipolar/Bipolar Bit
+SLP : Sleep Mode Bit
+Dx : Data Bits
+X : Don't care
+
+
+Example Code:
+
+Read Channel 0 in Single-Ended Unipolar mode when input is with respect to GND
+
+ adc_command = LTC1867_CH0 | LTC1867_UNIPOLAR_MODE; // Build ADC command for channel 0
+ LTC1867_read(LTC1867_CS, adc_command, &adc_code); // Throws out last reading
+ LTC1867_read(LTC1867_CS, adc_command, &adc_code); // Obtains the current reading and stores to adc_code variable
+
+ // Convert adc_code to voltage
+ adc_voltage = LTC1867_unipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_unipolar_code);
+
+*/
+
+#ifndef LTC1867L_H
+#define LTC1867L_H
+
+//#include <SPI.h>
+
+//! Define the SPI CS pin
+#ifndef LTC1867_CS
+#define LTC1867_CS QUIKEVAL_CS
+#endif
+
+//! @name LTC1867 Single-Ended Channel Addresses, COM=GND
+//! @{
+// Single-Ended Channel Address When CH7/COM Pin Is used As CH7
+#define LTC1867_CH0 0x80
+#define LTC1867_CH1 0xC0
+#define LTC1867_CH2 0x90
+#define LTC1867_CH3 0xD0
+#define LTC1867_CH4 0xA0
+#define LTC1867_CH5 0xE0
+#define LTC1867_CH6 0xB0
+#define LTC1867_CH7 0xF0
+//!@}
+
+//! @name LTC1867 Differential Channel Addresses
+//! @{
+// Differential Channel Address When CH7/COM Pin Is Used As CH7
+#define LTC1867_P0_N1 0x00
+#define LTC1867_P1_N0 0x40
+
+#define LTC1867_P2_N3 0x10
+#define LTC1867_P3_N2 0x50
+
+#define LTC1867_P4_N5 0x20
+#define LTC1867_P5_N4 0x60
+
+#define LTC1867_P6_N7 0x30
+#define LTC1867_P7_N6 0x70
+//!@}
+
+//! @name LTC1867 Single-Ended Channel Addresses, COM=CH7
+//! @{
+// Channel Address When CH7/COM Pin Is Used As Common
+#define LTC1867_CH0_7COM 0x88
+#define LTC1867_CH1_7COM 0xC8
+#define LTC1867_CH2_7COM 0x98
+#define LTC1867_CH3_7COM 0xD8
+#define LTC1867_CH4_7COM 0xA8
+#define LTC1867_CH5_7COM 0xE8
+#define LTC1867_CH6_7COM 0xB8
+//!@}
+
+//! @name LTC1867 Sleep / Unipolar/Bipolar config bits
+//! @{
+// Sleep Mode Command
+#define LTC1867_SLEEP_MODE 0x02
+#define LTC1867_EXIT_SLEEP_MODE 0x00
+#define LTC1867_UNIPOLAR_MODE 0x04 // Bitwise OR with channel commands for unipolar mode
+#define LTC1867_BIPOLAR_MODE 0x00
+//!@}
+
+/*
+ Example command
+ adc_command = LTC1867_P0_N1; // Differential Bipolar Mode with CH0 as positive and CH1 as negative.
+ adc_command = LTC1867_P0_N1 | LTC1867_UNIPOLAR_MODE; // Differential Unipolar Mode with CH0 as positive and CH1 as negative.
+ */
+
+//! Reads the ADC and returns 16-bit data
+//! @return void
+void LTC1867_read(uint8_t adc_command, //!< Channel address, config bits ORed together
+ uint16_t *adc_code //!< Returns code read from ADC (from previous conversion)
+ );
+
+
+//! Calculates the LTC1867 input's unipolar voltage given the binary data and lsb weight.
+//! @return Floating point voltage
+float LTC1867_unipolar_code_to_voltage(uint16_t adc_code, //!< Raw ADC code
+ float LTC1867_lsb, //!< LSB value (volts)
+ int32_t LTC1867_offset_unipolar_code //!< Offset code
+ );
+
+//! Calculates the LTC1867 input's bipolar voltage given the two's compliment data and lsb weight
+//! @return Floating point voltage
+float LTC1867_bipolar_code_to_voltage(uint16_t adc_code, //!< Raw ADC code
+ float LTC1867_lsb, //!< LSB value (volts)
+ int32_t LTC1867_offset_bipolar_code //!< Offset code
+ );
+
+//! Calibrate the offset and LSB voltage given two measured offset codes, and a full-scale voltage with the corresponding code.
+//! @return Void
+void LTC1867_cal_voltage(uint16_t zero_unipolar_code, //!< Code from a unipolar zero reading
+ uint16_t zero_bipolar_code, //!< Code from a bipolar zero reading
+ uint16_t fs_code, //!< full-scale code
+ float zero_voltage, //!< Measured zero voltage
+ float fs_voltage, //!< Measured full-scale voltage
+ float *LTC1867_lsb, //!< Return LSB value (volts)
+ int32_t *LTC1867_offset_unipolar_code, //!< Return Unipolar Offset code, in floating point
+ int32_t *LTC1867_offset_bipolar_code //!< Return Bipolar Offset code, in floating point
+ );
+
+#endif // LTC1867_H
#include "CB_functions.h"
#include "usart1.h"
#include "spi2.h"
+#include "spi.h"
#include "periph_conf.h"
+#include "ltc1867l.h"
#define UC_NO_REGS 17
// SPIBuffer[1] = 0x5678;
init_USART1();
+
+ spi_create(SPI1, GPIOA, GPIO_Pin_8);
spi_dma_shovel();
spi_addr=(spi_addr+1)%16;
+
+
+ static uint8_t uni_bi_polar = LTC1867_UNIPOLAR_MODE; //!< The LTC1867 unipolar/bipolar mode selection
+ static float LTC1867_lsb = 6.25009537E-5; //!< Ideal LSB voltage for a perfect part
+ static int32_t LTC1867_offset_unipolar_code = 0; //!< Ideal unipolar offset for a perfect part
+ static int32_t LTC1867_offset_bipolar_code = 0; //!< Ideal bipolar offset for a perfect part
+ // Constants
+ //! Lookup table to build the command for single-ended mode, input with respect to GND
+ const uint8_t BUILD_COMMAND_SINGLE_ENDED[8] = {LTC1867_CH0, LTC1867_CH1, LTC1867_CH2, LTC1867_CH3,
+ LTC1867_CH4, LTC1867_CH5, LTC1867_CH6, LTC1867_CH7
+ }; //!< Builds the command for single-ended mode, input with respect to GND
+ ////! Lookup table to build the command for single-ended mode with channel 7 as common pin
+ //const uint8_t BUILD_COMMAND_SINGLE_ENDED_COM7[7] = {LTC1867_CH0_7COM, LTC1867_CH1_7COM, LTC1867_CH2_7COM, LTC1867_CH3_7COM,
+ // LTC1867_CH4_7COM, LTC1867_CH5_7COM, LTC1867_CH6_7COM
+ // }; //!< Builds the command for single-ended mode, input with respect to CH7
+ ////! Lookup table to build the command for differential mode with the selected uni/bipolar mode
+ //const uint8_t BUILD_COMMAND_DIFF[8] = {LTC1867_P0_N1, LTC1867_P2_N3, LTC1867_P4_N5, LTC1867_P6_N7,
+ // LTC1867_P1_N0, LTC1867_P3_N2, LTC1867_P5_N4, LTC1867_P7_N6
+ // }; //!< Build the command for differential mode
+
+
+ uint8_t channel = 0;
+ uint8_t adc_command; // The LTC1867 command byte
+ uint16_t adc_code = 0; // The LTC1867 code
+ //float adc_voltage; // The LTC1867 voltage
+ adc_command = BUILD_COMMAND_SINGLE_ENDED[channel] | uni_bi_polar;
+ LTC1867_read(adc_command, &adc_code); // Throws out last reading
+ //delay(100);
+ LTC1867_read(adc_command, &adc_code); // returnes ADC reading in adc_code
+
+ //if (uni_bi_polar == LTC1867_UNIPOLAR_MODE)
+ // adc_voltage = LTC1867_unipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_unipolar_code);
+ //else
+ // adc_voltage = LTC1867_bipolar_code_to_voltage(adc_code, LTC1867_lsb, LTC1867_offset_bipolar_code);
}
#include "spi.h"
-#define BUFFER_SIZE 2
+#define BUFFER_SIZE 4
SPI_TypeDef * SPI_Module;
GPIO_TypeDef * CS_GPIO;
spi_chipSelect();
spi_enableTxInterrupt();
}
+
+void spi_writeFourBytes(uint8_t byte3, uint8_t byte2, uint8_t byte1, uint8_t byte0){
+ while(spiBusyFlag){}
+ spiTxCounter = 4;
+ spiRxCounter = 4;
+ spiBusyFlag = 1;
+ spiDataBuffer[0] = byte0;
+ spiDataBuffer[1] = byte1;
+ spiDataBuffer[2] = byte2;
+ spiDataBuffer[3] = byte3;
+ spi_chipSelect();
+ spi_enableTxInterrupt();
+}
void spi_handleSPI1Interrupt(void){
if(SPI_I2S_GetFlagStatus(SPI_Module, SPI_I2S_FLAG_RXNE) == SET){
spi_disableTxInterrupt();
}
}
-}
\ No newline at end of file
+}