In the previous post I designed the cellular modem module. However, the requirements for the device include having a SIM card, which I had elected to put on a separate module, so it's time to make that module now:
Requirement 2.2.1: Cellular Module Carrier board that can accept an
industry standard industrial cellular modem, breaking out all pins from
the connectors, and provides a SIM card slot.
It shouldn't be hard to do.
It'll be an edge-mounted module, which won't be a problem since I added support for edge-mounted modules into my procedural footprint generator.
I also know the single part that needs to go on the module, i.e., the combined SIM and SD card slot. When I made the last prototypes I couldn't buy them singly, so ended up buying a whole reel of 1,200 pieces -- and I still have 1,194 of them left, so that's what I'm going to use! But if others can't source the same part, then they can design a module that takes a different part -- that's part of the benefit of this modularisation approach!
The parts I have are Molex 104168-1616's. Unfortunately SnapEDA doesn't have a model for it. Mouser does have a 3D model for it, but no footprint or symbol. I have a vague recollection that I made a footprint for it at some point, but I don't remember for sure, or where I would have put it.
Okay, I have created a PCB symbol and footprint now. The footprint I have verified against the 3D model to make sure that everything lines up, which it does:
So let's lay it out now, with the 8 pins for SD card and 8 for SIM card, and GND. So that's 17 pins, plus we'll have a dummy for power. So this is what the result looks like:
Now to pop that into the PCBWay order, if I'm not already too late.
So that closes out this requirement:
Requirement 2.2.1: Cellular Module Carrier board that can accept an
industry standard industrial cellular modem, breaking out all pins from
the connectors, and provides a SIM card slot.
Okay, so next on the list of modules that we need to make is the cellular modem carrier.
I've previously used one of these for experimenting. They work great, and I was going to order one for working on the telephony software in the meantime, but they don't have shipping to Australia as a default option. And since I need to make one of my own, anyway, I may as well do that now.
Fortunately, the board is open-hardware (CC-BY-SA), so the schematics are available, which helps to save me a bit of time as much as anything else, as the actual wiring is not particularly hard.
1. Requirements Analysis
The only requirement that relates to this is:
Requirement 2.2.1: Cellular Module Carrier board that can accept an industry standard industrial cellular modem, breaking out all pins from the connectors, and provides a SIM card slot.
I'm of two minds as to whether to put the SIM card on a separate bay, so that it can be more easily exchanged, without having to pull the phone apart, as it's not that uncommon a task to need to perform. It probably makes sense to do so. For the SIM card slot, I'm using combined SIM + microSD card slots to save space. From a previous prototyping run I have a full reel of Molex 1041681616. While they are end-of-life there are still plenty in stock around the world, if you don't mind having to buy a whole reel like I did. If you don't need a whole reel, poke me on the MEGA65 Discord server, and I'm sure we can work something out. But more the point, by putting the SD card / SIM slot on a module of its own, we can easily switch to different parts -- that's part of the point of making this thing modular!
Otherwise we just need to look at the pinout of the EC25 Cellular Modem that we are using as the reference for the Mini PCIe form-factor that we are supporting. It's not hard to find a diagram like this:
Basically we have 52 pins, if we want to expose them all. USB_DM and USB_DP should have 90 Ohm differential routing for USB signals, but the rest are relatively low frequency signals. I'm not going to attest that USB will work for certain on this, because we don't strictly need it, although I would like to connect it to the Pi CM4 Module that I am planning, so that the Pi has direct access to fast internet in a way that Android running on the Pi will understand.
Let's now look at the EC25 Hardware Design Guide to see if there is anything special we should know for this module. Later, when we make the carrier board, there will be more things we need to care about, but for now, it's just whether we need any passives etc, and perhaps to know which pins are 1.8V or 3.3V IO domain. Okay, it looks like all pins are 1.8V IO domain, except for SIM card, which is auto-switching
In terms of main power supply, it requires 3.3V - 4.3V, designed for running directly from an LiPo cell. But as we are using LiFePO4 with a slightly lower voltage, we will be feeding it from one of the DC:DC converter modules I have designed.
Nothing jumps out as needing specific handling on this module, unless I wanted to include voltage conversion. But I don't think that's necessary, as the cellular modem will connect to the power management FPGA, not the main FPGA, and we can just set the voltage of that FPGA's IO lines to 1.8V... Except the FireAnt uses 3.3V for VCCIO, and the Efenix FPGAs can only do IO at VCCIO on a given bank.
I think it's best to leave the level conversion off the module, but I'll make a final decision as I progress. But either way I'll need to design the level conversion strategy. That strategy will differ depending on whether signals need to be bidirectional or not.
Lets look at the signals we have here, so that we can understand the requirements. These are described in this quectel document.
WAKE# - Open collector (output) used to wake host
COEX_UART_RX - Input
COEX_UART_TX - Output
UART_RX - Input
UART_TX - Output
RI - Output
UART_CTS - Input
UART_RTS - Output
DTS - Input (sleep mode control)
PCM_CLK -- Bidirectional
PCM_DOUT - Output
PCM_DIN - Input
PCM_SYNC - Bidirectional
USIM_VDD - N/A - Direct connect to SIM card
USIM_DATA - N/A - Direct connect to SIM card
USIM_CLK - N/A - Direct connect to SIM card
USIM_RESET - N/A - Direct connect to SIM card
W_DISABLE# - Input (airplane mode control)
PERST# - Input, active low, "fundamental reset control"
I2C_SCL - Output (so this is for an I2C interface controlled by the modem, typically for talking to audio codec ICs etc)
I2C_SDA - Bidirectional
USB_DP - N/A - Direct connect to USB. Requires 90 Ohm differential signalling.
USB_DM - N/A - Direct connect to USB. Requires 90 Ohm differential signalling.
LED_WWAN# - Open collector, active low LED indication.
So tallying that up, we get:
Input only - 7
Output only - 6
Bidirectional - 3
Open collector outputs - 2
N/A - 6
Total - 24
So the single-direction signals we can likely handle with something like a TXG404x.
Those parts come in either a 2 signals in each direction or 3 in one, 1 in the other direction variant. Both have output enable lines that allow for tri-stating outputs, which can be used for managing bi-directional lines. For the signals with fixed directions these will be super simple. For the bidirectional signals, two of those are for the PCM audio interface, and require the same direction. So having a simple way to generate inverted output enable signals for a pair going in both directions should work. The third bidirectional signal is actually that I2C interface for an audio-codec IC, which we can ignore.
So it sounds to me like we can get away with a bunch of TXG404x's on the PCB under the cellular modem.
Oh, blast. The TXG404x's are brand new, and not yet in stock anywhere. So maybe we can use an 8-channel TXV0108RGYR instead. In principal one each for the mono-directional line blocks will be sufficient -- plus some bidirectional solution for the PCM audio signals. We can actually use a 3rd one of these for that, as they have a direction control pin, so that will be nice and simple. They are only about US$1 each, so the cost is not too bad, in return for reduced BoM.
(I did also think about fixing the PCM signals in one direction, but I really want the modem to accept the signals from the FPGA, but I've seen problems with the firmware on these modems, where some modes only work if the modem generates the signals.)
Another advantage of the TXV0108's, is that they isolate when VCC is low on either side of the conversion. Thus I can use these to provide the isolation when the cellular modem is powered down, i.e., to prevent back-current.
2. Schematic & PCB Layout
I am working on the schematic layout and PCB layout together, as the order of pins on the voltage level converters makes a significant difference to the PCB layout effort required. This is because I'm aiming to keep to a 2-layer board to minimise cost. It feels like it should be possible to achieve. I should probably route the USB lines sooner rather than later, so that I have space etc for them to be properly differentially routed.
For the USB signals, I found this page that talks about how to do it in KiCad. Our biggest challenge that I can see for this so far, is that they should be routed over an unbroken ground plane. But the USB pins are kind of in the middle of the mini PCIe connector, and since we are aiming fora 2-layer board here, that's going to cause a bunch of routing pressure as I try to keep other signals (and power rails!) from crossing that zone.
I've managed to clear the routing for that, and also found a video that describes how to do differential routing of USB signals in KiCad:
So it is telling me that the traces need to be 1.3488 mm wide, if they are 0.2 mm apart, to get the required 90 Ohms resistance with a 2-layer stack-up.
The only problem is that when I tell KiCad to route the differential pair, and set that track width, it still draws the tracks with a width of 0.2 mm, rather than the 1.3488 mm I asked for. Hmm.. With a bit of mucking about, it now seems to want to draw the correct width. But my next problem is that the pin pitch on the mini PCIe connector is much less than 1.3488 mm, so I'll need to have some very short traces to get to having enough space to have the full-width traces.
But before I can route them, I think I need to get the module footprint organised, so that I have the opposite end of the trace to anchor the big fat traces onto, and then just do the short narrow terminations onto the mini PCIe connector. For that, we need to know the number of actual pads that we need. We have 24 signals we identified above, plus there is power and GND and a hand-full of others, so I think I'll allow for 36 pins, just to be totally safe. There will be plenty of room for these, because the cellular modem modules themselves are quite long.
(These extra pins also allow me the flexibility to supply a power on/off signal to the module, if I decide to put the 3.3V and 1.8V regulators for the cellular modem on the board. I'm leaning towards doing this, as it will make it a simple board that can be fed from VBAT with a 3.3V power on signal, and have just 3.3V IO to otherwise talk with it. That will all make the final host board much simpler.)
So let's look at it so far, without the power regulators:
On the PCB, we can see the amazingly fat USB traces required to try to get 90 Ohm impedance on the 1.6mm 2-layer PCB:
I guess I should add in the DC:DC converters for 3.3V and 1.8V, and finish hooking it all up. Here's how it looks with those:
Now what's missing is the footprint for the clip to hold the full-length mini PCIe modem in place, and the remaining standard silk-screening to indicate the module, its version and git repository.
For the clip, we can use something like a MM60-EZH059-B5-R650. From memory the R650 is the height that the clip stands above the board. We need to use the matching footprint for the contact end, as well, i.e., with the same height. Like one of these: MM60-52B1-E1-R650.
Okay, I have footprints and 3D models for those, so I'll substitute them in, to make sure they are exact fits for the existing connector, which looks to be the case. The main issue now is making sure I place them exactly right. It took some digging around until I found a drawing that shows the required relative placement.
Everything now looks right, and I have added all the silk-screen self-documentation, jumpers to let me cut the power from the on-board regulators if they prove to be a problem (and add pads to the edge to allow those rails to be supplied externally -- or for things off the module to use the power from this module.
Also, I've double-checked that the power supply components that sit under the module are lower than the bottom of the module:
I need to check with the EC25AU module I have here to see if it hangs below to far. If it does, I'll have to use the 850 rather than 650 height code mini PCIe connector parts.
But for now, it's all looking good, and I have it done just in time to add it to my current PCBWay order.
I'll check that this module has been approved when I get up in the morning... and it passed! And in time for me to combine with my existing order to save shipping :)
3. Requirements Verification
Okay, so let's just double-check that we have met all our requirements:
Requirement 2.2.1: Cellular Module Carrier board that can accept an
industry standard industrial cellular modem, breaking out all pins from
the connectors, and provides a SIM card slot.
Okay, so we have the mini PCIe connectors for industry standard industrial cellular modems, and we also have all pins broken out. What we don't yet have is the SIM card slot, which I'll address in another post. So we can't quite retire this requirement just yet.
In the previous post, I set about designing and laying out the high-current (2A) DC:DC converter for the MEGAphone. For draws of 10mA, that should still be 92% efficient across the plausible 2.6V to 3.6V battery voltage range. That's probably good enough.
Of course when I started looking to see if there were any options for even better efficiency at lower current levels, I found this one:
It's possibly even more efficient over the whole current range:
But what's really interesting, is that it doesn't have a thermal pad underneath it -- i.e., this thing would be way easier to hand assemble -- especially given that it also requires fewer passives. That would also allow the module to be physically smaller. They even include a sample layout, which I was silently a bit annoyed that the other one didn't:
So all up, this looks like a good option to use instead of the other design, as even at the lowest battery voltage, it should still be able to deliver ~2A, but at higher battery voltages, it can even deliver 3A or more. *sigh*
The question is whether it is worth designing a module around this right now or not.
I suspect the effort is better invested in creating another module instead... although hand-assembly is very attractive, as it would let me put off figuring out how to use the PCBWay assembly service for a bit longer.
Another option, though, is to use the same DC:DC converter that is on the MPPT module I've derived from this. Having commonality of the part is attractive for reducing the unique part count that I will need to have on hand. Also, I can in principle just replicate the circuit and layout from that one, and know that it's already been tested.
That design uses a AP63203, which, unfortunately has a minimum input voltage of 3.8V, which is above the full level of our LiFePO4 single-cell battery. Bother! I'd even gone and adapted the MPPT module down to having just this module. Oh well.
The TPS631000 looks like it will be what we will need to use. We'll also hook it up so that it can deliver either 1.8V or 3.3V, to cover the two most likely voltages we will need. I'll do this by again providing an extra resistor that goes parallel to the feedback voltage resistor ladder:
To select 1.8V output the 1V8 SEL line should be tied to VOUT (not GND, as that would _increase_ the output voltage!). To help avoid people making mistakes with this, I've added silkscreen instructions that they should be tied for 1.8V output.
I've also provided a MODE pin for pulling to GND if you have a load that is ~1mA or less, and really want to get an extra bit of efficiency. But 50% efficiency at 1mA still only means 1mA wasted, so we aren't going to bother using this in the MEGAphone. But the facility is there for those who might want it, if using this module in something else.
The module now looks like this:
So that's that one also schematic and PCB layout done, satisfying
Milestone 2.2.2 - Low-energy power-management module to minimise engery consumption of the device: Schematic
Milestone 2.2.3 - Low-energy power-management module to minimise engery consumption of the device:PCB Layout [sic]
I've already got a PCBWay order in progress, that is waiting for a 4-layer board to be fabricated, which will take 4 days more, so I can easily add this one onto the order, which I've done.
One last thing that will make it much easier for fabricating modules is to have a footprint that provides panelisation in the form of a perforated break-point, so that I can have multiple modules fabricated on a single panel, and also to provide space off of the module itself for the PCB manufacturer to put their job number.
I'll start by making such a perforisation as a dummy footprint, so that I can look at the resulting KiCad footprint, and then I can incorporate that into my procedural footprint generator as a -PANEL variant for each footprint.
Another option would be to use V scoring, where instead of cut-outs and tabs, a V-shaped scoring is made across a board. But it seems that there is no simple way to specify this in KiCad. So I think I'll stick with the tabs.
PCBWay's documentation on the tabs is a little confusing, in that tabs without drill holes must be at least 2mm wide, while for those with holes, they show an example with only 1.6mm wide. So maybe I'll play it safe and make it >2mm wide.
The result then looks like this:
The next step will be to include this in the edge-cuts for the procedurally generated footprints. This will mean replacing the previous edge-cut which is a rectangle with four lines, so that on the tab-side, I can replace that straight line with one or more of these.
I guess I'll have to come up with some logic for when one or when two of these is required, based on the module width. Probably I'll just make it so that the gap between tabs is >.35mm, so that the minimum spacing requirements between the "mouse bite" small drill holes (they are 0.45mm diameter, and 0.35mm apart) is met. That will allow the panels to be as strong as possible.
All up the goal here is to make something that is 100% compliant with PCBWay's manufacturing standards, so that they just accept boards that I submit without having to wait for engineering feedback rounds etc.
Okay, so after the obligatory mucking about, I now have it procedurally generating and placing either 1 or 2 tabs, depending on how many there is space for, with the spacing and sizes of the mouse-bite holes etc all matching the above. Here's the corner of a module -PANEL variant with this:
Actually, they are very slightly more widely spaced, as I think I had a couple of the gaps not quite wide enough previously. In any case, it looks like a perfectly tab. Let's just make sure it also works for the case with a single tab.
Now I'm trying to use this to make a panel with 2x the solar battery charge regulator, and hit a problem that KiCad doesn't like the drill holes overlapping the edge cut. This was really an oversight on my part, as I should have defined those circles as mechanical non-plated drill-holes, rather than edge-cuts. So I've fixed that:
With that, I am now able to fairly easily setup a panelised version in KiCad:
The big question now is whether PCBWay will accept this. The best way to find out if they have any problems is to submit it for fabrication quote.
I was a bit surprised about the cost of castellated 4-layer fabrication with them for earlier samples, so it will be interesting to see what they price this <100x100mm panel at. It's currently suggesting US$50 for 5 of these panels, i.e., 10 pieces, but I'll know for sure when they respond after doing the engineering checks.
Yup, after verification the price is now US$95 !!
Time to get some other quotes.
Email sent to Victory PCB.
Will also check out SEEED, JLC PCB, ITEAD and NextPCB.
I'm also wondering if I can't get away with some simpler process, e.g., grinding the edges off a normal PCB, leaving just the plated half hole-through, rather than requiring the edge plating, as I suspect that the 1mm diameter hole has plenty of surface area on it, and in fact, the castellated pads have only a very small amount of edge either side of the hole.
I'll ask PCBWay if they can do that, and also just give them a prod on price.
Or how about DIY castellation?
Meanwhile, I'm thinking about horrible hacky DIY castellated PCB strategies. After some brain-storming, I think a piece of mild-steel cut in two in a mitrebox with a hacksaw to create a pair of pieces of steel with straight burred edges can be used to grip the PCB at the limit of where material should be removed, and then that can be held in a vice, and a belt sander, file or whatever you like can then be used to remove the excess material until it's flat and straight at the right depth.
A wooden jig can be made with a slot the right depth (half a 2.5mm pad) so that the PCB can be dropped in there, and the burred steel pieces then placed on the surface of the timber either side, and gripped to pick the PCB up in the right place like a pair of tweezers, and then transferred into a vice, where it can all be sanded down.
The idea of this approach is that the burrs clamp the pads at the point where we want to keep material, so that they can't get easily ripped off. They will also provide some protection for the plated through hole.
As the burred steel wears, it can be recut to put a new burr on it super easily.
This could also be setup with longer pieces to allow processing of multiple boards at the same time.
It feels like it could just work -- especially since we don't need great accuracy on the castellated edges for our purposes.
The question is whether getting PCBWay or someone else to make the boards uncastellated will really save enough money to make this extra processing step that I will have to do worth it.
To test that, I'll need to adjust my procedural footprint generator to make non-castellated versions, i.e., with the full pads on the edges, and get a quote from PCBWay on those. I can also in the meantime do some testing of filing back some hole-through boards, to see how well the plated hole-throughs are likely to stand up to this treatment. For that, I just need to get a piece of mild-steel to cut in my mitre box. That shouldn't be too hard to organise.
I've just called my local metal supply store, and they should have what I need.
Or I could also just use a nibbler tool and sanding block, like in this video:
That would work, but is a bit more involved to get a consistent result, and since I will have quite a few castellated modules to design and test over the coming weeks, having some optimisation in my process is probably still worth it. I.e., it's probably still worth me making my jig idea.
I might explore both at the same time. The obvious optimisation I can make to the nibbler method, is to make the excess material on the PCB exactly match the depth in the nibbler, so that you don't have to guess about how far to slot the board into the nibbler.
So I tried nibbling and old spare PCB I had laying around, and it does a fair job:
For prototyping, this will be fine, I think.
Due to The Wonders Of The Modern World, a brand-new nibbler purchased in metric Australia chops out 1/16th of an inch! But that's ok. I can accommodate that in KiCad.
So time to modify my procedural footprint generator again, to make a -NIBBLE option for each module footprint, and then let's see what the quote from PCBWay looks like...
Looks pretty good to me! The 1/16th inch is just enough to clear the pads, which is a happy coincidence. So let's see how much PCBWay want to charge for 5 of those... About US$25, which is half the price compared to when it had castellated pads. Looks like that nibbler will pay for itself in a single order!
It's probably about time that I order a batch of each of the modules that I have designed so far -- and probably a test carrier board for them all, as well, so that I can test fit and soldering with the updated procedurally generated footprints.
Okay, so let's make Gerbers for the audio-jack module as well. That one had a really old manually generated footprint, instead of a procedurally generated one, so I had to re-do that. In the process I also improved the generator to add the command line args used to generate a given module into the symbol description to make it easier to re-do.
Audio jack and audio codec gerbers have been generated. Onto the high-efficiency high-current DC:DC converter. This one is also currently using a hand-generated footprint, and is a little trickier to quickly convert, because it uses only 8 pins from 22, but I chose their positions carefully to line up with where I wanted pads for convenience, and consistency. While my tool allows the selection of all possible pinouts in principle, they currently get selected by choosing a variant number, rather than being able to provide the set of pins.
It's clear that having a way to specify exactly which pin positions to use would be helpful. So I'll modify the tool so that if instead of a variant number you provide a string of Pn[,n...] it will use those absolute pin positions. But that's going to have to wait until tomorrow, as it's gotten late again, and I'm tired.
Okay, it's now a few days later, and I have implemented this, and re-done the DC:DC converter footprint to use it:
And then also the MEMS microphone board:
Okay, so now I have five modules ready for PCB fabrication.
All that I need now, is to make a dummy carrier PCB for them, so that I can verify that the procedurally generated footprints actually work between modules and module bays.
I do, of course, have to make sure that I use exactly the right footprints. I could open all the projects and look for them, but it's much easier to use a bit of shell scripting:
Okay, so now I can just add those symbols to a scratch project:
Okay. So that's all the PCBs I need to get fabricated right now. And by keeping everything to 2-layer, except the MPPT module, and by using my nibble-method to avoid the need for castellation during manufacture, that has the total order cost under US$100 plus postage. Compare that with the US$93 I was quoted just for the MPPT module when I had it castellated during manufacture!
So now I just have to wait a few minutes for PCBWay to do the final fabrication approval for the scratch board, and then I can submit payment and get it all being manufactured. Frustratingly, they will probably not turn up next weekend, but the following week, because of that 4-layer MPPT board that will take 4-5 days to fabricate, and since its Saturday morning now, they probably won't ship it until Wednesday or Thursday, which is a bit too tight for delivery to here by the following Saturday. But that's okay. I've got plenty more modules to design, and I also need to order the BoM for each of these five modules, in any case.
They rejected the scratch board because it has no drill holes and they can't tell if it's single or double sided -- whoops! I've just added a single via so that there is one hole to drill, and it makes clear that it's two layer. Let's see if that gets it through. If not I'll have to draw a picture on the rear copper layer ;)
Yup -- I need something on the back, too (or to be bothered going into board setup and making it single-sided). So we have a smily face on the rear, with vias for eyes instead.
Nope. Still not working. I guess because there are no pins on the back. I'll just flip a footprint to the back -- that got it through.
Okay, so it's been submitted for fabrication now. I'll head off to bed now, and then tomorrow I'll organise the BoM for each of the modules, and put an order in for the parts.
In the previous post I described how I went about procedurally generating KiCad footprints for modules of different sizes and pin configurations. That's all working great, but now I'd like the same for schematic symbols.
Like footprints, KiCad has a text-based format for symbols, and that format looks quite similar. The main difference is that while footprints each have their own file, symbols are are stored in a single library. I'm not quite sure why, but that's how it is.
So where as with the footprints I just had to create the files in the library directory, for the symbols I'll have to read the existing symbol library and then insert them. To do that I'll probably read the library file, and copy lines to a temporary file until I reach the end, removing the symbol if it's already in there in the process. Then at the end, instead of writing the final line, which is just a ")", I'll insert the new symbol entities. That way we can either insert or update the symbol.
One nice thing once I have this all done, is that I can make the symbols choose the correct footprint by default, to provide a small but welcome convenience.
Okay, it's taken a few hours to get it all right, but it's working now.
One thing I found out in the process, is that if you corrupt a KiCad symbol library, you can't just re-load it. You have to quit and reload KiCad, before it will actually reload the library. There are also some odd things with symbol order. It might expect them to be in alphabetical order or something in the file. But it all works okay.
Here's what the symbols look like for all the combinations of whether its the module or the bay to take a module, and whether its for the edge of a PCB and/or has a cut-out to allow a component zone on the rear of the module:
And of course it correctly populates which pins are actually present or not.
So now I really can get back to making the next module.
Each of the modules I am creating need a unique module footprint, so that they can't be installed in the wrong bay, or with incorrect orientation.
I've already spent quite a bit of time in the footprint editor making variants, and I've only designed 4 of the perhaps 30 modules I will need -- and then each needs its matching bay.
To save on work going forward, I want to explore writing a program that can generate a unique module footprint that has the required component area and number of pins.
This should be possible, because KiCad uses a text-based format for footprints.
After an hour or so of hacking up some C, I have it well under way, producing footprints like this:
The numbers mean the width and height of the cut-out area in the middle, and the minimum number of pins required. The final number, 1 in this case, is to select the variant (i.e., which pins are missing to make the result unambiguous in terms of rotation or flipping). It will make the module bigger if the number of pins or the cut-out size require it.
I still need to add the no-component zones, and then the logic for working out which pins to remove, when less than the full pin-count is required.
That latter will be fairly simple, if a little fiddly, as we need to consider all possible variants (or at least several) that meet the criteria of:
1. Has the correct number of pins.
2. Has no rotational or translational symmetry to itself, nor to any of the previously identified variants.
It might be that I try to come up with up to unique variants, until we run out of possibilities, or the requested variant number is reached.
This felt like the kind of problem to set ChatGPT against to work out. And it got it mostly right, but forgot to bother flipping, when testing. It probably saved some time overall. And now I can generate variants with any number of pins and any given cut-out size for components. It even works out the name for the variant, and adds the labels, like this:
So now I just need to make it write it out into the correct file name, and we are most of the way there. I will also need to make the module bay version that accepts the corresponding module, and then my life when defining new modules will be super easy.
This will not only save time, but likely help me work faster, as coming up with the footprints for these was a significant psychological drag, especially with the low-level concern that I might have to re-do it a different size or something, if I wasn't 100% sure I had the rest of the circuit done. It also meant that I was using cut-out areas that weren't optimal, because of the effort of making a new one, instead of just re-using an existing one.
So, onward with making the module bay versions. It was a bit of fiddling again, to get this right, but it now generates all four variants that I could need: Normal, No cutout for components in the middle for modules that don't need it (so that we keep ground planes, routing layers etc intact), Edge-of-board and both edge and no cutout, like this:
I am very happy with this -- as I can now just generate them as I need. I haven't done the same for symbol generation, but the symbols are much quicker and easier to generate by hand. It doesn't mean that I won't tackle it, but I want to get back to making modules using these footprints again first!
This one is a super simple one: It just has the 3.5mm audio jack on it. It's a bit questionable as to whether this even needs to be on a module, vs just be soldered directly onto the carrier board. But I still like the idea of it being on a module to allow easier re-use, as I iterate the main board. Also, it's about the size project that I can tackle on my lunch break.
1. Key Component Selection
The only component it needs is the connector itself.
We need to support stereo audio plus microphone input, and nothing else. So probably something like one of these should be okay:
Trying to find the symbols and footprints for KiCad for this connector, I was a bit surprised that it's not even listed in SnapEDA.com -- but the datasheet actually has links to the files from the vendor directly! It would be nice if all vendors included such links in their datasheets. It just removes that bit of friction for selecting a component, and isn't that hard to do.
Anyway, with that in place, and knowing that I need only 4 pins, it's time to think about the module layout -- in particular that this connector needs to sit on the edge of the board, which the standard castellated modules I have created don't handle explicitly. That said, the only real chance is the module bay footprint, to remove the furniture at one end of the module.
Meanwhile, I have been annoyed by a problem that I'd encountered before, but forgotten the solution for: KiCad freezes for several seconds when switching between the schematic and PCB windows. It turns out its a known problem with running KiCad under XWayland, and the solution is to make sure no KiCad window is maximised. The interested reader can go down the rabbit hole to understand why this happens, but I'm just glad I remembered I'd seen the problem before, and could easily deal with it, because it's really annoying, and a big productivity and mood drag.
2. Schematic Layout
Okay, for the schematic, this is super simple: We have 4 pins that need to go to 4 pads on the module. Nothing else. The only other thing I've added is cuttable jumpers for each of the four pins, in case I get the pin order wrong (again).
3. PCB Layout
The PCB layout itself is also super simple. The main thing is to try to keep the size of the module as small as possible. Once I know the dimensions of the active area of the module, I can create a castellated module footprint that will fit it:
Okay, so now we know the size we need. Note that unlike most of the other modules, for this one, the jack has to sit on the flat size of the module, rather than the side that will sit in the cut-out on rear-side. This means that the module can actually be a whisker smaller than it would otherwise be. So let's set this up.
Okay, so a 2x10 is a fair bit longer than we need. 2x7 should be enough, so it's probably worth making that size module, rather than wasting ~7.5mm at the tail-end.
In the process, I have also updated all of the other footprints to fix the castellation hole sizes, and some other minor things that I was having to fix in each derived footprint, so that it should be quicker to make new footprints in future. I do also wonder if I can't come up with a way to parametrically generate the footprints, as it should be quite possible given KiCad's text format for footprints. I'll have a think about it.
But in the meantime, here is what the module looks like now:
The internal speaker and 3.5mm audio jack require a driver. The easiest solution here is to use what they call an "Audio Codec" IC, that are used in mobile phones. They have drivers for internal and external audio sources, and often also allow termination of an external microphone, e.g., for 3.5mm audio headset.
1. Requirements Analysis
There is only one requirement we have to address here:
Requirement 3.2.1: Audio CODEC or equivalent that has output channels for loud speaker (mono is ok), 3.5mm audio output (stereo) ear piece, and input channel for 3.5mm microphone.
Implied in this, is that it supports I2S or similar audio interface, so that we can have the MEGAphone's FPGA drive it using the existing audio infrastructure that we have there.
I've previously used the ALC5616, but they seem to be end of life (EOL) now.
What I'd really like, is one that has a speaker amplifier built in, so that I don't need a separate component for that. The alternative option is to not have a 3.5mm jack, and only support bluetooth for external microphone and headset.
This one has two class-D 1.29W speaker drivers for stereo internal audio, as well as stereo line-drivers for 3.5mm line out jack, and also an analog microphone input line. In short, this can drive both the internal speakers, as well as the 3.5mm audio jack. It also supports I2S for the digital side of the audio.
That's more than enough to get us out of trouble for the current stage -- Bluetooth can wait until the time-critical period is over.
3. Schematic Layout
Further in the datasheet in sections 8 -- 10 we find a typical schematic:
The suggested layout is interesting, too:
Our module system effectively provides a means of separation of the analog and digital grounds, with just a single point of connection. Pleasingly, this all looks like it needs relatively few passives.
What I am considering, is whether I put the 3.5mm jack on this module, or whether it should be mounted on the main board. I really want to keep as few components as possible on the main board, partly so that I can easily update it as I go along.
This does mean that I need a way to have one of my modules that has one edge that can be aligned to the edge of the carrier board. I'll need this, in any case for various other modules, such as those carrying the SIM card and SD card, or thumb-wheel potentiometers. So I'll need to tackle that anyway -- so we might as well put the 3.5mm audio jack on the module with the audio codec IC.
Okay, so I'm going through the schematic now. One thing I've just noticed that is mildly annoying, is that the device requires a 1.8V supply, as well as whatever the IO voltage is (most likely 3.3V to match the rest of the system), and VBAT for powering the speaker amplifiers. The 3.3V and VBAT I had counted on, but 1.8V is going to require a 2nd DC:DC converter. I'm going to see how much current the 1.8V supply needs. It might be simpler and acceptable to use a linear regulator to derive the 1.8V from the 3.3V -- but only if it won't cause too much heat / wasted power.
Also, ideally the power rails should come up in a particular order. We're going to take the minor liberty of powering them up effectively simultaneously. The datasheet does say that it has been designed to be tolerant of power sequencing, so given that our power supplies should come on fairly simultaneously -- with the exception of VBAT which remains on at all times, unless I make that switchable for this module -- we should be okay.
Now, back to that 1.8V power rail, having read through the datasheet I can't find a clear indication of the total power consumption. It talks about the power requirements for various blocks, but doesn't have a convenient "maximum power consumption" line anywhere that I can find. So I'm probably going to have to assume the worst, that it could be ~250mA.
Probably something like a ADP5301ACBZ-1-R7 is a good option for this. It's a buck converter, so will be much more efficient than a linear regulator. And any noise will be on the digital 3.3V rail, rather than the VBAT analog rail. It's fairly easy to setup, and can be set to 1.8V using a single resistor:
The PWM/Hysteresis mode of this regulator selects between a more efficient (hysteresis) mode, but is limited to 50mA, or a less efficient PWM mode, which can supply up to 500mA. This is a bit annoying, as depending on my reading of the CODEC datasheet, the draw on the 1.8V rail is either about 30mW max, or about 150mW max -- i.e., spanning the two modes ranges. The PWM mode can do both, but is particularly inefficient at lower current draw levels.
I think the best solution here is to connect the SYNC/MODE pin to GPIO1 of the CODEC, and then we can talk to the CODEC, and switch modes based on how we configure it... except that the GPIO1 pin is not, despite it's name, actually a GPIO. DOUT can be configured as a GPIO, though... which sounds a bit odd. Perhaps the datasheet is wrong?
Here's the register description for controlling DOUT:
Nope, looking through the rest of the datasheet, it really looks like GPIO1 is really just a Multi-Purpose Pin, rather than a true GPIO. So all we can do is connect the PWM/Hysteresis pin to either a pad on the module, to allow the board to select it elsewhere, or just strap it to PWM, and accept the efficiency loss. Given that the efficiency at 20mA draw should still be ~70%, that's probably the most sensible option. I'll do that using a 100K pull-up, and expose the mode pin on a pad of the module, so that it can be controlled externally, if desired.
Okay, so with the 1.8V rail solved, I can go back to the rest of the schematic layout...
I've now got it mostly set out, except for the module outline. A quick count suggests that I'll need 20 signals visible on external pads, so a 2x11 with one key pin feels like it should do the trick. What I don't yet know, is whether the existing format of that module will fit all the components in the available cut-out area. So it's probably a case of adding the module footprint, and then trying to fit everything into the area. I don't yet have a strong sense of whether this module will need to be 4 layer or not.
Well, the initial scale of the module to the CODEC IC gives me a bit of hope -- but there are a bunch of passives, and also that 1.8V regulator to be added yet:
4. Passive Component Selection
Okay, so to go to the next step, I need all the passives, so that I can work out if it really will all fit in a sensible way.
I can't find any restrictions on capacitor types or particular voltage requirements for the codec. The 1.8V regulator does provide specific guidance in their example layout, which I'll follow.
A quick hunt through Digikey found suitable passives, almost all of which are 0603, which gives me hope.
Okay, so I have managed to lay it out with just 2 layers, which is great... except I realised right at the end that I hadn't flipped the module footprint to the rear, which is what you have to do if you want the components to go on in the cut-out in the module recepticle.
It shouldn't be too hard to flip it, but I will have to switch the pin assignments from left to right, and vice-versa -- which means that the pin that is opposite the key pin will have to be re-routed. I hope I won't have to do much to sort that out. It's only the GPIO1 pin, which I can see will be easy to sort out.
Oh, except that I also have to re-route the VBAT and GND pins. GND is easy, but VBAT might cause me some problems. Well, unexpectedly the routing ended up being simpler.
This is what the board looks like now:
As usual, I've added the values for all parts, so that if field repair is required, it can be done.
6. Requirements Verification
Here's our requirement again:
Requirement 3.2.1: Audio CODEC or
equivalent that has output channels for loud speaker (mono is ok), 3.5mm
audio output (stereo) ear piece, and input channel for 3.5mm
microphone.
We have stereo internal speaker outputs, as well as headset output and input for microphone, so we have everything we need.