📄 ms5540b.c
字号:
/* ----------------------------------------------------------------------------
* 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 NOTRACE
#define NOTRACE
#endif
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "ms5540b.h"
#include <spi/spi.h>
#include <utility/trace.h>
#include <utility/assert.h>
//------------------------------------------------------------------------------
// 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_LOG(trace_DEBUG, "-D- 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_LOG(trace_DEBUG, "-D- 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_LOG(trace_DEBUG, "-D- 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_LOG(trace_DEBUG, "-D- 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_LOG(trace_DEBUG, "-D- Word1 = %d\n\r", word1);
trace_LOG(trace_DEBUG, "-D- Word2 = %d\n\r", word2);
trace_LOG(trace_DEBUG, "-D- Word3 = %d\n\r", word3);
trace_LOG(trace_DEBUG, "-D- 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_LOG(trace_DEBUG, "-D- C1 = %d\n\r", lCoeffs[0]);
trace_LOG(trace_DEBUG, "-D- C2 = %d\n\r", lCoeffs[1]);
trace_LOG(trace_DEBUG, "-D- C3 = %d\n\r", lCoeffs[2]);
trace_LOG(trace_DEBUG, "-D- C4 = %d\n\r", lCoeffs[3]);
trace_LOG(trace_DEBUG, "-D- C5 = %d\n\r", lCoeffs[4]);
trace_LOG(trace_DEBUG, "-D- 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_LOG(trace_DEBUG, "-D- 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_LOG(trace_DEBUG, "-D- 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -