Hello folks.
I have an application on which I would like to ask your help. I had been using the SPI interface on a 'legacy' OTP HC05 processor to communicate (one way outgoing, only) to a serial input Phase Lock Loop synthesizer controller - specifically, the MC-154159 chip. With the HC05, it worked like a charm, every time, day in and day out. It just worked and worked. Unfortunately, these chips are no longer available......... and smaller is newer and better..............
Recently, I decided to recussitate this project with a new flash based chip in a DIP mountings. I don't think that namy of my hobbyist clients would be interested in a surface mount device and I'm loathe to work on them.. So, I decided to use the MC68HC908JL16 (28 pin) DIP. By some judicious reuse of some of the pins for several functions, I have it working (almost).
I'm trying to emulate the operation of the SPI using 3 output ports. I thought it would be relatively easy, but I was wrong. I hate to tell you how much time I've spent on it. I have a nice dual input scope and have tried to 'software engineer' the timing on the clock and data ports to get the necessary concurrence for data entru into the PLL (on the rising edge of the 'clock' pulse). I can't get it to work so far.
Has anyone out there tried to do something similar??
I checked over the Freescale chips to see if there was a DIP device with at least 23 I/O Ports (including an SPI interface) that would be available for the near term but couldn't find anything.
Any thoughts or suggestions would be most appreciated.
Thanks,
Joe Burch
Solved! Go to Solution.
Hi Mac (and others).
I took a last look at the radio this morning. In scoping out the pulses one more time, I took a more careful look at the clock pulse where it entered the radio. It was peaking around 4 volts (1 state) and at around .9 (0 state). Yet, at the JL16 pin itself, the levels were proper.
The M/P is interfaced with the radio's PLL circuitry through 3 leads, Enable, Clock and Data. To get the proper polarity, signal inverting transistors (2N3904's) are needed for the Enable and Data leads, each of which is fed from the port with a 1K current limiting resistor. Since the Clock lead is inverted twice by gates within the radio, it requires no inversion at the M/P.
However, in my frenzy to construct this thing, I had inadvertently placed a 1K resistor in series with the Clock lead. Strapping out the resistor solved the problem and now everything works properly, like 'grease through a goose'.
It's not easy for me to admit to such a dumb mistake, but that's what it was, pure and simple! All of the old platitudes like 'haste makes waste...' are ringing in my ears this morning.
Thanks again for your patient help.
Joe Burch
Hello Joe,
You might wish to consider possible members of the HCS08 family, rather than the older HC908 family. There are a couple of possibilities that I can see. It will also depend on how much flash capacity you actually require (and maybe whether you are using assembler or C programming).
MC9S08GT16 available in 32-pin shrink DIP package. This device contains a SPI hardware module, but needs 3.3 volt operation.
MC9S08SE8 available in 28-pin standard DIP package. You are restricted to 8K flash, and there is no SPI hardware. However, 5 volt or 3.3 volt operation is possible.
I assume that the PLL device you are using is actually a MC145159 (rather than a MC154159). On this basis, bit banging the SPI function should not have critical timing since you only need to meet setup, hold and clock pulse minimum requirements (tens of nanoseconds). The more complicated aspect would be arranging the various data of the 32-bits into the four individual bytes.
Perhaps you might post your problem bit banging code for comment.
Regards,
Mac
Hi Mac,
Thanks for your gracious offer to help with this 'bit banging'.. Maybe I should call it 'head banging' because my head hurts.
Anyway, I have reused virtually all of the code from the good old HC05 (with the SPI) to this new JL16 unit except, of course, for the new emulator for the SPI. The HC05 works beautifully - since 1995. The new JL16 arrangement, does not.
Using a scope, I've been able to compare the operation of both devices into the same MC145159 PLL. With the HC05 SPI, the operation is much quicker than the bit banged JL16. As shown in Figure 5 of the MC145159 data sheet, the clock pulse appears to lead the data (1) pulse by a small amount. Looking at the SPI operation with the 'scope, the clock is just 'slightly ahead' of the data bit (1). I assume this is all done with 'wired logic' in the HC05. When I emulate the same operation with 'bit banging' in the JL16, the best that I can do - even with the instructions one after the other - is to have the data (1) appear near the middle of the clock pulse. I'm not sure if this is causing any problems within the MC145159.
Maybe the JL16 is not fast enough in this application??? Dunno.
I have the JL16 set up with a 5K RC resistor, and this is just about as fast as it can go. Anyway, I'm stumped.
Shown below is the latest version of the code that does the 'bit banging':
sendbyte1
; SPI emulation link.
; portb 7 = SPI enable
; portb 6 = SPI clock
; portb 5 = SPI data
; A has the byte to be sent.
; a low to high transition on the data bit
; when the clock is high (1)
; will register a 1 in the shift register.
; routine assumes that the clock lead is low on entry.
; uses synr0, synr1
;
sei ; block all interrupts (precaution)
sta synr0 ; store byte to be sent in synr0
lda #$08 ; load the bit counter
sta synr1
bclr 5,prtb ; enter with clear data bit
; start looping
; the MSB is sent first
lpspi
nop ; inter bit interval
nop
lsl synr0 ; rotate byte
bcc spil ; bit is a 0
bra spith
spil
bset 6,prtb ; turn on clock
nop
nop
; data bit had previously been cleared
bclr 6,prtb ; turn off clock
bra dcmt ; continue to next bit
spith
bset 6,prtb ; turn on clock
bset 5,prtb ; set data bit
bclr 6,prtb ; turn off clock
nop
nop
nop
bclr 5,prtb ; clear data bit
dcmt
dec synr1 ; decrement bit counter
bne lpspi ; keep looping
nop ; inter byte interval
nop
nop
nop
nop
nop
nop
bset 5,prtb
rts ; done with this byte
I would appreciate any help you could offer.
This program is designed to control a ham radio so the frequencies must be exact.
Here's the website that further explains the project: www.k3jls.net
Thanks again,
Joe Burch
Hello Joe,
I think that I can see a problem with your code!
The PLL device requires that the data be set to the required bit state, and then a positive clock edge is applied to shift the data into the serial register (with minimum setup delay 20ns @ 5V). However, at the label spith the positive edge of the clock occurs prior to the data being set high. The two instructions should be reversed for correct operation. The execution cycles for the bset instruction should give sufficient setup delay.
Incidently, it is unnecessary to clear the data state after each high bit - simply test the next bit state and set or clear the data bit prior to generating the short clock pulse. It would also appear unnecessary to use the temporary variables in RAM. You might directly shift the data from ACC, and use X as the bit counter (making use of the dbnzx instruction). The "interbyte interval" is also unnecessary, and it does not matter if the execution of an ISR should intervene within the sequence
The following code snippet is my take on the transfer subroutine.
SPDAT equ 5
SPCLK equ 6
ENB equ 7
; On entry, ACC = byte value to be sent
sendbyte1:
ldx #8 ; bit count
lpspi: lsla
bcc spil ; bit is a 0
bset SPDAT,prtb ; Set high data state
bra spith
spil: bclr SPDAT,prtb ; Set low data state
nop
spith: bset SPCLK,prtb ; Generate clock pulse
nop
bclr SPCLK,prtb
dbnzx lpspi ; decrement bit counter
rts
Since you are writing code rather than using SPI hardware, it is also possible to transfer all 32 bits in one hit, rather than handle as four separate bytes. In this case you might use a four-byte variable in RAM, and left-rotate all four bytes for each bit transferred. Alternatively, it would be possible to use four bytes within the stack (something that could not be done with the HC05).
Regards,
Mac
Hi Mac,
Many thanks for the revised code. I guess I have to the the time to learn about and then use the 'new' HC08 instructions. That's the good news. The bad news is that it didn't work.
I have checked my work several times over and can't see anything wrong. The program itself is over 8K long and will accommodate the conversion of 16 or more radios. It works flawlesly on the HC05 platform (with the SPI), but won't work with the emulated SPI code. I was hoping to migrate everything over to a newer flash-based platform.
Do you think that there's some other 'magic' in the SPI code that cannot be readily emulated with discrete instructions, because the CPU is too slow to match the 'wired logic' of the conventional SPI mechanism?? If Motorola developed the SPI 'format' which has been embraced as a 'de facto' standard, that's possible.
Also, it would appear that Freescale's products are shifting away from the DIP variety to the surface mount types. Sure, there are still some DIP's and new Shrink Dips, but neither of these are really suitable for the home constructors / prototype builders. Is this going to be the trend, do you think?? Some of the other DIP devices are no longer available.
Once again, thanks again for all of your help. I'll keep checking things to see what I may have missed. If I can't get it to work with the JL-16, then I'll either look around for some kind of hardware based SPI converter (there must be some out there), see about 'porting' the code to another manufacturer's device, or just stop the project altogether.
It's really a shame that Freescale decided to phase out the DIP devices, but I guess that their main markets and profits are elsewhere!!!
Joe Burch
Hello Joe,
Of course the code snippet previously discussed is not the whole picture. The sub-routine would need to be called four times, with the correct data value each time. Then after sending a total of 32 bits, the data latches need to be stobed for the new data to take effect, maybe using the following code.
bset ENB,prtb ; Generate strobe pulse
nop
bclr ENB,prtb
I presume that you have already checked that the expected signal is appearing on each of the three pins of the PLL device associated with the data transfer. When you say that the code does not work, how are you testing it? Are you observing any RF output from the VCO? If you are getting output at the incorrect frequency, this may indicate a data value error, perhaps with the packing of each byte.
SPI operation is generally very straight forward - the slave device receives the serial data into a shift register, as you can see from the block diagram for the device. There are few critical timing requirements - instruction execution times should readily meet the minimum setup and hold time limits. There should be no issues with single stepping through the code. The code should also work with any other 74HC series shift register device.
To verify that the RF hardware surrounding the PLL device does not have a design fault, for presumably a new PCB layout, perhaps you need to test the new layout using the data signals obtained from the old MCU.
Regards,
Mac
Hi Mac (and others),
You ask very legitimate questions, and I'll try my best to answer them.
I first wrote this code back in the late 90's. I had the HC05 programmed to accommodate the frequency agile modification of many GE radios and a couple of Motorola Syntor X's. It took a while to do it, but the results were very good. I never had a 'mis' when channelizing the PLL (i.e. going from receive to transmit, and vice versa. I converted the radio I'm currently using as a 'test bed' for the JL16 controller a couple of years ago. In so doing, I added code to the controller to cover this radio. Once debugged, it worked without a hitch.
I decided to update the controller from the HC05 to the JL16 when a couple of radio amateurs asked me for the upgraded controller. So, I reused almost all of the code in the new JL16, with the exception, of course, of the SPI drivers, substituting the code you had helped me with.
I spent most of this afternoon using a borrowed 'scope to verify that the data was reaching the PLL chip. Using the delay time position, I was able to read all of the bits along with the clock timing pulses that the PLL was receiving for both the reference oscillator and for the N/A counters. I wrote them down and checked the values for the frequency selected. They were right on the money! I double checked this with the Code Warrior simulator - again, an exact match! The enable pulses seem to be correct as they are coded the same as they were in the old reliable HC05 program, and were likewise verified on the 'scope. And yet, the PLL will not lock.
I tried a couple of 'stares and compares' between the HC05 controller and the SPI emulated JL16 routines. The HC05 SPI runs a good deal faster and the 'strobe' of the clock pulse is nearly coincident with the onset of the '1' data pulse. This is why I thought that there might be some kind of 'affinity' between the design of the MC-145159's SPI input circuitry and that of the HC05 SPI and also why I tried to adjust the code that I had written to bring them more closely together. For a while there (with my modified code), I was getting occasional 'locks' while scanning frequencies, but it was very irregular.
I'll try to some additional testing tomorrow morning when I'm fresher. The only other (remote) possibility concerns the VCO bandswitching flip / flops that are set or reset depending upon the frequency. If these were mis-set, the PLL would not lock. But again, I resused the code en masse. But, mistakes do happen so I'll carefully check them out tomorrow.
Thanks again for all of your help! I think I'll be seeing traces tonite in my dreams.
Joe Burch
Hi Mac (and others).
I took a last look at the radio this morning. In scoping out the pulses one more time, I took a more careful look at the clock pulse where it entered the radio. It was peaking around 4 volts (1 state) and at around .9 (0 state). Yet, at the JL16 pin itself, the levels were proper.
The M/P is interfaced with the radio's PLL circuitry through 3 leads, Enable, Clock and Data. To get the proper polarity, signal inverting transistors (2N3904's) are needed for the Enable and Data leads, each of which is fed from the port with a 1K current limiting resistor. Since the Clock lead is inverted twice by gates within the radio, it requires no inversion at the M/P.
However, in my frenzy to construct this thing, I had inadvertently placed a 1K resistor in series with the Clock lead. Strapping out the resistor solved the problem and now everything works properly, like 'grease through a goose'.
It's not easy for me to admit to such a dumb mistake, but that's what it was, pure and simple! All of the old platitudes like 'haste makes waste...' are ringing in my ears this morning.
Thanks again for your patient help.
Joe Burch
Good to know the final solution - thanks for letting us know.
Too many people just go away when their problem gets solved.
Thanks Again,
Peter House
Hi Peter,
Thank you and your colleagues for all of your help.
I've learned that it's almost impossible to do any clocking with a 'rounded top' pulse.
Joe
Joe,
SPI is generally a static protocol and you can go as slow as you want and even breakpoint during a transfer. Generally, using discrete IO functions it is NOT possible to go too fast since the part you are talking to is hard logic based in the transfer engine. Make sure your code only changes one bit at a time and I would bet $100 it is a sequencing problem and not a setup or hold time issue unless you are changing multiple bits at one time in your code.
I hand prototype a lot of PCBs and fought the change to surface mount until about 5 years ago. Since then I have learned to prototype using the larger surfce mount parts and occasionally delve into some smaller ones using hand tools.
At first I shaved solder from .031" using an exacto knife and then found some .015" and .010" solder. I also purchased very fine tips for my Weller WES50 solder station and have not looked back. For desoldering I use either a heat gun or a small toaster oven and aluminum foil to protrect everything else - turn the oven on and let it get up to temperature - set to broil - put a small piece of .015" solder on top of the chip as an indicator - put the PCB in and in a few seconds, when the solder on top melts, pull the chip off using a small vacuum pickup tool. The pads can be cleaned using conventional solder wick and iron and then resolder a new chip. The old one is Toast !
I recently purchased a 40 power stereo working microscope and I can now do even smaller parts!
If you figure out how to do BGA's I would like to know.
Good Luck,
Peter House