David Summers / Mbed 2 deprecated MS5611

Dependencies:   mbed

Committer:
summers
Date:
Fri Mar 30 11:14:51 2018 +0000
Revision:
5:630aefee388b
Parent:
4:e0dbf2bdb967
Child:
6:be9a6932c869
Driver Version which works with all linear terms enabled

Who changed what in which revision?

UserRevisionLine numberNew contents of line
summers 0:9146d1e52be0 1 #include "mbed.h"
summers 1:3295382ddc81 2 #include "main.h"
summers 5:630aefee388b 3 /* This code is to drive the Measurement Specialties MS5611-01BA03
summers 5:630aefee388b 4 * pressure sensor. The sensor measures pressure via piezo electric
summers 5:630aefee388b 5 * sensor, that is measured by a 24bit delta-sigma ADC. Temperure is
summers 5:630aefee388b 6 * also measured via the same ADC.
summers 5:630aefee388b 7 *
summers 5:630aefee388b 8 * Pressure is then calculated via a first order equation in this code
summers 5:630aefee388b 9 * where both the pressure offset and linear term are also both linear
summers 5:630aefee388b 10 * dependent on temperature.
summers 5:630aefee388b 11 *
summers 5:630aefee388b 12 * Higher order terms are avaiable, but are not included in this code
summers 5:630aefee388b 13 * at present.
summers 5:630aefee388b 14 *
summers 5:630aefee388b 15 * The sensor can be accessed by either SPI or I2C, this code uses SPI.
summers 5:630aefee388b 16 *
summers 5:630aefee388b 17 * The algorithms are based on the MS5611-01BA03 data sheet, and also
summers 5:630aefee388b 18 * AN520
summers 5:630aefee388b 19 *
summers 5:630aefee388b 20 * Some details are not clear in the documents, these are:
summers 5:630aefee388b 21 * . The commands are 7bit, the 8th bit is a stop bit and must be zero
summers 5:630aefee388b 22 * . The sensor will reply to the command with 0xfe, e.g. has it own stop bit
summers 5:630aefee388b 23 * . If 0xfe is not receieved error condition has happened
summers 5:630aefee388b 24 * . This starts the command, but does not complete it
summers 5:630aefee388b 25 * . Chip Select (CS) must be pulled high (inactive) after every command
summers 5:630aefee388b 26 * . The linear cooeficients are help in the PROM
summers 5:630aefee388b 27 * . This has a CRC4 check sum
summers 5:630aefee388b 28 * . The CRC4 check sum is based on the polymonial 0x13=x^4+x+1
summers 5:630aefee388b 29 * . The CRC4 acts on the first 7 PROM values each 16bit,
summers 5:630aefee388b 30 * . The 8th PROM value, the CRC acts on the 12 MSB of the register
summers 5:630aefee388b 31 * . In addition in requires bits 9-12 to be zeroed in the check sum
summers 5:630aefee388b 32 */
summers 0:9146d1e52be0 33
summers 1:3295382ddc81 34 Serial pc(SERIAL_TX, SERIAL_RX, 115200); // tx, rx
summers 1:3295382ddc81 35 //DigitalOut led(LED_RED);
summers 1:3295382ddc81 36 //SPI spi(PTC6,PTC7,PTD1,PTC0);
summers 1:3295382ddc81 37 //SPI spi(PTC6,PTC7,PTD1); // my prefered, but mixed
summers 1:3295382ddc81 38 SPI spi(PTC6,PTC7,PTC5); // PTC5 - the LED
summers 1:3295382ddc81 39 //SPI spi(PTD2,PTD3,PTD1);
summers 1:3295382ddc81 40 DigitalOut cs(PTC0);
summers 0:9146d1e52be0 41
summers 0:9146d1e52be0 42 int main()
summers 0:9146d1e52be0 43 {
summers 5:630aefee388b 44 uint16_t PROM[8];
summers 2:b6a0d4ba24a1 45 uint32_t D1,D2;
summers 2:b6a0d4ba24a1 46 double T,P;
summers 1:3295382ddc81 47 cs.write(1); // disable all SPI
summers 2:b6a0d4ba24a1 48 pc.printf("Hello World!\r\n");
summers 1:3295382ddc81 49 MS5611_init(PROM);
summers 1:3295382ddc81 50 for (int i=0; i<8; i++) {
summers 2:b6a0d4ba24a1 51 pc.printf("Prom(%i): %i\r\n",i,PROM[i]);
summers 1:3295382ddc81 52 }
summers 3:a8c38c3fe967 53
summers 3:a8c38c3fe967 54 while (1) {
summers 2:b6a0d4ba24a1 55 // the third paramater gives over samping
summers 2:b6a0d4ba24a1 56 // 0 - 256
summers 2:b6a0d4ba24a1 57 // 1 - 512
summers 2:b6a0d4ba24a1 58 // 2 - 1024
summers 2:b6a0d4ba24a1 59 // 3 - 2048
summers 2:b6a0d4ba24a1 60 // 4 - 4096
summers 2:b6a0d4ba24a1 61 MS5611(&D1,&D2,4);
summers 5:630aefee388b 62 // pc.printf("%i\t%i\t",D1,D2);
summers 2:b6a0d4ba24a1 63
summers 2:b6a0d4ba24a1 64 MS5611_phys(D1,D2,PROM,&T,&P);
summers 2:b6a0d4ba24a1 65
summers 5:630aefee388b 66 // pc.printf("%f\t",T/100.0);
summers 5:630aefee388b 67 // pc.printf("%f\r\n",P/100.0);
summers 5:630aefee388b 68 pc.printf("%i\t%i\t%f\t%f\r\n",D1,D2,T/100,P/100.0);
summers 4:e0dbf2bdb967 69 wait(1.0);
summers 3:a8c38c3fe967 70 }
summers 1:3295382ddc81 71 }
summers 1:3295382ddc81 72
summers 5:630aefee388b 73 void MS5611_init(uint16_t *PROM)
summers 1:3295382ddc81 74 {
summers 3:a8c38c3fe967 75 uint32_t crc=0;
summers 1:3295382ddc81 76 spi.format(8,0); // 8 bit mode 0 - this is default anyway but good to code.
summers 1:3295382ddc81 77 spi.frequency(1000000); // 1MHz is this the minimum?
summers 1:3295382ddc81 78 cs.write(0); // Enable the MS5611 intercae
summers 2:b6a0d4ba24a1 79 if (spi.write(0x1E)!=0xfe) {
summers 2:b6a0d4ba24a1 80 pc.printf("Error reseting the device\r\n");
summers 2:b6a0d4ba24a1 81 }
summers 1:3295382ddc81 82 wait_ms(3); // give time for ROM to reload 2.8ms by the spec
summers 2:b6a0d4ba24a1 83 cs.write(1); // close the connection - does it finish the command?
summers 2:b6a0d4ba24a1 84 wait_us(10); // Pause after putting CSB high
summers 1:3295382ddc81 85 for (int i=0; i<8; i++) {
summers 2:b6a0d4ba24a1 86 cs.write(0); // enable the SC to start a command.
summers 2:b6a0d4ba24a1 87 if (spi.write(0xA0|(i<<1))!=0xfe) {
summers 2:b6a0d4ba24a1 88 pc.printf("Error reading prom(%i)\r\n",i);
summers 2:b6a0d4ba24a1 89 }
summers 5:630aefee388b 90 PROM[i]=((uint16_t) spi.write(0x00))<<8;
summers 5:630aefee388b 91 PROM[i]|=((uint16_t) spi.write(0x00));
summers 2:b6a0d4ba24a1 92 cs.write(1); // disable CS to finish the command
summers 3:a8c38c3fe967 93 crc|=(i==7)?(PROM[i]&0xff00):PROM[i]; // Note AN520 gives this bit mask
summers 2:b6a0d4ba24a1 94 for (int j=0; j<16; j++) {
summers 2:b6a0d4ba24a1 95 crc=crc<<1;
summers 2:b6a0d4ba24a1 96 if (crc&0x1000000) { // implimt the CRC4 algorithm 0x13 -
summers 3:a8c38c3fe967 97 crc^=0x1300000; // This won't do the last 4 bits of PROM7
summers 2:b6a0d4ba24a1 98 }
summers 2:b6a0d4ba24a1 99 }
summers 2:b6a0d4ba24a1 100 wait_us(10); // Pause probably not stricly needed, but after switching CSB high give a bit of time.
summers 1:3295382ddc81 101 }
summers 2:b6a0d4ba24a1 102 if ((crc>>20)!=(PROM[7]&0xf))
summers 2:b6a0d4ba24a1 103 pc.printf("CRC check sum: %x vs recorded %x\r\n",crc>>20,PROM[7]&0xf);
summers 1:3295382ddc81 104 }
summers 1:3295382ddc81 105
summers 2:b6a0d4ba24a1 106 void MS5611(uint32_t *D1, uint32_t *D2, int os)
summers 1:3295382ddc81 107 {
summers 1:3295382ddc81 108 // cs.write(0);
summers 1:3295382ddc81 109 spi.format(8,0);
summers 1:3295382ddc81 110 spi.frequency(1000000);
summers 2:b6a0d4ba24a1 111 cs.write(0); // Enable the MS5611 intercae
summers 2:b6a0d4ba24a1 112 if (spi.write(0x1E)!=0xfe) { // and reset the device
summers 2:b6a0d4ba24a1 113 pc.printf("Error reseting the device\r\n");
summers 2:b6a0d4ba24a1 114 }
summers 2:b6a0d4ba24a1 115 wait_ms(3); // give time for ROM to reload 2.8ms by the spec
summers 2:b6a0d4ba24a1 116 cs.write(1); // close the connection - does it finish the command?
summers 2:b6a0d4ba24a1 117 wait_us(10); // Pause after putting CSB high
summers 2:b6a0d4ba24a1 118 cs.write(0); // Enable the MS5611 intercae
summers 2:b6a0d4ba24a1 119 if (spi.write(0x40|(os<<1))!=0xfe) { // D1 please
summers 2:b6a0d4ba24a1 120 pc.printf("Error asking for D1\r\n");
summers 2:b6a0d4ba24a1 121 }
summers 2:b6a0d4ba24a1 122 cs.write(1); // Disable the MS5611 intercae
summers 2:b6a0d4ba24a1 123 wait_us(600*(1<<os)); // pause for read, longer when oversampling
summers 2:b6a0d4ba24a1 124 cs.write(0); // Enable the MS5611 intercae
summers 3:a8c38c3fe967 125 if(spi.write(0x00)!=0xfe) { // can I have the result?;
summers 3:a8c38c3fe967 126 pc.printf("Error reading D1\r\n");
summers 3:a8c38c3fe967 127 }
summers 4:e0dbf2bdb967 128 *D1=((uint32_t) spi.write(0x00))<<16;
summers 4:e0dbf2bdb967 129 *D1|=((uint32_t) spi.write(0x00))<<8;
summers 4:e0dbf2bdb967 130 *D1|=((uint32_t) spi.write(0x00));
summers 2:b6a0d4ba24a1 131 cs.write(1); // and terminate the command
summers 2:b6a0d4ba24a1 132 wait_us(10); // Pause after putting CSB high
summers 2:b6a0d4ba24a1 133 cs.write(0); // Enable the MS5611 intercae
summers 2:b6a0d4ba24a1 134 if (spi.write(0x50|(os<<1))!=0xfe) { // D2 please
summers 2:b6a0d4ba24a1 135 pc.printf("Error asking for D2\r\n");
summers 2:b6a0d4ba24a1 136 }
summers 2:b6a0d4ba24a1 137 cs.write(1); // Disable the MS5611 intercae
summers 2:b6a0d4ba24a1 138 wait_us(600*(1<<os)); // pause for read, longer when oversampling
summers 2:b6a0d4ba24a1 139 cs.write(0); // Enable the MS5611 intercae
summers 3:a8c38c3fe967 140 if(spi.write(0x00)!=0xfe) { // can I have the result?;
summers 3:a8c38c3fe967 141 pc.printf("Error reading D2\r\n");
summers 3:a8c38c3fe967 142 }
summers 4:e0dbf2bdb967 143 *D2=((uint32_t) spi.write(0x00))<<16;
summers 4:e0dbf2bdb967 144 *D2|=((uint32_t) spi.write(0x00))<<8;
summers 4:e0dbf2bdb967 145 *D2|=((uint32_t) spi.write(0x00));
summers 2:b6a0d4ba24a1 146 cs.write(1); // and terminate the command
summers 2:b6a0d4ba24a1 147 }
summers 2:b6a0d4ba24a1 148
summers 5:630aefee388b 149 void MS5611_phys(uint32_t D1,uint32_t D2,uint16_t *PROM, double *T, double *P)
summers 2:b6a0d4ba24a1 150 {
summers 3:a8c38c3fe967 151 int64_t dt=((int64_t) D2)-(((int64_t) PROM[5])<<8);
summers 2:b6a0d4ba24a1 152 *T=2000.0+((double) dt*PROM[6])/8388608.0;
summers 4:e0dbf2bdb967 153 int64_t off128=(((int64_t) PROM[2])<<23)+(((int64_t) PROM[4])*dt);
summers 4:e0dbf2bdb967 154 int64_t sens256=(((int64_t) PROM[1])<<23)+(((int64_t) PROM[3])*dt);
summers 4:e0dbf2bdb967 155 *P=(((double) D1)*((double) sens256)/4194304.0-((double) off128))/4194304.0;
summers 5:630aefee388b 156 /* this keeps the power expansion - result not diffferent from above
summers 5:630aefee388b 157 Hence the above doesn't have rouding problems.
summers 5:630aefee388b 158 Pp[0]=
summers 5:630aefee388b 159 -((double) PROM[2])*2.0+((double) PROM[4])*((double) PROM[5])/16384.0
summers 5:630aefee388b 160 +((double) D1)*( ((double) PROM[1])*32768.0
summers 5:630aefee388b 161 -((double) PROM[3])*((double) PROM[5]))/68719476736.0
summers 5:630aefee388b 162 -((double) PROM[4])*((double) D2)/4194304.0
summers 5:630aefee388b 163 +((double) D1)*((double) PROM[3])*((double) D2)/17592186044416.0;
summers 5:630aefee388b 164 * this breaks it down by terms
summers 5:630aefee388b 165 Pp[0]=-((double) PROM[2])*2.0+((double) PROM[4])*((double) PROM[5])/16384.0;
summers 5:630aefee388b 166 Pp[1]=+((double) D1)*( ((double) PROM[1])*32768.0
summers 5:630aefee388b 167 -((double) PROM[3])*((double) PROM[5]))/68719476736.0;
summers 5:630aefee388b 168 Pp[2]=-((double) PROM[4])*((double) D2)/4194304.0;
summers 5:630aefee388b 169 Pp[3]=+((double) D1)*((double) PROM[3])*((double) D2)/17592186044416.0;
summers 5:630aefee388b 170 */
summers 5:630aefee388b 171
summers 0:9146d1e52be0 172 }