If a 16 bit timer counter registers an event at 0xB123 and a subsequent event at 0x23B1 how many clock ticks have occurred between these values?
2^16 = 65536
0xB123 in decimal is 45347
0x23B1 in decimal is 9137
Not sure if I am correct. But do you just subtract 9137 from 45347 which gives the answer 36210?
Lol, microcomputers 204 tutorial?
Since the question say a "subsequent event at 0x23B1"
Not sure if im correct either, but doesn't the counter overflows at 65536? So the max address should be 65535, hence 65535-45347=20188 (before it reaches overflow to start at 0 again.) then plus 9137 (20188+9137=29325?)
What do you think?
Related
For one MCU I have written some assembly routines performing RX and TX of a proprietary protocol (UART-based) in a bit-bang fashion. How can I test them?
TX might be tested by sending data, and at the same time, with the help of a logic analyzer, checking that all the sampled timings are correct (manually or with some scripts).
RX on the other hand is more difficult. On one hand I can check if I'm receiving what someone else is sending, but on the other hand how do I know that the RX sampling is happening correctly (timing-wise)?
For example, my RX routine may return the correct data by sampling at the edge of the "bit window" instead of the middle.
I thought about toggling a "debug pin" to indicate when the sampling is actually happening, but this introduces delays in the sampling procedure, hence I wouldn't be testing my original routine.
Some things worth clarifying after reading comments:
I know that hardware UART is better (it depends, though), but I can't use it. This is not a matter of "have you tried this ...?";
I know how to do the bit banging (I have already written the assembly routines);
I can't connect TX to RX because I'm only using 1 wire (the communication is half-duplex);
I'm asking how to test the RX sampling timings, not how to implement UART.
I thought about toggling a "debug pin" to indicate when the sampling
is actually happening, but this introduces delays in the sampling
procedure, hence I wouldn't be testing my original routine.
Test with the instrumentation code, and then leave the instrumentation - or near-equivalent code that doesn't actually twiddle hardware - in place.
You'll need something to send data to the MCU, perhaps a second MCU. I've worked on similar code for both 6502 and Z80 for old 8 bit Atari peripherals. These are half duplex protocols, so whenever the device is idle, it's polling for a start bit. After detecting a start bit, it delays 1.5 bit times, then receives 8 bits, with 1 bit time between bits. Both receiving and sending of data routines are coded to get exact cycle counts for timing. These were old devices, and even the fastest bit rate was relatively slow at 19 microseconds per bit ~= 52600 baud.
The question has been updated. If the input and output instructions take the exact same time to run (cycle count), you could modify the receive code to transmit data to verify the bit time, and confirm exactly how fast the processor is running.
For the timing regarding sensing the start bit and doing a 1.5 bit time wait, you'd have to calculate the minimum and maximum number of cycles to sense the start bit. The maximum cycle count would be an input instruction that just misses the trailing edge of the start bit, the test instruction, and the loop back to the input, followed by another test and then a fall through the loop to continue the receive. The minimum cycle count would be an input that just barely catches the leading edge of the start bit, does a test, then falls through the loop. Then the remainder of the receive code needs to sample as close as possible to the middle of the data bit periods.
Here is example of code for a 4mhz Z80 that receives data at 19 microseconds == 76 cycles per data bit. The comments include the cycle count for each instruction. The ideal wait time for start bit to 1st data bit is 114 cycles. The min,max cycle time for the start bit loop is 20,50 cycles. An additional delay plus the input of the first data bit of 79 cycles is used so min,max cycle time to sense start to receive 1st data bit is 99,129 cycles, within the min,max bounds of 76,152 cycles. The remaining data bits are read at exactly 76 cycles per bit.
LD E,0 ;SET UP
; ; START BIT TO DATA BIT=114
NRXF0: LD A,(FBS) ;(13) WAIT FOR START BIT
AND FBSRXD ;(7)
JP NZ,NRXF0 ;(10)
; ; NOTE: 20 MIN, 50 MAX, 35 AVG
EX (SP),HL ;(19) DELAY
EX (SP),HL ;(19)
LD A,(HL) ;(7)
NRXF1: LD A,(HL) ;(7)
LD A,(HL) ;(7)
LD D,8 ;(7) 8 BITS PER BYTE
; ; 76 CYCLES PER DATA BIT
NRXF2: LD A,(FBS) ;(13) GET DATA BIT
AND FBSRXD ;(7)
ADD A,0FFH ;(7)
RR C ;(8)
PUSH BC ;(11) DELAY
POP BC ;(10)
NOP ;(4)
DEC D ;(4) LP TIL BYTE DONE
JR NZ,NRXF2 ;(12/7)
RET NZ ;(5) DELAY
NRXF4: LD A,(FBS) ;(13) WAIT FOR NEXT START BIT
AND FBSRXD ;(7)
JP NZ,NRXF4 ;(10)
; ; START BIT TO DATA BIT=114
LD (HL),C ;(7) STORE BYTE
LD A,C ;(4) DO CKSUM
ADD A,E ;(4)
ADC A,0 ;(7)
LD E,A ;(4)
INC HL ;(6) ADV ADR
DJNZ NRXF1 ;(13/8) LP IF MORE BYTES
Is this the 1 billionth ugly/hamming number?
62565096724471903888424537973014890491686968126921250076541212862080934425144389
76692222667734743108165348546009548371249535465997230641841310549077830079108427
08520497989078343041081429889246063472775181069303596625038985214292236784430583
66046734494015674435358781857279355148950650629382822451696203426871312216858487
7816068576714140173718
Does anyone have code to share that can verify this? Thanks!
This SO answer shows a code capable of calculating it.
The test entry on ideone.com takes 1.1 0.05 sec for 109 (2016-08-18: main speedup due to usage of Int instead of the default Integer where possible, even on 32-bit; additional 20% thanks to the tweak suggested by #GordonBGood, bringing band size complexity down to O(n1/3)).
It gives the answer as ((1334,335,404),"6.21607575556559E+843"), i.e.
21334 * 3335 * 5404 ≈ 6.21607575556559 * 10843.
(coincidentally, only two last digits in the fractional number above are incorrect).
This also means, of course, that there are 404 zeroes at the end of this number, and that it has 844 digits in total. So no, the number you show isn't it.
Exact answer:
6216075755565244861630816332872072003947056519089652706591632409642337022002753141824417540777256732780370172616615291935540418620025524916729500086831454711313694078635504004160312872951788703647948382456091072701600790562071797590306654765882256990391763887850141154482249915927439184562828227449023750262318234797192076792208033475638322151983772515798004125909334741121595323950448656375104457026997424772966917441779406172736975588556800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
I am reading sensor output as square wave(0-5 volt) via oscilloscope. Now I want to measure frequency of one period with Beaglebone. So I should measure the time between two rising edges. However, I don't have any experience with working Beaglebone. Can you give some advices or sample codes about measuring time between rising edges?
How deterministic do you need this to be? If you can tolerate some inaccuracy, you can probably do it on the main Linux OS; if you want to be fancy pants, this seems like a potential use case for the BBB's PRU's (which I unfortunately haven't used so take this with substantial amounts of salt). I would expect you'd be able to write PRU code that just sits with an infinite outerloop and then inside that loop, start looping until it sees the pin shows 0, then starts looping until the pin shows 1 (this is the first rising edge), then starts counting until either the pin shows 0 again (this would then be the falling edge) or another loop to the next rising edge... either way, you could take the counter value and you should be able to directly convert that into time (the PRU is states as having fixed frequency for each instruction, and is a 200Mhz (50ns/instruction). Assuming your loop is something like
#starting with pin low
inner loop 1:
registerX = loadPin
increment counter
jump if zero registerX to inner loop 1
# pin is now high
inner loop 2:
registerX = loadPin
increment counter
jump if one registerX to inner loop 2
# pin is now low again
That should take 3 instructions per counter increment, so you can get the time as 3 * counter * 50 ns.
As suggested by Foon in his answer, the PRUs are a good fit for this task (although depending on your requirements it may be fine to use the ARM processor and standard GPIO). Please note that (as far as I know) both the regular GPIOs and the PRU inputs are based on 3.3V logic, and connecting a 5V signal might fry your board! You will need an additional component or circuit to convert from 5V to 3.3V.
I've written a basic example that measures timing between rising edges on the header pin P8.15 for my own purpose of measuring an engine's rpm. If you decide to use it, you should check the timing results against a known reference. It's about right but I haven't checked it carefully at all. It is implemented using PRU assembly and uses the pypruss python module to simplify interfacing.
I believe this question is sort of open ended, but I am seriously struggling. I keep getting an over flow.
I have two longs. The first is set to 16552800. I can add 32760 to it no problem. However I get an overflow error when I add 32820 to is.
Any ideas?!?!?!
Thanks!!!
A long in Visual Basic 6 is 32 bits and has a range from 2,147,483,648 to 2,147,483,647. You are nowhere near this limit. In VB.NET it is 64 bit.
It seems that you get an error when you add a number greater than or equal to 215 = 32768. Could you try 32767 and 32768 and see if that is the point at which the error starts occurring?
Are you sure that the overflow is coming from the addition? I suspect that you are trying to assign 32820 to a signed integer (range -32768 to +32767), and it's this assignment that gives the overflow, not the addition.
Noted that the parameter of taskDelay is of type int, which means the number could be negative. Just wondering how the function is going to react when passing a negative number.
Most functions would validate the input, and just return early/return 0/set the parameter in question to a default value.
I presume there's no critical need to do this in production, and you probably have some code lying around that you could test with.... why not give it a go?
The documentation doesn't address it, and the only error codes they do define doesn't cover this case. The most correct answer therefore is that the results are undefined.
See the VxWorks / Tornado II FAQ for this gem, however:
taskDelay(-1) shows another bug in
the vxWorks timer/tick code. It has
the (side) effect of setting vxTicks
to zero. This corrupts the localtime
(and probably other things). In fact
taskDelay(x) will have the same effect
if vxTicks + x >= 0x100000000. If the
system clock rate is 100Hz this
happens after about 500 days (because
vxTicks wraps). At faster clock rates
it will happen sooner. Anyone trying
for several years uptime?
Oh there is an undocumented upper
limit on the clock rate. At rates
above 4294 select() will fail to
convert its 'usec' time into the
correct number of ticks. (From: David
Laight, dsl#tadpole.co.uk)
Assuming this bug is old, I would hope that it would either return an error or do the same thing as taskDelay(0), which puts your task at the end of the ready queue.
The task delay tick will be VIRTUALLY 10,9,..,1,0 for taskDelay(10).
The task delay tick will be VIRTUALLY -10,-11,...,-2147483648,2147483647,...,1,0 for taskDelay(-10).