Invert an RTC GPIO on ESP32 - esp32

I am developing a battery powered device that will wake when a sensor switch goes high. Now I also need the device to go back to hibernate mode and wait for the sensor switch to go low. I am using the ESP-IDF. I have configured the ext_1 wakeup pin(s). The device wakes as expected.
The problem is that the pin is set to wake on going high. When the device goes back to sleep, the pin will still be high and I want to detect when it goes low. My first thought is to invert the pin - so low reads as high. I don't see a way to do that in the ESP-IDF.
I do not want to use the ULP for this as it draws too much current in sleep.

If you are using a single pin to wake up, just change the level to ESP_EXT1_WAKEUP_ALL_LOW before going back to sleep. If you need it to wake when any of multiple pins goes low, and/or need it to sleep with multiple wake pins in mixed states, ULP is the only option I came up with. The problem isn't just with getting it to wake on any low, it won't go back to sleep when any are high -- by definition with the only other ext1 level choice of ESP_EXT1_WAKEUP_ANY_HIGH.

According to the gpio_wakeup_enable() documentation you can request wakeup from light sleep on either low or high GPIO value by specifying GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL as the value of parameter intr_type.

Related

Raspberry Pi GPIO: Hardware Timing (e.g. Interrupts)

I've been trying to find any way to do hardware timing control on the Raspberry Pi but have been unable to find anything.
I need to be able to generate stable timing over the GPIO pins on the RasPi (e.g. to communicate with an FPGA at high-bandwidths) and need upwards of a 10-100MHz clock on the GPIO pins.
Everything I've seen so far uses delays to achieve timing, which is a really bad way of doing timing. For one, you don't get timing guarantees and get clock jitter; on top of this, I can't get a 10-100 MHz clock uwith usleep.
How do I get an interrupt or some other hardware-controlled timing for GPIO?

Wake-up from Deep Power-Down mode causes a reset in LPC1768

I need to minimize the current consumption in my board which uses a LPC1768. Now I don't have any problem with going into Deep Sleep or Power-Down modes and waking up from those modes. I have configured the RTC to generate an interrupt after some predefined time which does wake up the MCU correctly and works just fine.
My problem occurs when I want to go into Deep Power-Down mode which is precisely what I need (its consumes much less power). But after generating the RTC Interrupt the MCU goes into a reset state and starts the execution from the beginning as if someone pushes the reset button!
Now why is that? I read from the documents (like this example: AN10915: Using the LPC1700 power modes) that these three routines are pretty much the same.
I don't understand. There should be no problem according to the example.
I really need to do this otherwise we loose the battery sooner than it is supposed to.
UM10360.pdf, chapter 4.8.4 says: "In Deep Power-down mode, power is shut off to the entire chip" [...]
That means all data that is not in the RTC backup registers is lost, and the chip will thus restart with a reset.

500Hz or higher serial port data recording

Hello I'm trying to read some data from the serial port and record it in the hard drive. I'm using visual C++ express, and made an application using the windows form.
The program basically sends a byte ("s") every t seconds, this trigger the device connected to the serial port to send back 3 bytes. The baud rate now is on 38400bps. The time t is controlled by the timer class of visual c++.
The problem I have is that if I set the ticking time of the timer to 1ms, the data is not recorded every 1ms, but around every 15ms. I've read that maybe the resolution of the timer is set to 15ms, but not sure about it. Anyhow, how can I make the timer event to trigger every 1ms, instead of every 15ms? or is there another way to read the serial port data faster? I'm looking for 500Hz or higher.
The device connected to the serial port is a 32bit microcontroller, which I have control over the program as well so I can easily change it, but just can't figure out another way to make this transmission.
Thanks for any help!
Windows is not a real-time OS, and regardless of what period your timer is set to there are no guarantees that it will be consistently maintained. Moreover the OS clock resolution is dependent on the hardware vendor's HAL implementation and varies from system to system. Multi-media timers have higher resolution, but the real-time guarantees are still not there.
Apart from that, you need to do a little arithmetic on the timing you are trying to achieve. At 38400,N,8,1, you can only transfer at most 3.84 characters in 1ms, so your timing is tight in any case since you are pinging with one character and expecting three characters to be returned. You can certainly go no faster without increasing the bit rate.
A better solution would be to have the PC host send the required reporting period to the embedded target once then have the embedded target perform its own timing so that it autonomously emits data every period until the PC requests that it stop or sends a different period. Your embedded system is far more capable of maintaining hard-real-time constraints.
Alternatively you could simply have your device perform its sample and transmit the three characters with the timing entirely determined by the transmission time of the three characters, and stream the data constantly. This will give you a sample period of 781.25us (1280Hz) without any triggering from the PC and it will be truly periodic and jitter free. If you want a faster sample rate, simply increase the bit rate.
Windows Forms timer resolution is about 15-20 ms. You can try multimedia timer, see timeSetEvent function.
http://msdn.microsoft.com/en-us/library/windows/desktop/dd757634%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd743609%28v=vs.85%29.aspx
Timer precision is set by uResolution parameter (0 - maximal possible precision). In any case, you cannot get timer callback every ms - Windows is not real-time system.

