Month: April 2015
http://www.openrtls.com/shop
Have a bunch of interesting products.
A NEYO anchor to go into a wall socket is 85 Euros.
A tag with an IMU is only 27 Euros and contains an
DW1000 UWB transceiver
Cortex M4F, 84MHz, 512kB flash, 80kB RAM
This one looks particularly interesting.
IMU only means accelerometer!
2ppm clock seems good.
- M=MircoController onboard,
- I=Inertia Measurement Unit (optional)
- P=Pressure sensor (optional)
- H=Humidity, Temperature sensor (optional)
- Q=Qi wireless charger circuit without external coil (optional)
DW1000 UWB transceiver
EPC 2 active RFID
Cortex M3, 128kB flash, 64kB RAM
Accelerometer LIS3DSH
2 DAC (1Mbit 10 bit)
1 ADC (400ksps)
1 GPIO
1 I2C, 1 uart
Integrated UWB antenna
Li-Po Battery connector (BM03B)
micro-USB port
30nA sleep current1 (RAM retention/2ppm clock)2
dimensions: 27 x 47 mm
1 = optional
2 = standard sleep current approx 200nA, standby current with IMU active approx 5uA
mA | W @ 3.3V | duration us | uW seconds |
3 | 0.0099 | 2000 | 19.8 |
12 | 0.0396 | 7 | 0.2772 |
15 | 0.0495 | 10 | 0.495 |
65 | 0.2145 | 135 | 28.9575 |
48 | 0.1584 | 16 | 2.5344 |
uJ | 52.0641 |
I got a simple loop-back SPI program to work. I connected MISO to MISO with a jumper and then checked to see that the characters I sent out on MOSI matched the ones I got back on MISO.
It appears to be important to to set the slave select high before configuring it as an output or it creates glitches.
MISO is configured with no pullup.
The Nordic has two SPI channels which can be pointed at any set of GPIOs.
p_nrf_spi->PSELSCK = p_spi_master_config->SPI_Pin_SCK;
p_nrf_spi->PSELMOSI = p_spi_master_config->SPI_Pin_MOSI;
p_nrf_spi->PSELMISO = p_spi_master_config->SPI_Pin_MISO;
I initialised the code to run with:
POL=ActiveHigh;
PHA=Leading;
FREQ=125Kb;
BITORDER=MsbFirst
This is right for BusPirate SPI_Sniffer, but the bits are back-to-front on the scope
My program sets up to catch interrupts, and the interrupt handler simply sets a flag when the IO has finished. The main loop
Here’s some output.
0: Hello SPI! => Hello SPI!
1: Hello SPI! => Hello SPI!
2: Hello SPI! => Hello SPI!
3: Hello SPI! => Hello SPI!
4: Hello SPI! => Hello SPI!
5: Hello SPI! => Hello SPI!
6: Hello SPI! => Hello SPI!
7: Hello SPI! => Hello SPI!
8: Hello SPI! => Hello SPI!
9: Hello SPI! => Hel
If the jumper is not in place then the SPI hardware clocks character 255 into the receive buffer.
0: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
1: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
2: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
3: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
4: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
5: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
6: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
7: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
8: Hello SPI! => ÿÿÿÿÿÿÿÿÿÿ
9: Hello SPI! => ÿÿÿÿÿÿÿÿ
Using the Bus Pirate and SPI_Sniffer
The startup bat file contain this:
SPIsniffer -d COM4 -r 0 -s 125000
pause
The data is interpreted as follows:
BP_record ::= CS_low ‘[‘ { DataPair } CS_hi ‘]’
CS_low ::= 0x5B
CS_hi ::= 0x5D
DataPair ::= MOSI ‘(‘ MISO ‘)’
MOSI ::= .dec .hex
MISO ::= .dec .hex
SPI working on TS06.2
I needed to learn how to do interrupt handling on the Nordic. The simplest thing seemed to be to setup the RTC to generate regular interrupts. It was a useful process because I learned quite a bit about the hardware in the process.
(My test program is called: RTC_C_nRF51822)
There are two clocks: a low-frequency clock, and a high-frequency clock. The LFCLK runs at 32KHz. It generates the basic system tick which is a sub-multiple of the 32768Hz. The PRESCALAR which essentially divides the clock is only 12 bits wide, so the slowest clock-tick is 32768/(0xFFF + 1) = 8Hz.
#define RTC_FREQUENCY_HZ (10UL)
#define COUNTER_PRESCALER ((LFCLK_FREQUENCY / RTC_FREQUENCY_HZ) – 1)
The name of the interrupt routine is hard-wired : void RTC0_IRQHandler() It gets called at RTC_FREQUENCY_HZ.
There is another times called the “compare” timer that can be set to cause an timer interrupt at any multiple of RTC_FREQUENCY_HZ.
Whereas the basic tick interrupt repeats automatically, the compare timer is a one-shot and has to be restarted.
So the basic process involves setting up the timer frequencies, and the interrupt events and masks, and then going to sleep until a tick, or “compare” interrupt occurs.
The sleep loop is a little subtle. It is important to make sure that all pending interrupts are processed before sleeping, for which this opaque/confusing sequence is recommended.
// Enter System ON sleep mode __WFE(); // Make sure any pending events are cleared __SEV(); __WFE();
Incidentally I learned that the basic printf procedure is interrupts driven, so it get’s a bit confusing.
So here’s an example that toggles one LED every ten system ticks, and the other at 3Hz.
I noticed that in sleep mode the board is still consuming about 1.5mA with the LEDs off.