From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- components/sensors/ms5540b/ms5540b.c | 327 +++++++++++++++++++++++++++++++++++ components/sensors/ms5540b/ms5540b.h | 52 ++++++ 2 files changed, 379 insertions(+) create mode 100644 components/sensors/ms5540b/ms5540b.c create mode 100644 components/sensors/ms5540b/ms5540b.h (limited to 'components/sensors/ms5540b') diff --git a/components/sensors/ms5540b/ms5540b.c b/components/sensors/ms5540b/ms5540b.c new file mode 100644 index 0000000..ae6b3cf --- /dev/null +++ b/components/sensors/ms5540b/ms5540b.c @@ -0,0 +1,327 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * 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 disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +#undef TRACE_LEVEL +#define TRACE_LEVEL 0 + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include "ms5540b.h" +#include +#include +#include + +//------------------------------------------------------------------------------ +// Local definitions +//------------------------------------------------------------------------------ + +/// Baudrate divisor value. +#define SCBR (0xFF << 8) + +/// Command for retrieving calibration word 1. +#define CMD_WORD_1 /*0x0EA8*/ 0x1D50 +/// Command for retrieving calibration word 2. +#define CMD_WORD_2 /*0x0EB0*/ 0x1D60 +/// Command for retrieving calibration word 3. +#define CMD_WORD_3 /*0x0EC8*/ 0x1D90 +/// Command for retrieving calibration word 4. +#define CMD_WORD_4 /*0x0ED0*/ 0x1DA0 +/// Command for starting a pressure conversion. +#define CMD_PRES 0x0F40 +/// Command for starting a temperature conversion. +#define CMD_TEMP 0x0F20 + +/// Driver is idle. +#define STATE_IDLE 0 +/// Driver is performing a temperature conversion. +#define STATE_TEMP 1 +/// Driver is performing a pressure conversion. +#define STATE_PRES 2 + +//------------------------------------------------------------------------------ +// Local variables +//------------------------------------------------------------------------------ + +/// SPI peripheral used to connect to the MS5540B. +static AT91S_SPI *lpSpi; + +/// Chip select configured for the sensor. +static unsigned int lCs; + +/// Calibration coefficients. +static unsigned short lCoeffs[6]; + +/// Current driver state. +static unsigned char lState; + +/// Last temperature measurement made. +static unsigned short lD2 = 0; + +//------------------------------------------------------------------------------ +// Local functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Reads & returns the result of the last command. +//------------------------------------------------------------------------------ +unsigned short Fetch(void) +{ + unsigned short result; + + // Configure SPI to receive the first 8 data bytes + SPI_ConfigureNPCS(lpSpi, lCs, AT91C_SPI_BITS_8 | SCBR); + + // Read the first 8 bytes + SPI_Write(lpSpi, lCs, 0); + while (!SPI_IsFinished(lpSpi)); + result = (SPI_Read(lpSpi) & 0xFF) << 8; + + // Configure SPI to receive the next 8 bytes (with one dummy byte) + SPI_ConfigureNPCS(lpSpi, lCs, AT91C_SPI_BITS_9 | SCBR); + + // Read the last 8 bytes + SPI_Write(lpSpi, lCs, 0); + while (!SPI_IsFinished(lpSpi)); + result |= (SPI_Read(lpSpi) >> 1) & 0xFF; + + TRACE_DEBUG("MS5540B_Fetch: Result = %d\n\r", result); + + return result; +} + +//------------------------------------------------------------------------------ +/// Resets the sensor. +//------------------------------------------------------------------------------ +static void Reset() +{ + const unsigned short pCommand[] = {0x00AA, 0x1540}; + + SANITY_CHECK(SPI_IsFinished(lpSpi)); + + TRACE_DEBUG("MS5540B_Reset()\n\r"); + + // Configure chip select for 8 bits transfer + SPI_ConfigureNPCS(lpSpi, lCs, AT91C_SPI_NCPHA | AT91C_SPI_BITS_8 | SCBR); + + // Transfer first 8 bits + SPI_Write(lpSpi, lCs, pCommand[0]); + while (!SPI_IsFinished(lpSpi)); + + // Configure chip select for 13 bits transfer + SPI_ConfigureNPCS(lpSpi, lCs, AT91C_SPI_NCPHA | AT91C_SPI_BITS_13 | SCBR); + + // Transfer remaining 13 bits + SPI_Write(lpSpi, lCs, pCommand[1]); + while (!SPI_IsFinished(lpSpi)); +} + +//------------------------------------------------------------------------------ +/// Reads and returns a calibration word from the sensor. +/// \param cmd Command to retrieve desired word (CMD_WORD_1 ... CMD_WORD_4). +//------------------------------------------------------------------------------ +static unsigned short ReadCalibrationWord(unsigned short cmd) +{ + TRACE_DEBUG("MS5540B_ReadCalibrationWord(0x%04X)\n\r", cmd); + + SANITY_CHECK((cmd == CMD_WORD_1) + || (cmd == CMD_WORD_2) + || (cmd == CMD_WORD_3) + || (cmd == CMD_WORD_4)); + SANITY_CHECK(SPI_IsFinished(lpSpi)); + + // Configure SPI to send the command + SPI_ConfigureNPCS(lpSpi, lCs, AT91C_SPI_NCPHA | AT91C_SPI_BITS_13 | SCBR); + + // Transfer command + SPI_Write(lpSpi, lCs, cmd); + while (!SPI_IsFinished(lpSpi)); + + // Read & return result + return Fetch(); +} + +//------------------------------------------------------------------------------ +// Global functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// Initializes a MS5540B sensor. The provided SPI peripheral is configured +/// for the sensor (using the given chip select), and the calibration data +/// is extracted. +/// The sensor MUST BE CLOCKED before calling this function. It can then be +/// unclocked in-between measurements. +/// In addition, the SPI peripheral must be configured properly prior to calling +/// this function. +/// \param pSpi Pointer to the SPI peripheral connected to the MS5540B. +/// \param cs Chip select value to use. +//------------------------------------------------------------------------------ +void MS5540B_Initialize(AT91S_SPI *pSpi, unsigned char cs) +{ + unsigned short word1, word2, word3, word4; + + SANITY_CHECK(pSpi); + + TRACE_DEBUG("MS5540B_Initialize(0x%08X, %d)\n\r", pSpi, cs); + + // Store SPI information + lpSpi = pSpi; + lCs = cs; + lState = STATE_IDLE; + + // Reset the sensor + Reset(); + + // Extract calibration data from the sensor + word1 = ReadCalibrationWord(CMD_WORD_1); + word2 = ReadCalibrationWord(CMD_WORD_2); + word3 = ReadCalibrationWord(CMD_WORD_3); + word4 = ReadCalibrationWord(CMD_WORD_4); + + TRACE_DEBUG("Word1 = %d\n\r", word1); + TRACE_DEBUG("Word2 = %d\n\r", word2); + TRACE_DEBUG("Word3 = %d\n\r", word3); + TRACE_DEBUG("Word4 = %d\n\r", word4); + + // Compute coefficients + lCoeffs[0] = (word1 >> 1) & 0x7FFF; + lCoeffs[1] = (word4 & 0x003F) | ((word3 & 0x003F) << 6); + lCoeffs[2] = (word4 >> 6) & 0x03FF; + lCoeffs[3] = (word3 >> 6) & 0x03FF; + lCoeffs[4] = ((word2 >> 6) | ((word1 & 0x0001) << 10)) & 0x07FF; + lCoeffs[5] = word2 & 0x003F; + + TRACE_DEBUG("C1 = %d\n\r", lCoeffs[0]); + TRACE_DEBUG("C2 = %d\n\r", lCoeffs[1]); + TRACE_DEBUG("C3 = %d\n\r", lCoeffs[2]); + TRACE_DEBUG("C4 = %d\n\r", lCoeffs[3]); + TRACE_DEBUG("C5 = %d\n\r", lCoeffs[4]); + TRACE_DEBUG("C6 = %d\n\r", lCoeffs[5]); +} + +//------------------------------------------------------------------------------ +/// Starts a temperature acquisition. This function returns as soon as the +/// command has been sent. +/// The conversion must be completed by calling MS5540B_ConversionFinished() +/// whenever the device signals the end-of-conversion. +//------------------------------------------------------------------------------ +void MS5540B_AcquireTemperature(void) +{ + SANITY_CHECK(lState == STATE_IDLE); + + TRACE_DEBUG("MS5540B_AcquireTemperature()\n\r"); + + // Configure SPI for 12 bits transfers + SPI_ConfigureNPCS(lpSpi, lCs, AT91C_SPI_NCPHA | AT91C_SPI_BITS_12 | AT91C_SPI_CSAAT | SCBR); + + // Send command + SPI_Write(lpSpi, lCs, CMD_TEMP); + while (!SPI_IsFinished(lpSpi)); + + // Update driver state + lState = STATE_TEMP; +} + +//------------------------------------------------------------------------------ +/// Starts a pressure acquisition. This function returns as soon as the +/// command has been sent. +/// The conversion must be completed by calling MS5540B_ConversionFinished() +/// whenever the device signals the end-of-conversion. +/// A temperature measurement must have been performed prior to calling this +/// function. +//------------------------------------------------------------------------------ +void MS5540B_AcquirePressure(void) +{ + SANITY_CHECK(lState == STATE_IDLE); + SANITY_CHECK(lD2 != 0); + + TRACE_DEBUG("MS5540B_AcquirePressure()\n\r"); + + // Configure SPI for 12 bits transfers + SPI_ConfigureNPCS(lpSpi, lCs, AT91C_SPI_NCPHA | AT91C_SPI_BITS_12 | AT91C_SPI_CSAAT | SCBR); + + // Send command + SPI_Write(lpSpi, lCs, CMD_PRES); + while (!SPI_IsFinished(lpSpi)); + + // Update driver state + lState = STATE_PRES; +} + +//------------------------------------------------------------------------------ +/// Fetches and returns the result of the last conversion from the sensor. This +/// function must only be called whenever the MS5540B signals that the +/// conversion is completed with the DOUT signal line. +/// The temperature returned is 10*C° (e.g. 31.4°C -> 314). +//------------------------------------------------------------------------------ +unsigned short MS5540B_ConversionFinished(void) +{ + signed short result; + signed short dT; + unsigned short offset, sensitivity, x; + + SANITY_CHECK((lState == STATE_TEMP) || (lState == STATE_PRES)); + + TRACE_DEBUG("MS5540B_ConversionFinished()\n\r"); + + // Retrieve conversion result + result = (signed short) Fetch(); + + // Correct result using calibration data + if (lState == STATE_TEMP) { + + lD2 = result; + dT = result - 8 * lCoeffs[4] - 20224; + result = 200 + dT * (lCoeffs[5] + 50) / 1024; + TRACE_DEBUG("D2 = %d\n\r", lD2); + TRACE_DEBUG("dT = %d\n\r", dT); + TRACE_DEBUG("TEMP = %d\n\r", result); + } + else { + + TRACE_DEBUG("D1 = %d\n\r", result); + dT = lD2 - 8 * lCoeffs[4] - 20224; + offset = lCoeffs[1] * 4 + ((lCoeffs[3] - 512) * dT) / 4096; + sensitivity = lCoeffs[0] + (lCoeffs[2] * dT) / 1024 + 24576; + x = (sensitivity * (result - 7168)) / 16384 - offset; + result = x * 10 / 32 + 2500; + TRACE_DEBUG("dT = %d\n\r", dT); + TRACE_DEBUG("OFF = %d\n\r", offset); + TRACE_DEBUG("SENS = %d\n\r", sensitivity); + TRACE_DEBUG("X = %d\n\r", x); + TRACE_DEBUG("P = %d\n\r", result); + } + + // Update driver state + lState = STATE_IDLE; + + return result; +} + diff --git a/components/sensors/ms5540b/ms5540b.h b/components/sensors/ms5540b/ms5540b.h new file mode 100644 index 0000000..3057f09 --- /dev/null +++ b/components/sensors/ms5540b/ms5540b.h @@ -0,0 +1,52 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * 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 disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL 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. + * ---------------------------------------------------------------------------- + */ + +#ifndef MS5540B_H +#define MS5540B_H + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// Global functions +//------------------------------------------------------------------------------ + +extern void MS5540B_Initialize(AT91S_SPI *pSpi, unsigned char cs); + +extern void MS5540B_AcquireTemperature(void); + +extern void MS5540B_AcquirePressure(void); + +extern unsigned short MS5540B_ConversionFinished(void); + +#endif //#ifndef MS5540B_H + -- cgit v1.2.3