I need to drive a 32Khz square wave on pin 19 of a Renesas R8C/36C µController. The pin is non-negotiable (the circuit design is already complete.)
The software design uses a 250 µsec interrupt for simulating multi-tasking, but that's only good for 2Khz full-wave.
Do I need to create another higher-priority interrupt for driving 32 Khz, or is there some other trick that I'm not aware of?
R8C/36C Hardware Manual
R8C/36C Software Manual
I am not familiar with the RC8 and Renesas don't say much on the subject of performance, but it is a CISC processor with typically 4 cycles per instruction, so lets estimate about 4 MIPS? Some instructions are much longer with division up to 30 cycles.
So if you create a 64KHz timer and flip the output on each interrupt, you have about 63 instructions between each interrupt, you have the interrupt latency plus the code to flip the bit. If it works at all, it is likely to constitute a significant CPU load and may affect the timeliness of other operations.
Be realistic, without a redesign, the project may not be viable. You are already stressing it with the 4KHz OS tick in my opinion - the software overhead at that rate is likley to be a significant chunk of your CPU load.
[ADDED]
I previously suggested 6 instructions between interrupts - finger trouble in the calculator, I have changed that estimate to 63, and moderated my conclusion to "barely feasible".
However I looked again at the data sheet, interrupt latency is variable because the instruction execution is variable, and the current instruction must complete before the interrupt is serviced, the worst case is when the DIVX instruction is executing, when it takes up-to 51 cycles before the first instruction of the interrupt routine. That's 2.55us, when you need the interrupt to trigger every 15.625us, the variable latency will impose significant jitter and constitutes 6 to 16 % of your total CPU time without even considering that used by the ISR itself.. Plus if the interrupt itself is pre-empted, or a higher priority interrupt is running when this one becomes due, further jitter will be imposed.
Whether it works will depend on the accuracy and jitter constraints of the 32KHz, and whatever else your code needs to get done.
As many people have pointed out, this design doesn't seem to be very good from a hardware standpoint if the 32khz clock is meant to be generated with a gpio.
However, I don't know How desperate is your situation, nor do I know the volume involved. But if it is a prototype or very short series, and pin 20 is free, you can short-circuit pins 19 and 20, setup pin 19 as an input and 20 as output. Since pin 20 can be used as output from timer rd, you could set up that timer to output the 32khz without using any interrupts.
I am not a renesas micro expert, but I'm talking from what I've seen in the data sheet you attached and previous experience with other mcu's.
I hope this helps.
Looking at the datasheet for that chip:
It looks like your only real option is to use the pin as a generic output port.
the only usable output mode seems to be the generic output port.
If you can't strap pin 19 to another pin that has the hardware to generate 32KHz and just make pin 19 an input? Not a proud moment but it was easy on a DIL package.
Could you call an interrupt every 15.6us and toggle pin19 then on the sixteenth interrupt do the multi-tasking stuff but that is likely to be wasteful. With an interrupt rate of 32Khz, setting pin19 then eighth of the time doing the multi-tasking decisions and the other seven times wait till a point you can reset pin19 and do some background code for less than half the CPU time
Related
I am trying to learn how to debug an MCU non-intrusively using SWD & openOCD.
while (1)
{
my_count++;
HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
HAL_Delay(750);
}
The code running on my MCU has a free running counter "my_count" . I want to sample/trace the data stored in the address holding "my_count" in real time :
I was doing it this way:
while(1){// generic algorithm no specific language
mdw 0x00000000200000ac; //openOCD command to read from an address
}
0x200000ac is the address of the variable my_count from the .map file.
But, this method is very slow and experiences data drops at high frequencies.
Is there any other way to trace the data at high frequencies without experiencing data drops?
I made some napkin math, and I have an idea that may work.
As per Reference Manual, page 948, the max baud rate for UART of STM32F334 is 9Mbit/s.
If we want to send memory at the specific address, it will be 32 bits. 1 bit takes 1/9Mbps or 1.111*10^(-7)s, multiply that by 32 bits, that makes it 3.555 microseconds. Obviously, as I said, it's purely napkin math. There are start and stop bits involved. But we have a lot of wiggle room. You can easily fit 64 bits into transmission too.
Now, I've checked with the internet, it seems the ST-Link based on STM32F103 can have max baud rate of 4.5Mbps. A bummer, but we simply need to double our timings. 3.55*2 = 7.1us for 32-bit and 14.2us for 64-bit transmission. Even given there is some start and stop bit overhead, we still seem to fit into our 25us time budget.
So the suggestion is the following:
You have a timer set to 25us period that fires an interrupt, that activates DMA UART transmission. That way your MCU actually has very little overhead since DMA will autonomously handle the transmission, while your MCU can do whatever it wants in the meantime. Entering and exiting the timer ISR will be in fact the greatest part of the overhead caused by this, since in the ISR you will literally flip a pair of bits to tell DMA to send stuff over UART # 4.5Mbps.
I am evaluating the ATtiny806 running at 20MHz to build a cycle-accurate Intel 4004 microprocessor emulator. (I know it will be a bit too slow, but AVRs have a huge community.)
I need to synchronize to the external, two-phase non-overlapping clocks. These are not fast clocks (the original 4004 ran at 750kHz)
but if I spin-wait for every clock edge, I risk wasting most of my time budget.
The TinyAVR 0-series has a very nice pin-change interrupt facility that can be configured to trigger only on rising edges.
But, an interrupt routine round-trip is 8 cycles (3 in, 5 out).
My question is:
Can I leverage the pin-change sensing mechanism while never visiting an ISR?
(Other processor families let you poll for interruptible conditions without enabling interrupts from that peripheral). Can polling be done with a tight skip-on-bit/jump-back loop, followed by a set-bit instruction?
Straightforward way
You can always just poll on the level of the GPIO pin using the single cycle skip if bit set/clear instruction on the appropriate PORT register and bit.
But as you mention, polling does burn cycles so I'm not sure exactly what you want here - either a poll (that burns cycles but has low latency) or an interrupt (that has higher latency but allows processing to continue until the condition is true).
Note that if things get really tight and you are looking for, say, power savings by sleeping between clock signal transitions then you can do tricks like having an ISR that nevers returns (saving the IRET cycles) but that requires some careful coding probably with something like a state machine.
INTFLAG way
Alternately, if you want to use the internal pin state machine logic and you can live without interrupts, then you can use the INTFLAGS flags to check for the pin change configured in the ISC bits of the PINxCTRL register. As long as global interrupts are not enabled in SREG then you can spin poll on the appropriate INTFLAG bit to check/wait for the desired condition, and then write a 1 to that bit to clear the flag.
Note that if you want to make this fast, you will probably want to map the appropriate PORT to a VPORT since the VPORT registers are in I/O Memory. This lets you use SBIS to test the INTFLAG bit a single cycle and SBI to clear the bit in a single cycle (these instructions only work on IO memory and the normal PORT registers are not in IO Memory).
Finally one more complication, if you need to leave the interrupts on when doing this, it is probably possible by hacking the interrupt priority registers. You'd set the pin change to be on level 0, and then make sure the interrupts you care about are level 1 or higher, and then trick the interrupt controller into thinking that there is already a level 0 running so these interrupts do not actually fire. There are also other restrictions to this strategy so avoid it if at all possible.
Programmable logic way
If you want to get really esoteric, it is likely possible that you could route the input value of a pin to a configurable custom logic LUT in the chip and then route the output of that module to a bit that you test using a 1-cycle bit test (maybe an unused IO Pin). To do this, you'd feedback the output of the LUT back into one of its inputs and then use the LUT to create a strobe on the edge you are looking for. This is very complex, and also since the strobe has no acknowledgement that if the signal changes when you are not looking for it (in a spin check) then it will be lost and you will have to wait for the next edge (probably fatal in your application).
I have interfaced 8051 with an image sensor,the frame valid is connected to INT1,image sensor is capable of giving 60frames per second.that is 60 times frame valid interrupt per second,is 8051 is capable of handling 60 interrupts per second?
correct me if i am wrong.
regards,
geetha.
8051 based MCUs come in many shapes and forms. Most of modern ones have a much more efficient execution performance. The original ran at 12 cycles per instruction as far as I remember(don’t recall the isr to first instruction though.). That being said even the original ones are capable of 60 iterrupts per second. The real question though is how much processing you need to actually transfer each frame and how this will be implemented in your MCU(dma etc).
I am using a 16F877A pic with 20MHz crystal and a change interruption on portB, pin 6-7 connected to an encoder. I'm using the encoder to calculate the velocity of a wheel and I have a doubt about the maximum ppr that I can use to avoid the program to stop or freeze? Thanks
I watched a student have this problem in a lab next to me.
Without interrupt shadow registers, you'll find the maximum quadrature decoding rate probably slower than you want. IIRC under 100000pps
You can measure it easily by running your wheel backwards and forwards with a motor and going faster until the counts for forward and reverse passes no longer line up.
Microchip recommend using the PIC16F18877 in new designs, which has automatic register shadowing on interrupt. All the 18 series PIC have this feature too and it raises the rate significantly to IIRC over 200000pps.
I'm sorry I can't give hard numbers, the exact figures are at an earlier employer.
In UART, the default state is high it will start the process when it receives start bit i.e, state change of high to low.
My question is In some worst scenario any spike, noise or interrupt may
change the default sate from high to lowwhich is enough for the UART to detect it as a start bit, So that it should not start
processing the next bits. I know UART internally handles these
scenarios and avoids the processing.
Can anyone explain me how UART behaves for this?
If the signal drop is short enough, the UART might not detect it as a start bit. For example, a UART might oversample the line level at 16x the bit rate and when it detects a falling edge in the RX line will then look for a certain number of 0 samples in the next 16 to detect the start bit. If it doesn't see enough 0 samples, it won't consider it a start bit (and might set some condition bit that indicates a noisy/dirty line).
But if the UART sees the line drop for long enough to consider it a start bit, then the UART will start processing as if a character is being received. If the signal is "junk" this might result in:
a spurious character,
a framing error,
a parity error (if the UART is configured to check parity),
a 'break' signal (if the line stays in the low state long enough)
The datasheet for the UART device should give details on how bits are sampled & detected.
UART Receiver samples the Rx line 16 times(most uC's) before confirming the value of each bit. For example, if the baud is 9600,each bit time will be 104uS. Now to correctly detect the value of each bit(i.e whether its high or low), the UART receiver samples the bus every 104uS/16 seconds. The majority voting of these samples is then used to decide the value of a bit. The start bit is used to indicate to the receiver that data bits are about to be received. Its mandatory that the start bit be low.By employing such a sampling scheme, the receiver ensures that the effects of noise is eliminated.
UART is an old, increasingly obsolete 1970s technology, so the error handling is poor. On the most fundamental level, the UART will trigger any read by a falling edge, which is the start bit.
So if there is noise which gets interpreted as the falling edge of the start bit, the UART will then sample 8 data bits, with sample times according to its pre-configured baudrate (usually it samples 16 times faster than the set baudrate). It will sample regardless of any edges present. After that, it will clock in a potential parity bit, and then 1 or 2 stop bits.
At the point where the stop bit is read, the UART checks to ensure that the parity bit (if present) is correct, if not, you will get parity errors. And then it checks the stop bit, which must be high, otherwise you get a framing error.
These kind of error checks are roughly of a fifty/fifty quality. Double-bit errors or larger will cause lots of problems. "Parity" in particular, is a poor method of detecting errors. Professionals stopped using it around 30 years ago. Overall, the error detection chance by hardware is very poor, by design.
This is why all UART-based protocols must have lots of checksums, sync bytes and other such overhead in order to work. UART is very vulnerable to EMI, to the point where you cannot reliably use UART buses outside a circuit board, without using differential signals (like RS-422).