This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problem with SPI communication read/write for MS5540C.

Hello to all,

I am using nRF52840 DK with SDK15.0 and SES. To communicate with MS5540C I have used SPI master sample example but getting some incorrect results.

Almost 4 days I have spend to analyse this issue but still get same problem. I want to send the following commands to sensor:

Conversion start for pressure measurement (D1): 0Fh & 40h
Conversion start for temperature measurement (D2): 0Fh & 20h
Read calibration word 1 (W1): 1Dh & 50h
Read calibration word 2 (W2): 1Dh & 60h
Read calibration word 3 (W3): 1Dh & 90h
Read calibration word 4 (W4): 1Dh & A0h
Reset sequence command: 15h & 55h & 40h 

I am able to read word1-4 but not confirm is this correct result or Not and problem getting for read D1 and D2 continuously getting FF FF value. 

Will you please review my below program snippet and is it correct?

static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
static volatile bool start_measurement = false;
/* Configure MS5540C Sensor Register frame & Sequence */
static uint8_t       reset_seq[] = { 0x15, 0x55, 0x40 };     /**< TX buffer. */
static uint8_t       address_word1[] = { 0x1D, 0x50, 0x00, 0x00 };       /**< TX buffer. */
static uint8_t       address_word2[] = { 0x1D, 0x60, 0x00, 0x00 };       /**< TX buffer. */
static uint8_t       address_word3[] = { 0x1D, 0x90, 0x00, 0x00 };       /**< TX buffer. */
static uint8_t       address_word4[] = { 0x1D, 0xA0, 0x00, 0x00 };       /**< TX buffer. */
static uint8_t       address_pressure[] = { 0x0F, 0x40, 0x00, 0x00 };    /**< TX buffer. */
static uint8_t       address_temp[] = { 0x0F, 0x20, 0x00, 0x00 };        /**< TX buffer. */
static uint8_t       m_rx_buf[sizeof(address_word1)];    /**< RX buffer. */
static uint8_t       p_rx_buff[sizeof(address_pressure)];    /**< RX buffer. */
//static uint8_t start = 0x1D;
//static uint8_t add_word1 = 0x50;
static const uint8_t m_length = sizeof(m_rx_buf);

/* Declair coefficients factor of MS5540C sensor */
static long c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0;
unsigned int sensor_val = 0;

/**
 * @brief SPI user event handler.
 * @param event
 */
void spi_event_handler(nrf_drv_spi_evt_t const *p_event, void *p_context) {
  spi_xfer_done = true;
  NRF_LOG_DEBUG("Transfer completed.");
  if (m_rx_buf[0] != 0) {
    NRF_LOG_INFO(" Received:");
    NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
    NRF_LOG_HEXDUMP_INFO(m_rx_buf2, strlen((const char *)m_rx_buf2));
  }
}

void wait_for_spi_event() {
  while (!spi_xfer_done) {
    idle_state_handle();
  }
}

/**
 * Initialized SPI driver and their pin configurations
 */
void spi_init() {
  nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
//  spi_config.ss_pin = SPI_SS_PIN; /* Vibzer PCB Pin: 25*/
  spi_config.miso_pin = SPI_MISO_PIN; /* Vibzer PCB Pin: 27*/
  spi_config.mosi_pin = SPI_MOSI_PIN; /* Vibzer PCB Pin: 26*/
  spi_config.sck_pin = SPI_SCK_PIN; /* Vibzer PCB Pin: 28*/
  spi_config.mode    = NRF_DRV_SPI_MODE_0;
  spi_config.frequency    = NRF_SPI_FREQ_500K;
  spi_config.bit_order    = NRF_SPI_BIT_ORDER_MSB_FIRST;
  APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
}

/**
 * reset sensor module and send sequence.
 */
void reset_sensor() {
  NRF_LOG_INFO("Reset Sensor");
  spi_xfer_done = false;
  APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, reset_seq, sizeof(reset_seq), NULL, 0));
  wait_for_spi_event();
  NRF_LOG_FLUSH();
}

/**
 * brief function Read calibration data (factory calibrated) from PROM of MS5540C
 * by sending specific address.
 */
