And yes, I use the dreaded pointers. Even worse, tables of function pointers! Gasp.
That's fine, they're allocated on the stack
And yes, I use the dreaded pointers. Even worse, tables of function pointers! Gasp.
Not if your doing it right.That's fine, they're allocated on the stack
I use a C++ compiler (because every embedded C tool chain is C++), but my embedded code is pure C and assembler. And yes, I use the dreaded pointers. Even worse, tables of function pointers! Gasp.
I may have started writing device drivers in Microsoft Macro Assembler, but all the PC code I write today is in C#. Use the appropriate tool for the job.I avoided pointers as long as I could. Once I learned them, I felt like a coding super hero. Super clean and efficient. They can feel convoluted and deliver some really hard to track down bugs, but when I only had an 8bit CPU and, tiny RAM - this is the way. Every bit and clock cycle justified.
When I use a 32bit MCU with some huge amount of flash and RAM to do a relatively tiny task - It is hard to dig in that deep anymore. I don't need most of my projects to run for a decade continuously or some ridiculously limiting power source.
Some see it as a cheat to oversize the MCU to allow a higher level (bloated) code - but if the project is ok with the ramifications - the time saved is delicious.
Not if your doing it right.
I had one product where the customer had their own rate calculating code that was totally secret squirrel stuff (it involved money).
We were supposed to make function calls into their engine for "EVERYTHING". Want the bitmap for a character, make a function call. Want to know how to map the keys, make a function call. Want to look up a user interface prompt (in the local language), make a function call. And we were supposed to walk the same chain of calls every time we needed to do anything.
First implementation was so slow (this was running on a Philips XA51) that it was unusable. I built up a table of function pointers in RAM at startup and jumped around their judiciously slow rate engine. Sped up the user interface by a 5X factor.
I built up the function pointer tables on the fly every time we powered up (new rate data could be loaded into the device without updating our firmware), so the only real risk was that they might get tricky and conditionally remap internal functions based on context. So I created an automated test bench to exhaustively determine if this ever happened and ran this each time we got a new version of the rate engine. It never changed. They honestly weren't very good coders. The customer's internal development group was not very good or responsive and I was routinely asked to fix bugs in their rate engine in my code. No problem, they were buying $25M a year of our product (in the '90s) and we were making a 60 margin on that, so we were glad to cater to their every whim. That $15M of margin a year will buy a lot of my time.
They can feel convoluted and deliver some really hard to track down bugs
It would hurt. I am just blessed that I have been able to do this pretty much my entire working life and I am getting close to retirement now.@HaldorEE I could learn so much from you.
Are you able to send me an archive of your brain, including all the 'experience' files?
My coding skills have always been a lower priority than by ME and EE skills. To make that even worse - I owned my own businesses for 25 years which ensures that I was distracted 24/7.
As I get older, all I want to do is software development and coding.
I have successfully fought off every attempt by my employer to turn me into a manager. I would have sucked so hard at that. It not that good management is not important, it is that I would be terrible at it.@HaldorEE I could learn so much from you.
Are you able to send me an archive of your brain, including all the 'experience' files?
My coding skills have always been a lower priority than by ME and EE skills. To make that even worse - I owned my own businesses for 25 years which ensures that I was distracted 24/7.
As I get older, all I want to do is software development and coding.
Here is another one. Every single signal connected to a processor's GPIO gets a 33 ohm series termination resistor. From a logic level and timing standpoint, that is small enough to be completely transparent.
It is things like this that make adding series resistors to everything just not worth talking about, just do it. Series resistance also helps with ESD immunity. It is like eating your vegetables, there really is no downside and it can save you from some very unpleasant situations.
I will look at the Arduino programming language, but I think MicroPython makes so much more sense.
What signal where you thinking about using a 1.8K resistors on? The series resistor and the trace capacitance form a low pass filter which helps reduce noise in general on the PCB. You have to be careful with faster clock rate signals that you don't overdo the resistor value or else you will lose high frequency drive capacity. I am a major fan of using LVDS buffers for really high speed signals, especially if they have to travel any distance or pass through a harness. Every signal is differential, LVDS just forces you to acknowledge this truth in your PCB design.Yes, I planned to use 1.8 k but since 33 Ohms is good enough I guess I'll go down to 330 Ohms (values are because of BoM reuse) to gain back some drive capability.
1.8K is too high. I suggest you use 100 ohm resistors then see if you still have a ringing problem. If you do, then add a 1 nF cap to ground on the receive input. If you want to be pre-emptively safe, just add the 1nF caps to the PCB layout and you can decide later if you need to populate these parts or not.I have TTL clock and data signals going to some shift registers and a few simple TTL signals. A 100 kHz clock would be plenty enough for what I'll do, so speed shouldn't be too much of a concern and the shift registers have schmitt trigger inputs to avoid noise related problems. And the simple TTL signals go into schmitt trigger buffers to avoid any noise problems too.
I'm more worried about having a fan-out of 4 with the relatively high 1.8 k resistors, but since your experimental data shows values far lower that are good enough then I can lower them.
I plan to support up to around 1 m of unshielded flat flex cable so that's why I thought a lot about suppressing probable noise and ringing problems before I even have a chance to encounter them. I also have the shift registers signal wires inbetween grounded wires on the flat cable (even number wires are signal, odd number wires are ground) for the same reasons, and to reduce radiated noise too. It's actually a method which was already used a while back for the floppy drives signals.
Are these device all going to be on the same PCB or are you going to be driving receivers on more than one PCB?
If the cable is going to daisy chain from PCB to PCB, then you might want to consider doing what I am going to do. Most LVDS receiver ICs build the 120 ohm termination resistor into the IC and you only want a single termination resistor at the end of the chain. To get around having to manually put the termination resistor into the last PCB in the chain, I am buffering the input on each PCB and resending it out to the next PCB through another LVCS driver. The data coming back to the master uses M-LVSD drivers so these signals just pass through from PCB to PCB in a daisy chain fashion.
Why are fixed space fonts broken now? I made the above diagram using Courier font and it still messed the spacing up.
I just noticed you are going to be driving a 1m cable. Save yourself a lot of heart burn and use LVDS drivers.
The SCK and MOSI signals can use standard LVDS drivers since that is a one to many connection. The MISO signal will need to use M-LVDS drivers to permit a many to one connection.
I suggest looking at these ICs for the M-LVDS drivers.
https://www.ti.com/interface/lvds-m-lvds-pecl/products.html#~p1389=M-LVDS&sort=p1130;asc