I’ve been playing around with the package tracker firmware and having quite a lot of fun tweaking various bits however getting the SCP1000 pressure sensor working properly has got me stumped. The supplied code works but calls the sensor initialization routine every time it writes a block to the SD card. This seemed unnecessary so I took it out but then it doesn’t work properly! I just can’t work out why and it’s really bugging me. As far as I can see once the sensor is set up in continuous mode you should just be able to read off the data as soon as it has a new reading and it shouldn’t need regular resetting. I can’t work out whether it’s just a timing issue or something I’ve missed in the documentation. If anyone has played with this and knows more about how it is working I’d be very grateful.
Cheers
Bill
Well I now know a lot more about the SCP1000. I think the problem is that device often doesn’t behave properly for the first SPI command after a chip select (my guess is that it uses a different edge than the other devices on the package tracker or it needs a brief pause before doing anything). Anyway that means that having a do nothing sort of read such as reading the revision ID as the first command in a block means that the subsequent (useful) commands work properly. The other gotcha on this device is that you don’t have very long to read the data after the conversion has finished in continuous mode before it gives you an error. The low power mode where you have to retrigger the sensor each time is preferable when you are polling the output since it has no such time limit.
Does anyone have any advice about how to improve the performance of the micro SD card write? You get up to 40 or 50 ms when writing to the card when you can’t read any sensors because the SPI bus is being used. I can improve things a bit with some double buffering but there are obviously SPI responses that don’t like being interrupted by other SPI bus activity so I can’t just use a simple mutex like approach and interrupts.
Well I’ve found a simple way to speed up the data write and that is to always write in 512 byte blocks. You can do that by changing the buffering code a little so that all writes are cached until you have 512 bytes and then that is written as a single chunk. Then no more writes until you’ve got another 512 bytes. It means that you might lose a line or two if the power fails but performance seems much higher otherwise. I suspect it reduces the number of FAT table read/writes required. The other option is to pre-allocate a big file and write data into it rather than making the file bigger each time you write - if someone has some example code for that strategy I’d like to see it.
Other things I’ve found is that dropping the clock speed to 12 MHz really improves the battery life and my code seems quite happy. Changing clock speed is a little tricky because there is both a mutiplier and a divider to set up. Here is the code to do that (it can go at the beginning of boot up):
// first set the PLL clock speed
// with a 12MHz external clock suitable values are
// 12 MHz .set PLLCFG_Val, 0x00000060
// 24 MHz .set PLLCFG_Val, 0x00000041
// 36 MHz .set PLLCFG_Val, 0x00000042
// 48 MHz .set PLLCFG_Val, 0x00000023
// 60 MHz .set PLLCFG_Val, 0x00000024
#ifdef USE_60MHZ
PLLCFG=0x24; //Multipler and divider setup
#else
PLLCFG=0x60; //Multipler and divider setup
#endif
PLLCON=0x01; //Enable PLL
PLLFEED=0xAA; //Feed sequence
PLLFEED=0x55;
while(!(PLLSTAT & 0x0400)) ; //is locked?
PLLCON=0x03; //Connect PLL after PLL is locked
PLLFEED=0xAA; //Feed sequence
PLLFEED=0x55;