unsigned int read_cal_word(const uint8_t *address) {
  spi_xfer_done = false;
  unsigned int word = 0;
  uint8_t dummy_byte = 0x00;
  memset(m_rx_buf, 0, m_length);
  memset(m_rx_buf2, 0, sizeof(m_rx_buf2));
//  NRF_LOG_INFO("m_length: %d", m_length)
//  NRF_LOG_INFO("address: %s", (uint32_t)address);
  reset_sensor(); /*Before read calibration word need to reset sensor module*/
  APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, address, sizeof(address), m_rx_buf, sizeof(m_rx_buf)));
  nrf_delay_ms(200);
  wait_for_spi_event();
  NRF_LOG_FLUSH();
  APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, &dummy_byte, sizeof(dummy_byte), m_rx_buf2, sizeof(m_rx_buf2)));
  wait_for_spi_event();
  nrf_delay_ms(200);
  NRF_LOG_INFO("RX Buff_byte1:%X byte2:%X", m_rx_buf[2], m_rx_buf[3]);
  word = (m_rx_buf[2] << 8) | m_rx_buf[3]; /*Combine received 2 bytes from sensor*/
//  NRF_LOG_DEBUG("Return Calibration word = %u", word);
  return word;
}

/**
 * brief function for sensor initialized to read factory calibrated data from PROM of MS5540C
 */
void sensor_init() {
  unsigned int word1 = 0; /*Calibration Word 1 */
  unsigned int word2 = 0; /*Calibration Word 2 */
  unsigned int word3 = 0; /*Calibration Word 3 */
  unsigned int word4 = 0; /*Calibration Word 4 */
  
  /* Read Calibration Word 1 */
  word1 = read_cal_word(address_word1);
  NRF_LOG_DEBUG("Calibration Word 1: %u", word1);
  nrf_delay_ms(200);
  /* Read Calibration Word 2 */
  word2 = read_cal_word(address_word2);
  NRF_LOG_DEBUG("Calibration Word 2: %u", word2);
  nrf_delay_ms(200);
  /* Read Calibration Word 3 */
  word3 = read_cal_word(address_word3);
  NRF_LOG_DEBUG("Calibration Word 3: %u", word3);
  nrf_delay_ms(200);
  /* Read Calibration Word 4 */
  word4 = read_cal_word(address_word4);
  NRF_LOG_DEBUG("Calibration Word 4: %u", word4);
  nrf_delay_ms(200);
  /*Do some bitshifting to extract the calibration factors*/
   /*Convert calibration data into coefficients*/
  c1 = (word1 >> 1);
  c2 = ((word3 & 0x3F) << 6) | (word4 & 0x3F);
  c3 = (word4 >> 6);
  c4 = (word3 >> 6);
  c5 = (word2 >> 6) | ((word1 & 0x1) << 10);
  c6 = word2 & 0x3F;
  NRF_LOG_INFO("coefficients- C1: %u C2:%u C3:%u C4:%u C5:%u C6:%u", c1,c2,c3,c4,c5,c6);
}

/**
 * brief function for read pressure value
 */
void read_sensor_val() {
  unsigned int dp_val = 0;
  unsigned int dt_val = 0;
  static uint32_t level = 0;
  /* Read compensated digital pressure value */
  dp_val = read_cal_word(address_pressure);
  NRF_LOG_DEBUG("compensated pressure value: %u", dp_val);
  nrf_delay_ms(200); /* wait for conversion end */
  /* Read compensated digital temperature value*/
  dt_val = read_cal_word(address_temp);
  nrf_delay_ms(200); /* wait for conversion end */
  NRF_LOG_DEBUG("compensated temperature value: %u", dt_val);
}  

The compensate pressure and temperature value getting 65535. Where the coefficients c1-c6 values getting but not sure whether is correct or not.

I am stuck here and getting difficult to understand for debugging. Because we don't have logic analyzer or CRO to check SPI signals.

Will you please provide your suggestion in program or other solution for the same. For your reference I have attached sensor datasheet ms5540c.pdf

Looking forward your response..

Thanks.....

Vishal

Parents
  • Hi Vishal

    First of all, I think this case would be better to post publically, as there are multiple people in the community with experience with different sensors and such. So if you want, I can set it to public mode for you.

    I see that you've commented out the SS_PIN in your configuration, but I can't see where you handle it manually, please indulge me.

    Best regards,

    Simon

Reply
  • Hi Vishal

    First of all, I think this case would be better to post publically, as there are multiple people in the community with experience with different sensors and such. So if you want, I can set it to public mode for you.

    I see that you've commented out the SS_PIN in your configuration, but I can't see where you handle it manually, please indulge me.

    Best regards,

    Simon

Children
No Data
Related