The RF portion is now complete. The component on the left hand side of the image below is a Analog Devices ADC4360 synthesizer running at 870 MHz and serves as the local oscillator to jump down to our first intermediate frequency.
One leg of the output is used to drive the transmitter and the other leg is amplified and split four ways for each of the receivers. The traces for the receivers are laid out such that they’re all the exact same length and thus have the same phase shift. This is critical because our system measures the phase differences between antennas to determine the location of a neighbor and layout differences would produce large offsets in phase.
The ‘X’s there surrounding the traces form a via shield tying the surface ground plane to the internal ground planes and serve to isolate the signal from its surroundings.
A nudge here, a tweak there, and slowly but surely the layout comes together. I’ve removed a couple of things (most notably the logic analyzer connector) to make routing a bit easier and bumped up to a six layer board. Having a header to connect the logic analyzer is a nice to have feature but it was turning the traces into a ball of yarn.
I decided to give the autorouter a chance again because they’re just too many nets. I invariably have to go back and tweak a bunch but at least it give me a starting point. Here’s what it came up with:
I can see a bunch of tweaks that need to happen but it’s not a bad start.
Merry New Year!
Well I’m back after a two week winter break. It was weird taking so much time off and utterly unproductive so I’m glad to be back at work.
Today I’m working on the main board that the receiver and transmitter boards plug into. This is the board with the ARM, ADC/DAC, and local oscillators.
Here’s the receiver board:
Here’s the transmitter board:
Each board will plug into the main board via the card edge connectors.
Update: 6:15 PM
I’ve got a good start on a main board. I’ve grouped all the related components and started routing the more critical traces. It’s a start!
Alright, well I’ve written my DMA configuration macros for the ARM (I don’t like ST‘s library) and I have simple DMA transfer to the SSP working! That was pretty easy. Next trick is to get it running continuously and pinging me back with an interrupt when a buffer is complete.
Today I’m going to work on getting the final piece of the ARM firmware settled: DMA. Right now, I’m acquiring samples from the SSP manually but I won’t be able to process data if I’m wasting all my time grabbing samples so I need to pass that task to the DMA controller. The unknown at this point is how the DMA controller affects to slave select line because I need it to toggle every 8 bytes to use it as the start acquisition line on the ADC.
Well, just got back in port. The mission went well but the seas were terrible. The first night was the worst with 16 foot seas and it usually takes a day or two to acclimate so it was not fun at all. The seas calmed down a bit to about 8-12 foot seas the rest of the cruise with a lot of cold wind that is typical of December.
The AUV‘s we were using performed very well, running their full 18 hour missions without intervention. We ran them at around 1000 meters, though they’re capable of 6000; surveying about 100 square miles of sea floor.
About the only mishap we had was one of our transponders “came loose” and drifted off. With some deft detective work, Greg was able to study the currents and winds to see where it would have drifted off to. It took us about an hour to locate it and when we pulled it aboard, the end of the line that should have had an anchor on it was just a frayed rope. Looks like something down there liked the taste of rope and chewed through about 1/2 inch thick line. The AUV had an interesting time with it because one of its transponders that was supposed to be a fixed point was suddenly drifting off. It recovered well though and completed its mission.
Up early this morning for a work cruise. We should be out one week deploying AUV‘s. You can read more about the mission here.
Final exam day. They say the waiting is the hardest part.
Update: 1:32 PM
Well that was easier than I thought. I finished early so that’s a good sign. We’ll find out how I did once he posts the solutions online. Grades are due on the 15th so hopefully I’ll know my final grade a week from now. Tonight I plan on finishing the documentation for my RF scripts and placing them online in the hope they’ll be useful to someone else.
Update: 5:24 PM
Well I did some analysis on the magnitude estimation trick I talked about Monday and it looks like it may work for us. Here’s the table of errors using a fixed point version of the estimator:
Angle Error using Magnitude Estimator
Name Alpha Beta Avg Err Peak Err
Min RMS Err 31048 12860 -0.07 3.18
Min Peak Err 31470 13035 0.70 2.37
Min RMS w/ Avg=0 31065 12867 -0.03 3.14
1, Min RMS Err 32767 10592 1.12 3.94
1, Min Peak Err 32767 11009 1.38 3.36
1, 1/2 32767 16383 4.53 6.06
1, 1/4 32767 8191 -0.48 7.55
Frerking 32767 13106 2.67 4.10
1, 11/32 32767 11263 1.54 3.11
1, 3/8 32767 12287 2.18 3.65
15/16, 15/32 30719 15359 1.01 3.82
15/16, 1/2 30719 16383 1.63 3.82
31/32, 11/32 31743 11263 -0.02 4.45
31/32, 3/8 31743 12287 0.64 3.01
61/64, 3/8 31231 12287 -0.15 3.72
61/64, 13/32 31231 13311 0.51 2.82
Using the Min RMS w/ Avg=0 we could get about 0.03o error on average. I think, because our phase rolls evenly from 0 to 2π, we should achieve the average response with perhaps a little extra error from incomplete cycles. I’ll have to think a bit more about this but it looks promising.
Not much to post today. I spent most of the day tracing down little bugs here and there. There was a interesting bug where small, seemingly insignificant code changes would sometimes cause the compiler to push some registers onto the stack, changing the amount of time it would take to perform a computation because of the extra push and pops.
There is an interesting trick for estimating the magnitude of a vector here. I started evaluating it for use with int16′s because it’ll be quite a quick operation on the ARM with the multiply and accumulate instructions.
That’s about it. I’ll be out tomorrow studying for my final exam in High Frequency Amplifiers. I’ve written a bunch of python code for impedance matching so I hope to post that once I’m done studying.
It slipped my mind that using the dot product yields the absolute value of the angle difference and we care very much which vector leads of lags the other. No matter, cross product to the rescue! Because the cross product is anti-commutative, the sign of the resultant vector will tell us if the angle difference is positive of negative. We also know that the angle difference should remain constant over a reasonably short period of time so we’ll only need to compute the cross product for a single vector to determine the sign.
Update: 3:05 PM
Currently my buffer sizes and number of taps are divisible by 6. That makes optimal use of the registers in the ARM but it’s causing me a bit of a headache because 6 is not a 2n number, so I’m going to make everything divisible by 8 to ease some of the math involved.