After reading an thinking about it a bit more, one partial answer is given in the AMuxHW datasheet, which pretty clearly states that a 12-AMuxHW needs 17 macrocells and a 4-AMuxHW needs 7 macrocells (if I have done the math correctly). That's a lot, but not really surprising given the purpose they have. That's a sum of 24 macrocells, which can fit in 6 PLDs.
But still - 6 more for the rest really sounds like too much.
Note that the number of PLDs is not the major concern. Sometimes the routing tool picks macrocells and pterms across multiple PLDs to optimize the logic. So what really matters is the number of macrocells and pterms your design uses.
Well my overall design doesn't route despite using only 78% of the macrocells and 64% of the P-Terms (does the resource meter even output accurate results if routing fails?). The largest share, by far, is used by the module attached above. Or rather, something very similar, because I keep modifying and moving stuff back and forth to somehow get it to route.
You definitely will not be able to achieve 100% of Macrocells and P-Terms.
Usually you will not be able to route something if you are using over 90% of the resources (Pterms or Macrocells).
I'm surprise you can't route with 78%/64%. Can you share your RPT file?
Of course! I can also share the overall design, if that helps. I'd just clean it up a bit first so that folks don't get confused by the large number of unused connectors that I added to try different approaches to the problem.
20200808_BLDC_flex.rpt.zip 31.4 K
Another side note: There's one block that still needs to be added to my design, but it's rather small and stand-alone. I just don't know yet how I'd implement it, so it's missing. Resource usage would be roughly
- one timer
- one datapath
- a handful of macrocells (let's say 4) and PTs
- 2 GPIO
A quick look on the design.
Do you need to use AnalogMuxHw in this design? Could you use the SAR MUX? That would save a lot of Macrocells and Pterms.
I thought about using the SAR mux too but I haven't found an approach that sounded like it could do the job with the SAR mux. However, this is my first project with the PSoC and I've discovered a ton of alternative approaches to a lot of tasks on the way so I'd give it a try. Here's what I want to achieve:
- Each of the 4 ESCs drives a BLDC motor (3 phases). At any time while the motor is actively driven, one of the phases is unpowered. bemf is measured on this phase. 4 x 3 = 12 positive inputs to the ADC
- All 3 phases are tied together in a virtual center point. bemf from the floating phase is measured against this voltage. That's 4 negative inputs to the ADC. My AMuxHW logic provides the corresponding 4x(3:1) differential channel selection signals.
- The motors are driven by PWM. After each switch on the PWM signal, there's a short period in the 1 us range where no sample should be taken, because voltage spikes would mess up the results. The current design has "blanking timers" for this. There are more reasons for blanking the ADC at other times, but they aren't as time critical. There's one PWM blanking timer per ESC,
- We need to get at least around 200 ksps per ESC, ideally without wasting time on channel switching in software.
- For each sample we also need a timestamp from the ESC this sample was taken for.
- That's why want hardware control over what's measured, when, and for which ESC.
When I try to use the SAR mux, my understanding is that I have no information (in hardware) about when the ADC is sampling for which ESC, so I can't even discard samples that would be messed by PWM switch spiking. It would also be harder to implement the 4x(3:1) differential muxing, and I'd have to handle each sample in an ISR. I'd like to avoid that, because previous tests have shown that things get very busy when the CPU has to execute an ISR for each sample.
Edit: One thing that *might* work is to DMA SAR_CHAN_RESULT_UPDATED to a datapath that then triggers each ESC core's sample evaluation. However, that's only useful if I can somehow configure SARSEQ to trigger a conversion on one channel of a set of enabled channels, then give me a pulse on eos, and then proceed to the next enabled channel. As I understand it, SARSEQ would scan all channels and then trigger eos when the whole scan is completed. Is that correct?
Possible approach using SARMUX:
Each ESC's code writes the currently correct analog input configuration to a location in memory. For each ESC, this changes at a frequency of up to 40 kHz and we need at least 4-5 samples during each period.
- Select an ESC in hardware; route soc, sdone and eos to the selected ESC
- If the selected ESC has ADC sampling enabled:
- Trigger a DMA transfer of the current ESC’s analog input configuration to SARMUX
- Start conversion and let the ESC figure out if it still wants the sample when it’s done
- ESC will grab the sample via DMA and post-process it. This step is a bit tricky because I need to tell my hardware where to find the correct result. With the HWMux it was always in Result0 - now it's in the actual channel's result register.
- repeat for next ESC
the DMA transfer would probably not impact ADC performance that much.
The above doesn't work without a lot of CPU intervention since the SARMUX can't handle 12 differential pairs. But it can handle 4 differential pairs (one for each ESC) so the 12:1 mux for the positive inputs can be split into 4 3:1 hardware muxes, like so:
That allows the fitter to place the 3:1 muxes closer to the source of their select inputs, and simplify the overall routing. The 4 extra PCB traces are not a problem (yet). We'll see how that fits - it's not tested yet. The ADC's sdone output can be used to DMA SAR_STATUS::CUR_CHAN into the fabric while SARSEQ is cycling through the 4 inputs.
So I adapted my overall design, got rid of an optional feature, and it now uses 67% of MCs and 54% of PTs. The top-level schematic (see attached pdf) brings across the overall analog muxing that we need, so that we can use the SARMUX to switch between ESCs and the individual ESCs' analog muxes to control which input that actually is.
Each ESC's 3:1 AMux sits on one segment of AMuxBus A or B. As it is, the schematic fits on the PSoC, with one PLD completely free. The analog routing is constrained with one pin per ESC so as to assign an AMuxBus segment to an ESC. This was necessary to help find a solution for the analog routing. However, since the analog muxing is tightly coupled with the digital part of each ESC, this puts some constraints on the digital routing as well and I don't know how to ease the digital routing other than by trial and error. When I pick a worse AMuxBus-ESC mapping, the design occupies all of the PLDs.
However, a handful of additional components are needed. That would be an 8-bit datapath with a state machine and 2-bit parallel output, DMA channels (maybe 2) and a bunch of timers, and glue logic and digital I/O that controls external analog switches. The VDAC/Comparator combo on the right hand side of the top level schematic is also part of this. When I add a series of two one-shot timers to the comparator's output, the routing fails. My impression is that the problem is not in the number of MCs and PTs that the design has, but the mapping between each ESC and its I/O.