gps time synchronization accuracy

i have a GPS NTP Time server synchronizing my PC.
HOW am i able to compare 1PPS of the GPS receiver with clock pulse of my PC to see how much accurately it is synced to the GPS time?(with an oscilloscope maybe!)
I've designed experiments of this sort before. In my case, I wrote a device driver that would -- inside the kernel -- watch the PC's clock in a tight loop waiting for it to roll over to a new second. As soon as it did, I would raise one of the pins high on the PC parallel port. Then I attached that pin of the parallel port and the PPS signal output of the GPS receiver to an oscilloscope and had it measure the time difference between the two pulses.

How to generate ~100kHz clock signal in Liunx kernel module with bit-banging?

I'm trying to generate clock signal on GPIO pin (ARM platform, mach-davinci, kernel 2.6.27) which will have something arroung 100kHz. Using tasklet with high priority to do that. Theory is simple, set gpio high, udelay for 5us, set gpio low, wait another 5us, but strange problems appear. First of all, can't get this 5us of dalay, but it's fine, looks like hw performance problem, so i moved to period = 40us (gives ~25kHz). Second problem is worst. Once per ~10ms udelay waits 3x longer than usual. I'm thinking that it's hearbeat taking this time, but this is is unacceptable from protocol (which will be implemented on top of this) point of view. Is there any way to temporary disable heartbeat procedure, lets say, for 500ms ? Or maybe I'm doing it wrong from the beginning? Any comments?
You cannot use tasklet for this kind of job. Tasklets can be preempted by interrupts. In some case your tasklet can be even executed in the process context!
If you absolutely have to do it this way, use an interrupt handler - get in, disable interrupts, do whatever you have to do and get out as fast as you can.
Generating the clock asynchronously in software is not the right thing to do. I can think of two alternatives that will work better:
Your processor may have a built-in clock generator peripheral that isn't already being used by the kernel or another driver. When you set one of these up, you tell it how fast to run its clock, and it just starts running out the pulses.
Get your processor's datasheet and study it.
You might not find a peripheral called a "clock" per se, but might find something similar that you can press into service, like a PWM peripheral.
The other device you are talking to may not actually require a regular clock. Some chips that need a "clock" line merely need a line that goes high when there is a bit to read, which then goes low while the data line(s) are changing. If this is the case, the 100 kHz thing you're reading isn't a hard requirement for a clock of exactly that frequency, it is just an upper limit on how fast the clock line (and thus the data line(s)) are allowed to transition.
With a CPU so much faster than the clock, you want to split this into two halves:
The "top half" sets the data line(s) state correctly, then brings the clock line up. Then it schedules the bottom half to run 5 μs later, using an interrupt or kernel timer.
In the "bottom half", called by the interrupt or timer, bring the clock line back down, then schedule the top half to run again 5 μs later.
Unless you can run your timer tasklet at higher priority than the kernel timer, you will always be susceptible to this kind of jitter. You do really have to do this by bit-ganging? It would be far easier to use a hardware timer or PWM generator. Configure the timer to run at your desired rate, set the pin to output, and you're done.
If you need software control on each bit period, you can try and work around the other tasks by setting your tasklet to run at a short period, say three-fourths of your 40 us delay. In the tasklet, disable interrupts and poll the clock until you get to the correct 40 us timeslot, set the I/O state, re-enable interrupts, and exit. But this effectively types up 25 % of your system in watching a clock.

Resources